Note
I'm no longer working on this. The new blessed project is https://github.com/Rust-GPU/cargo-gpu
Write GPU shaders in Rust
Based on the rust-gpu
project: https://github.com/Rust-GPU/rust-gpu. This project adds a CLI "frontend" to perhaps make using rust-gpu
easier. See their docs for details on how to actually write Rust shaders: https://rust-gpu.github.io/rust-gpu/book/
But here's the basic idea:
use spirv_std::glam::{Vec4, vec4};
#[spirv(fragment)]
pub fn main_fs(output: &mut Vec4) {
*output = vec4(1.0, 0.0, 0.0, 1.0);
}
rust-gpu
requires a specific version of Rust nightly and certain components. Install them with:rustup toolchain install nightly-2023-09-30 --component rust-src,rustc-dev,llvm-tools
Double check that the nightly version matches thechannel
field in therust-toolchain.toml
in this repo.
Usage: rust-gpu-compiler [OPTIONS] <PATH_TO_CRATE> [OUTPUT_PATH]
Arguments:
<PATH_TO_CRATE> Shader crate to compile
[OUTPUT_PATH] If set, shader module will be copied here. Otherwise shader module is copied to the root of the shader crate at `compiled/[crate name].spv`, see logs for exact path
Options:
-t, --target <TARGET>
rust-gpu compile target [default: spirv-unknown-spv1.3]
--deny-warnings
Treat warnings as errors during compilation
--debug
Compile shaders in debug mode
--capability <CAPABILITY>
Enables the provided SPIR-V capabilities. See: `impl core::str::FromStr for spirv_builder::Capability`
--extension <EXTENSION>
Enables the provided SPIR-V extensions. See https://github.com/KhronosGroup/SPIRV-Registry for all extensions
--multimodule
Compile one .spv file per entry point
--spirv-metadata <SPIRV_METADATA>
Set the level of metadata included in the SPIR-V binary [default: none]
--relax-struct-store
Allow store from one struct type to a different type with compatible layout and members
--relax-logical-pointer
Allow allocating an object of a pointer type and returning a pointer value from a function in logical addressing mode
--relax-block-layout
Enable VK_KHR_relaxed_block_layout when checking standard uniform, storage buffer, and push constant layouts. This is the default when targeting Vulkan 1.1 or later
--uniform-buffer-standard-layout
Enable VK_KHR_uniform_buffer_standard_layout when checking standard uniform buffer layouts
--scalar-block-layout
Enable VK_EXT_scalar_block_layout when checking standard uniform, storage buffer, and push constant layouts. Scalar layout rules are more permissive than relaxed block layout so in effect this will override the --relax-block-layout option
--skip-block-layout
Skip checking standard uniform / storage buffer layout. Overrides any --relax-block-layout or --scalar-block-layout option
--preserve-bindings
Preserve unused descriptor bindings. Useful for reflection
--validate <VALIDATE>
Validate the compiled SPIR-V binary and, optionally, its WGSL version using `naga`
Options:
- "spirv": validates the generated SPIR-V binary
- "wgsl": cross-compiles the SPIR-V binary to WGSL, and also validates the WGSL
-h, --help
Print help
-V, --version
Print version
- You can disassemble (inspect a text-readable version of) the resulting
.spv
files and even convert them to other formats like.glsl
with Khronos' SPIR-V Tools: https://github.com/KhronosGroup/SPIRV-Tools. Pre-built binaries are available for most OSes.
rust-gpu
recommends including itself as a dependency of your main project. This generally works, but seeing as it is still in beta, it does have some rough edges and I've found that trying to debug them amongst my own projects' bugs, can make things overly complicated.rust-gpu
pins to an entire Rust toolchain which can add unnecessary restrictions on your own project.- I wonder if the compiler were a separate binary, then this it would a better user experience anyway?
- Will probably need to add multi-module support, see: EmbarkStudios/rust-gpu#539
- Is it possible to make this into a single, publishable, standalone binary?
- Always force build on first run? The
rust-gpu
watcher only rebuilds if the underlying shader code has changed. But changing the CLI args here should also be cause for re-compiling. - A
rust-gpu.toml
to set requirements for the shader. Eg; instead of setting--target spirv-unknown-spv1.3
on the CLI, we can settarget = spirv-unknown-spv1.3
in the root config of the shader crate. - Check shader's
spirv-std
to see if matches the compiler's version and issue a warning if not.
- The original CLI argument code for this project was taken from Bevy's https://github.com/Bevy-Rust-GPU/rust-gpu-builder
- This PR enables a dedicated CLI tool for building shaders: Bevy-Rust-GPU/rust-gpu-builder#8
- Issue discussing lack of docs: EmbarkStudios/rust-gpu#1096
- https://github.com/EmbarkStudios/kajiya
- https://github.com/Patryk27/strolle