Convert Figma logo to code with AI

EmbarkStudios logorust-gpu

šŸ‰ Making Rust a first-class language and ecosystem for GPU shaders šŸš§

7,374
244
7,374
107

Top Related Projects

12,901

A cross-platform, safe, pure-Rust graphics API.

4,579

Safe and rich Rust wrapper around the Vulkan API

Quick Overview

Rust-GPU is an experimental project that enables writing GPU shaders in Rust. It aims to provide a safer, more ergonomic alternative to traditional shader languages like GLSL or HLSL by leveraging Rust's powerful type system and safety features.

Pros

  • Utilizes Rust's safety features and ergonomics for shader development
  • Potential for better integration with Rust-based game engines and graphics applications
  • Supports cross-compilation to various shader formats (SPIR-V, GLSL, HLSL)
  • Enables code sharing between CPU and GPU

Cons

  • Experimental project, not yet production-ready
  • Limited ecosystem compared to established shader languages
  • May have performance overhead compared to hand-optimized GLSL/HLSL
  • Requires learning Rust for developers familiar with traditional shader languages

Code Examples

  1. Basic vertex shader:
#[spirv(vertex)]
pub fn main(
    #[spirv(vertex_index)] vert_id: i32,
    #[spirv(position)] out_pos: &mut Vec4,
) {
    let x = (vert_id - 1) % 2;
    let y = (vert_id - 1) / 2;
    *out_pos = vec4(x as f32 * 2.0 - 1.0, y as f32 * 2.0 - 1.0, 0.0, 1.0);
}
  1. Simple fragment shader:
#[spirv(fragment)]
pub fn main(
    #[spirv(frag_coord)] in_frag_coord: Vec4,
    output: &mut Vec4,
) {
    let r = (in_frag_coord.x / 800.0) as f32;
    let g = (in_frag_coord.y / 600.0) as f32;
    *output = vec4(r, g, 0.0, 1.0);
}
  1. Compute shader example:
#[spirv(compute(threads(64)))]
pub fn main(
    #[spirv(global_invocation_id)] id: UVec3,
    #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] data: &mut [f32],
) {
    let i = id.x as usize;
    data[i] = data[i].sqrt();
}

Getting Started

  1. Add rust-gpu to your Cargo.toml:

    [dependencies]
    spirv-std = "0.4"
    
  2. Create a shader crate with the following in lib.rs:

    #![no_std]
    #![cfg_attr(target_arch = "spirv", feature(lang_items))]
    use spirv_std::glam::{vec4, Vec4};
    
    #[spirv(fragment)]
    pub fn main(output: &mut Vec4) {
        *output = vec4(1.0, 0.0, 0.0, 1.0);
    }
    
  3. Compile the shader:

    cargo build --target spirv-unknown-spv1.5
    
  4. Use the resulting SPIR-V shader in your graphics application.

Competitor Comparisons

12,901

A cross-platform, safe, pure-Rust graphics API.

Pros of wgpu

  • Cross-platform support for multiple graphics APIs (Vulkan, Metal, D3D12, WebGPU)
  • Higher-level abstraction, easier to use for general GPU programming tasks
  • More mature and widely adopted in the Rust ecosystem

Cons of wgpu

  • Less direct control over GPU operations compared to rust-gpu
  • May have slightly higher overhead due to abstraction layers
  • Limited to specific GPU programming paradigms supported by the API

Code Comparison

rust-gpu:

#[spirv(compute(threads(64)))]
pub fn main(
    #[spirv(global_invocation_id)] id: glam::UVec3,
    #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] data: &mut [f32],
) {
    let idx = id.x as usize;
    data[idx] = data[idx].sqrt();
}

wgpu:

let mut encoder = device.create_command_encoder(&CommandEncoderDescriptor { label: None });
{
    let mut compute_pass = encoder.begin_compute_pass(&ComputePassDescriptor { label: None });
    compute_pass.set_pipeline(&compute_pipeline);
    compute_pass.set_bind_group(0, &bind_group, &[]);
    compute_pass.dispatch(workgroup_count, 1, 1);
}
4,579

Safe and rich Rust wrapper around the Vulkan API

Pros of vulkano

  • More mature and stable project with a larger community
  • Provides a higher-level abstraction over Vulkan, simplifying development
  • Offers better documentation and examples for beginners

Cons of vulkano

  • Less performant due to higher-level abstractions
  • May not expose all low-level Vulkan features directly
  • Steeper learning curve for those new to Vulkan concepts

Code Comparison

vulkano:

let device = Device::new(physical, &Features::none(), &Extensions::none(), None)?;
let queue = queues.next().unwrap();
let image = StorageImage::new(device.clone(), Dimensions::Dim2d { width: 1024, height: 1024 },
    Format::R8G8B8A8Unorm, Some(queue.family()))?;

rust-gpu:

#[spirv(compute(threads(64)))]
pub fn main(
    #[spirv(global_invocation_id)] id: glam::UVec3,
    #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] output: &mut [u32],
) {
    output[id.x as usize] = id.x;
}

The code snippets demonstrate the difference in approach: vulkano provides a higher-level API for Vulkan operations, while rust-gpu focuses on writing shader code directly in Rust.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Ć°ĀŸĀĀ‰ rust-gpu

Rust as a first-class language and ecosystem for GPU graphics & compute shaders

This project has moved home!

This repository was the nursery of rust-gpu during its inception and while it was still under the stewardship of Embark Studios. It has now moved into community ownership under the Rust-GPU GitHub organization. rust-gpu is still used by Embark and this repository still gets used for work specific to us. However, its main home has relocated to the community.

How rust-gpu began

Historically in games GPU programming has been done through writing either HLSL, or to a lesser extent GLSL. These are 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.

In part this is because it's a niche language for a niche market, and in part this has been because the industry as a whole has sunk quite a lot of time and effort into the status quo. While over-all better alternatives to both languages exist, none of them are in a place to replace HLSL or GLSL. Either because they are vendor locked, or because they don't support the traditional graphics pipeline. Examples of this include CUDA and OpenCL. And while attempts have been made to create language in this space, none of them have gained any notable traction in the gamedev community.

Our hope with this project is that we push the industry forward by bringing an existing, low-level, safe, and high performance language to the GPU; namely Rust. And with it come some additional benefits that can't be overlooked: 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 tools and utilities to improve programmer workflows, and many others!

Backwards compatibility, breaking changes and deprecation

Right now because the project is in an early state of development, we might introduce temporary changes as stop-gap measures, or implement features or APIs that might not work exactly in a way we end up liking. Therefore it is expected that some (if not most) of the user facing code will change and evolve over time. At the moment this means that we make no guarantees about backwards compatibility and have no formal deprecation model in place. Effectively meaning that currently we only support building from source with the latest main branch in our repository. We appreciate our early adopters and would ask them to evolve their code along with ours.

Please read our Contributor Guide for more information on how to get started.

License

Licensed under either of

at your option.