Skip to content

Releases: EmbarkStudios/rust-gpu

rust-gpu v0.9

25 Jul 10:03
Compare
Choose a tag to compare

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.9.0, the Rust nightly version has been updated to nightly-2023-05-27,
so make sure to update your rust-toolchain.toml file when upgrading to Rust-GPU 0.9.0.
This Rust nightly is equivalent (in language and library features) to the stable Rust 1.71.0 version, released recently.

As usual, you can find a complete list of changes in the changelog, but keep reading for the highlights.

panic! at the GPU

panic!s then (Rust-GPU 0.8.0 and earlier)

As many Rust APIs (or even language features) have some edge cases which they handle by panicking (e.g. bounds-checked indexing), Rust-GPU has had some panic!(...) support for a long time, but it was both unsound, and unhelpful to users:

  • unsound, because in Rust-GPU 0.8.0 (and earlier) panic!(...) was turned into loop {}
    the SPIR-V standard doesn't seem to allow it, but SPIR-V tools/drivers appear to be making the same mistake LLVM originally did, i.e. assuming that such "unproductive" infinite loops can never happen, and making loop {} UB (see rust-lang/rust#28728 - UB in safe Rust due to the C-specific assumptions in LLVM, fixed much later by making those assumptions opt-in as "mustprogress")
  • unhelpful, because even if the loop {} wasn't optimized out, the best case scenario was a timeout error
    but on some platforms/drivers, timeouts only work well for compute, or even require using a compute-only queue (via Vulkan, e.g. wgpu doesn't allow queue selection yet) to avoid disrupting the rest of the user's system (as compositors and other applications may be slowed down or even hanged into a crash by a timeout on one of the graphical/mixed queues, if they're blocked behind the loop {}-ing shader)
    • crucially, neither "which panic!", nor "which shader invocation" (caused the panic!) could be determined

panic!s now (Rust-GPU 0.9.0)

PRs #1070, #1080, #1036, #1082 replaced the old strategy (and refined the new one), resulting in:

  • by default, a panic!(...) is now soundly propagated all the way up to the shader entry-point, as if the Rust code had used -> Result<_, ()> and ? after every call (and so acts as a silent "early exit" for invocations that trigger it)

  • spirv_builder::ShaderPanicStrategy allows further customizing the behavior, notably:

    SpirvBuilder::new(/* ... */)
        .shader_panic_strategy(ShaderPanicStrategy::DebugPrintfThenExit {
            print_inputs: true,
            print_backtrace: true,
        })

    enables debugPrintf with maximal detail: panic! message + shader "inputs" + (compile-time) "backtrace"
    (see ShaderPanicStrategy docs for more details, and also how to e.g. enable debugPrintf output from Vulkan)

  • panic!(...) messages support (some) formatting, by conversion to an equivalent debugPrintf
    (e.g. assert!(x < 1.0, "{x} is not sub-unitary") will print x's value using debugPrintf's %f specifier)

Here's what it looks like in practice to get panic!(...) messages from the GPU:

Adding an assert! just for demonstration purposes:

--- a/examples/shaders/sky-shader/src/lib.rs
+++ b/examples/shaders/sky-shader/src/lib.rs
@@ -65,2 +65,7 @@ fn sun_intensity(zenith_angle_cos: f32) -> f32 {
     let cutoff_angle = PI / 1.95; // Earth shadow hack
+    const MIN_ZAC: f32 = 0.075;
+    assert!(
+        zenith_angle_cos > MIN_ZAC,
+        "expected {zenith_angle_cos} > {MIN_ZAC}, oops!"
+    );
     SUN_INTENSITY_FACTOR

Enabling debugPrintf output without code changes/debug mode:

VK_LOADER_LAYERS_ENABLE='VK_LAYER_KHRONOS_validation' \
VK_LAYER_ENABLES='VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT' \
DEBUG_PRINTF_TO_STDOUT=1 \
  cargo run -p example-runner-wgpu --release -- --force-spirv-passthru

Specialization Constants

SPIR-V allows shaders to declare "specialization constants" (i.e. OpSpecConstant) which can have their values specified just before using the shader module in e.g. a Vulkan pipeline (WebGPU also has this feature, calling it "pipeline-overridable constants").

While some shader languages can choose to expose this feature as a variation on their equivalent of "compile-time constants" (e.g. layout(constant_id = 123) const T x; in GLSL), Rust's consts and const-generic parameters are required to be known by the Rust compiler, so they're not a plausible path for Rust-GPU to expose this SPIR-V feature.

Instead, we're exposing the feature via #[spirv(spec_constant(...))]-decorated shader inputs (only u32 for now):

#[spirv(vertex)]
fn main(
    // Default is implicitly `0`, if not specified.
    #[spirv(spec_constant(id = 1))] no_default: u32,

    // IDs don't need to be sequential or obey any order.
    #[spirv(spec_constant(id = 9000, default = 123))] default_123: u32,
) {...}

You can read more about this feature in the "Specialization constants" section in the Rust-GPU book (which goes into more detail about the background of this feature, and Rust/Rust-GPU-specific limitations).

rust-gpu v0.8

02 Jun 22:16
Compare
Choose a tag to compare

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 of wgpu 0.15
  • naga 0.12.1, for users of wgpu 0.16
  • future naga versions (starting with 0.13, to be used by future wgpu 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)
image image

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)
image image

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.

rust-gpu v0.7

21 Apr 21:04
Compare
Choose a tag to compare

As we keep following Rust's release cadence, it's time for a new 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 this version, the nightly has been updated to nightly-2023-03-04, so make sure to update your rust-toolchain file if you want to switch to version 0.7.0. This nightly includes the Rust language features supported by Rust 1.69 released this week.

As usual, you can find a complete list of changes in the changelog, but keep reading for the highlights.

Error reporting overhaul

As some rust-gpu errors are deferred to reduce false positives (e.g. for unsupported Rust core APIs, if they're not used in a shader), they could vary a lot more in style or precision, from the Rust compiler errors you might expect.

In this release, we've reworked how such errors are reported, to more precisely locate them, and always use the same strategy (regardless of whether the error comes from libraries like core, or shader code itself).

Here's an example of what it can look like, based on one of our tests most impacted by the change:

Previously (up to 0.6) This release (0.7)
image image

SPIR-🇹 untyped/"quasi" pointer (qptr) experiment

One of the biggest difficulties in compiling Rust to SPIR-V, has been the "typed" vs "untyped" memory distinction:
Rust expects that it can freely reinterpret memory (from unsafe Rust, like union or transmute, or even for safe features like enums), while shader languages and SPIR-V require typed memory (with their types limited to arrays and structs).

So far we've only been able to support e.g. only simple Rust enums like Option<usize>, by relying on them acting more like (bool, usize), than the full general case of tagged unions.

With SPIR-🇹 as an intermediate stage between rust-gpu and SPIR-V, however, we can take a new approach: we can extend SPIR-V with our own untyped pointers, and introduce passes for lowering to such pointers (erasing redundant type information), and for lifting from them back to SPIR-V (regenerating the minimal amount of type information) - everything in between can remain faithful to the untyped memory paradigm Rust prefers.
(the lowering part may become unnecessary, if or when rust-gpu eventually starts emitting SPIR-🇹 directly)

The EmbarkStudios/spirt#24 pull request begins this experiment (codenamed qptr, for "quasi"-pointer), and it's included in this release of rust-gpu, but not enabled by default for now (you can also read more about the overall strategy in that PR).

While we've focused for now only on avoiding regressions in existing rust-gpu shaders, this approach is a promising avenue for unlocking, in the long term, Rust features such as enums, slices, or even dynamic allocation - but perhaps more importantly, future rust-gpu releases could unlock parts of the Rust ecosystem never meant to run on GPUs, and we're very excited to see how far we can push such experiments.

For now, if you would like to try out the initial stage of this experiment, you can use:

RUSTGPU_CODEGEN_ARGS="--no-infer-storage-classes --spirt-passes=qptr"

(--no-infer-storage-classes disables the existing rust-gpu "SPIR-V Storage Class inference" pass, meaning the pass lifting qptrs back to SPIR-V pointers, would alone be figuring out all all of the same information)

Whether it works or not, we'd love to hear back! (especially if you encounter bugs with it, that our testing didn't catch).

Improvements to the Image API

We also made some quality-of-live improvements to spirv-std, specifically to the Image API. Previously, most sampling functions always returned a 4-vector, regardless of the image format. With this PR, it will take into account the image format. For example, calling sample() on an rg32f image will yield a glam::Vec2, as the pixel format only has 2 components. For images with an Unknown format, you have to option to specify the number of components, like so: Image!(2d, type=f32, components=3). The components parameter is optional, and defaults to 4 when not specified.

This release also enables a new experimental API to specify what is known as image operands in SPIR-V. We already supported quite a few of these operands by manually specific functions, such as sample_by_lod() that allows you to specify a lod parameter. But with this new API, this is generalized using a builder pattern to build a parameter object that you can then pass to a generic function, like so:

let s = image.sample_with(*sampler, coords, sample_with::bias(1.0));

We currently support the following operands: bias, lod, grad and sample_index. Although the API lets you chain parameters, as in sample_with::bias(1.0).grad(dx, dy).lod(1.0), this combination of parameters do not make sense semantically so you will get a validation error. More operands will be added in the future. One thing that is possible with this new API that wasn't possible before, is specifying the sample index when fetching from a multisampled texture, using image.fetch_with(coord, sample_with::sample_index(idx)). We refer you to the actual PR for more information and usage patterns.

rust-gpu v0.6.1

20 Mar 16:19
Compare
Choose a tag to compare

A new minor release containing the fix (#1006) for a bug (#1002) causing incorrect SPIR-V to be generated when issuing a OpReturnValue instruction inside an asm! block of a function that gets inlined.

Affected API functions of spirv-std are:

  • IndexedUnchecked::index_unchecked() for [T] and [T; N]
  • IndexedUnchecked::index_unchecked_mut() for [T] and [T; N]
  • AccelerationStrucutre::from_u64()
  • AccelerationStructure::from_vec()
  • RuntimeArray::index()
  • RuntimeArray::index_mut()

This bug got triggered by a new inlining codepath in rustc's MIR and was introduced somewhere before the release of 0.4.0 and remained undetected until now.

A workaround for previous versions of rust-gpu is to compile your shaders without optimizations in general, e.g. by calling release(false) on your SpirvBuilder object, or by making sure the following environment variable is set as such: RUSTGPU_RUSTFLAGS=-Zmir-opt-level=0

rust-gpu v0.6

15 Mar 14:49
Compare
Choose a tag to compare

rust-gpu in bevy
Rust-gpu hot reloading in action using the rust-gpu plugin for Bevy

Hi there, and welcome to 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 this version, the nightly has been updated to nightly-2023-01-21, so make sure to update your rust-toolchain file if you want to switch to version 0.6.0. This nightly includes the Rust language features supported by Rust 1.68 released last week.

Image API

This release also contains the first part of a change to the Image API, namely the removal of return type inference for the texture fetch functions. In a nutshell, because of the return type inference, the Rust compiler had to know the type where you store the result of a texture fetch. For most use cases, this implied that you had to specifically store the result in an explicitly typed variable before being able to do further computations on it, like so:

// You had to do this in 0.5.0 and before:
let s: Vec3 = texture.sample(uv);
let result = s.xy() * coefficients;

// Rather than this (this works starting from 0.6.0):
let result = texture.sample(uv).xy() * coefficients;

By removing the return type inference, the texture fetch functions, such as sample(), always return a concrete glam Vector type (typically a glam::Vec4 for unknown and floating point formats). However, in order to do this, we had to make the API less generic, and therefore remove support for user supplied vector library bindings. This also means that glam has now become a non-optional dependency of spirv-std, and you no longer need to add glam as feature when depending on spirv-std (in fact, you'll need to remove glam if specified as feature).

If you were using your own vector library, then unfortunately this is a breaking change. You'll need to either switch to glam, or manually convert to and from your vector type of choice. We may want to add support for other popular vector libraries in the future.

Code generation

Furthermore, we made the previously experimental shader IR framework SPIR-🇹 the default. Extensive testing has not resulted in any issues or performance degradation, and in fact this may improve the generated SPIR-V code of your shader. If you previously already opted in using --spirt in the codegen args, you must remove the flag. On the other hand, if this change is causing you issues, you can opt out by specifying --no-spirt (and please let us know by filing a new issue 🙏). You can do so in the RUSTGPU_CODEGEN_ARGS environment variable, or using the new extra_arg() function when invoking the SpirvBuilder from code.

Community spotlight

A big shoutout to the developers of Bevy, and @Shfty in particular, for adding support for rust-gpu to Bevy. The above title image shows hot reloading of shaders written in rust-gpu in the engine. Awesome work, and much appreciated for fast prototyping of rust-gpu shaders! 🚀

rust-gpu v0.5

03 Feb 17:42
Compare
Choose a tag to compare

Yes that's right, another rust-gpu release! 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.

As we mentioned in the previous release notes, we intended to do more frequent releases, and more or less in line with new stable Rust releases. That way you can use your beloved new Rust features as soon as possible. As Rust 1.67 was released last week, it's time for a rust-gpu update as well.

Not much has changed as the 0.4 release was only a month ago. The most notable changes are the update to the nightly-2022-12-18 toolchain, which should cover all new features new to Rust 1.67. We also made it compatible with Rust edition 2021, while we required 2018 before. As usual, more information in the changelog.

That said, we have been busy with some exciting stuff behind the scenes, as we're focusing on better SPIR-V generation and quality of life improvements to the spirv-std API that'll hopefully make writing shaders in rust-gpu a bit less cumbersome in some situations.

Contributors

Thank you to all the contributors who helped make this release possible! 🎉
@Bobo1239, @eddyb, @oisyn.

Special shoutout to @Bobo1239 for submitting their first contribution 🥳.

rust-gpu v0.4

21 Dec 15:53
Compare
Choose a tag to compare

image
Screenshot from Embark's Creative Playground, which uses rust-gpu and raytracing.

Hi there! It's been long overdue, but it's finally here: the fourth 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.

With this release, all relevant crates have been published to crates.io. In fact, this has been the case since 0.4.0-alpha.13, released last August. So you no longer have to refer to our github to pull in rust-gpu, and can instead directly refer to spirv-std and spirv-builder by version! What hasn't changed, though, is that you still need to build your shaders using a specific nightly toolchain of Rust. For rust-gpu 0.4.0, this will be nightly-2022-10-29. We do produce a user friendly error message when the toolchain you're building with does not exactly match the version required for rust-gpu.

It has been a while since we published a proper release, and going forward we'd like to do better. We intend to keep rust-gpu on the same schedule as the stable Rust release, so you can use your favorite new language features as new stable versions of Rust are being released, by just updating your rust-gpu version. As of right now, rust-gpu uses a Rust nightly that is equivalent to Rust 1.66, and you can expect a new release on or around the 26th of January, 2023, when Rust 1.67 is planned to be released.

A lot has changed since v0.3, too much to summarize in these release notes. However, we have started to track our changes in a changelog and have even retroactively listing all changes since the first release 🙂. We'll try our best to feature some of the hightlights here, but please refer to the changelog for a more detailed accounting.

There is one thing we want to highlight in particular: rust-gpu now supports ray-tracing. Using #[spirv(..)] attributes, you can define entry points for various raytracing events: intersection, any_hit, closest_hit, and miss. The #[spirv(ray_generation)] can be used to define a ray generation shader. We still lack proper examples in our codebase, but for now we can refer you to the spirv_std::ray_tracing documentation. The code example below shows a somewhat stripped down shader that is used to generate the shadows in above screenshot.

Show ray-tracing code example
pub struct ShadowPayload {
    shadowed: u32,
}

pub fn trace_shadow_ray(
    acceleration_structure: &AccelerationStructure,
    mut ray_desc: RayDesc,
    payload: &mut ShadowPayload,
) -> bool {
    payload.shadowed = 1;

    unsafe {
        // see documentation of `spirv_std::ray_tracing::AccelerationStructure` on what these values mean
        acceleration_structure.trace_ray(
            RayFlags::SKIP_CLOSEST_HIT_SHADER, // ray flags
            !0,             // cull mask
            0,              // shader binding table offset
            0,              // shader binding table stride
            0,              // miss index
            origin,         // ray origin
            0.0,            // tmin
            direction,      // ray direction
            f32::MAX,       // tmax
            payload,        // payload
        );
    }

    payload.shadowed != 0
}

#[spirv(miss)]
pub fn miss(#[spirv(incoming_ray_payload)] payload: &mut ShadowPayload) {
    payload.shadowed = 0;
}

#[spirv(ray_generation)]
pub fn raygen(
    #[spirv(descriptor_set = 0, binding = 0)] output_tex: &Image!(2D, format=rgba16f, sampled=false),
    #[spirv(descriptor_set = 1, binding = 0)] acceleration_structure: &AccelerationStructure,
    #[spirv(ray_payload)] payload: &mut ShadowPayload,
) {
    let ray_origin = /* calculate ray origin */;
    let ray_dir = /* calculate ray dir */;

    let shadowed = trace_shadow_ray(
        acceleration_structure,
        ray_origin,
        ray_dir,
        payload,
    );

    unsafe {
        output_tex.write(px, if shadowed { Vec3::ZERO } else { Vec3::ONE });
    }
}

Language and code generation changes

  • Updated toolchain to nightly-2022-10-29.
  • Changed the way the #[spirv(..)] attribute works, because of the removal of register_attr support in Rust. You now need the spirv macro attribute to be globally visible by doing:
     use spirv_std::spirv;
    See also this migration guide for more information. PR#926
  • Replaced spirv_std::storage_class "named pointer types" with #[spirv(...)] &T entry-point parameters. (PR#443). This means you can now use the following code:
    #[spirv(fragment)]
    pub fn main(
        #[spirv(frag_coord)] in_frag_coord: &Vec4,    // instead of: #[spirv(frag_coord)] in_frag_coord: Input<Vec4>,
        output: &mut Vec4,                            // instead of: mut output: Output<Vec4>,
    ) {
      // ...
    }
  • Added basic support for unsized structs (e.g. ending with a [T] field). PR#504
  • Removed the need to manually specify the storage class for Image/Sampler/ImageSampler entry-point parameters. PR#567
  • Added support for constant memory (&'static _ references), within the limits of SPIR-V. PR#586
  • Added #[spirv(subgroup_local_invocation_id)]. PR#848
  • Removed the fn/closure #[spirv(unroll_loops)] attribute. You can use #[spirv(unroll)] on individual code blocks instead. PR#946
  • This release includes an experimental new shader IR framework called SPIR-🇹, which will ultimately help us in generating better SPIR-V code. This library is opt-in, see here how to enable it. Again, experimental, use at own risk. PR#940

API changes

spirv-std

  • Added a const-generic Image type, and Image! macro wrapping it. PR#359.
    #[spirv(fragment)]
    pub fn main(
        #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled),
        #[spirv(descriptor_set = 1, binding = 1)] image_array: &Image!(2D, type=f32, arrayed, sampled),
        #[spirv(descriptor_set = 2, binding = 2)] cubemap: &Image!(cube, type=f32, sampled),
        #[spirv(descriptor_set = 3, binding = 3)] sampler: &Sampler,
        output: &mut f32,
    ) {
        let v2 = glam::Vec2::new(0.0, 1.0);
        let v3 = glam::Vec3A::new(0.0, 0.0, 1.0);
        *output = image.sample_depth_reference(*sampler, v2, 1.0);
        *output += image_array.sample_depth_reference(*sampler, v3, 1.0);
        *output += cubemap.sample_depth_reference(*sampler, v3, 1.0);
    }
  • As you might have noticed from above example, cubemaps are now supported as well. PR#521
  • Float packing/unpacking operations. PR#709
  • Lots of other new APIs
    Image: Image::gather/Image::sample_bias#704, Image::query_*#608, Image::read_subpass#643, Image::sample_by_lod/Image::sample_by_gradient#498, Image::fetch#480
    arch: arch::read_clock_khr#757, arch::{signed,unsigned}_{min,max}#763, arch::*memory_barrier*#769, arch::IndexUnchecked#805, arch::atomic_i_increment#839, arch::atomic#877
    Misc: ByteAddressableBuffer#735, SampledImage::sample_by_lod#755, debug_printf!#768, RayQuery::confirm_intersection#822, is_helper_invocation#612, memory_barrier/control_barrier#519

spirv-builder

Read more

rust-gpu v0.3

04 Mar 16:54
Compare
Choose a tag to compare

A high res Sci-Fi helmet by @msiglreith

The Khronos Sci-Fi helmet model. glTF model viewer created by @msiglreith using rust-gpu (Source)

Hello everyone, and welcome to the third 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.

We're still not publishing releases to crates.io or distributing artefacts for rust-gpu, but we still wanted to highlight some of the changes that have been happening over the past couple of months. For more information on how to get started with using rust-gpu in your projects, be sure to check out the Rust-GPU Dev Guide! You can always add a git dependency in cargo to access spirv-builder.

[build-dependencies]
spirv-builder = { git = "https://github.com/EmbarkStudios/rust-gpu.git", branch = "main" }

While not a user facing feature, we are also proud to announce that we've also reached an important internal milestone in rust-gpu. We've now completely rewritten our GLSL shaders in our internal Ark project with Rust thanks to the improvements in this release! 🎉

rustc_codegen_spirv

spirv-std

spirv-builder

Contributors

Thank you to all the contributors who helped make this release possible! 🎉

rust-gpu v0.2

04 Dec 16:08
fecc71d
Compare
Choose a tag to compare

image

Created by @bcata6 using rust-gpu (Rust source) with shaders originally from https://shadertoy.com/

Hello everyone, and welcome to the second 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.

First of all we'd like to welcome @eddyb, who will be working as a collaborator with the rust-gpu team on the compiler backend, and has already been contributing a lot of improvements to rust-gpu!

We're still not really cutting releases for rust-gpu, but we wanted to highlight some of the changes that have been happening over the past month. For more information on how to get started with using it in your projects, be sure to check out the new Rust-GPU Dev Guide!

Community

  • SHADERed, an IDE designed for building shaders have released a plugin and added support for running rust-gpu in SHADERed lite, their in-browser editor. Now you can to write Rust shaders on the web and in an IDE! Check out their blog post for more details on the new features.

SPIR-V Backend

spirv-std

Misc

Contributors

Thank you to all the contributors who helped make this release possible! 🎉

Introducing rust-gpu v0.1 🐉

22 Oct 13:36
7b1a271
Compare
Choose a tag to compare

Today, we're releasing a very early version of rust-gpu - a new project to make Rust a first-class language and ecosystem for GPU code!

GPU programming has historically been done with HLSL or GLSL, simple programming languages that have evolved along with rendering APIs over the years. However, as game engines have evolved, these languages have failed to provide mechanisms for dealing with large codebases, and have generally stayed behind the curve compared to other programming languages.

Our hope with this project is that we push the industry forward by bringing Rust, an existing low-level, safe, and high performance language, to the GPU. And with it come some additional great benefits: a package/module system that's one of the industry's best, built in safety against race-conditions or out of bounds memory access, a wide range of libraries and tools to improve programmer workflows, and many others!

If we do this project right, developers could use open-source crates that provide the graphical effects needed to create beautiful experiences. Instead of sharing snippets of code on forum posts, they could simply add the right crates.

Why Embark?

At Embark, we've been building our own new game engine from the ground up in Rust. We have previous experience in-house developing the RLSL prototype, and we have a team of excellent rendering engineers that are familiar with the problems in current shading languages both from games, game engines and other industries. So, we believe we are uniquely positioned to attempt solving this problem.

We want to streamline our own internal development with a single great language, build an open source graphics ecosystem and community, facilitate code-sharing between GPU and CPU, and most importantly: to enable our (future) users, and fellow developers, to more rapidly build great looking and engaging experiences.

Who are we?

But we can't do this alone. That's why we've decided to develop this project in the open,alongside the rest of the Rust and graphics programming communities. Please connect with us if you are interested in collaborating

Current Status

Compiling and running very simple graphics shaders works, and a significant portion of the core library also compiles.

With this we've been able to create some first real shaders in Rust, such as this sky shader written (source):

Sky shader

However, many things aren't implemented yet: for example, loops and switches aren't supported yet!

That means that while being technically usable, this project is far from being production-ready.

Project Scope

The scope of this overall project is quite broad, but is in multiple stages

  • rustc compiler backend to generate SPIR-V, plugging in via -Z codegen-backend.
  • Focus on Vulkan graphics shaders first, then after Vulkan compute shaders
  • Cargo and crates.io support to develop and publish SPIR-V crates
  • High-level render graph to take advantage of this, make it easy for users to develop and use rendering effects.

An in-depth exploration of our roadmap and milestones can be found here.

Open Development

We'll have weekly meetings on Discord, with open agendas shared in GitHub issues. RFCs and other discussions will also be handled in GitHub.

Want to get started?