rspirv
Rust implementation of SPIR-V module processing functionalities. It aims to provide:
- APIs for processing SPIR-V modules
- Command line tools building on top of the APIs for common processing tasks
rspirv defines a common SPIR-V data representation (MR) as the medium for various purposes. rspirv also provides a builder to build the MR interactively and a parser to parse a given SPIR-V binary module into its MR. A higher level structured representation is currently under developing.
SPIR-V is a common intermediate language for representing graphics shaders and compute kernels for multiple Khronos APIs, such as Vulkan, OpenGL, and OpenCL.
SPIRV-Tools is the Khronos Group's official C++ implementation of SPIR-V binary parser, assembler, disassembler, optimizer, and validator. rspirv is not a Rust language binding for that project; it is a complete rewrite using Rust.
Documentation
The current implementation supports SPIR-V 1.3 (Revision 4).
Multiple crates are published from this project:
Name | Crate | Docs |
---|---|---|
rspirv | ||
spirv_headers |
In total rspirv APIs contains:
- The SPIR-V header (all SPIR-V structs, enums, and constants)
- The whole SPIR-V grammar (instruction layouts and their operands)
- A data representation of SPIR-V modules and its loader and builder
- SPIR-V binary module decoding and parsing functionalities
The Khronos SPIR-V JSON grammar is leveraged to generate parts of the source code using Cargo build scripts.
Please see the links to docs.rs for detailed documentation.
Status
I plan to implement several functionalities:
- SPIR-V data representation (MR)
- SPIR-V module builder
- SPIR-V module assembler
- SPIR-V binary module parser
- SPIR-V binary module disassembler
- HLSL/GLSL to SPIR-V frontend (maybe)
- SPIR-V MR to LLVM IR transformation (maybe)
The MR doesn't handle OpLine
and OpNoLine
well right now.
The SPIR-V binary module parser is almost feature complete; the only feature
(that I am aware of) missing is 64-bit selectors in OpSwitch
.
Usage
This project uses associated constants, which became available in the stable channel since 1.20. So to compile with a compiler from the stable channel, please make sure that the version is >= 1.20.
Examples
Building a SPIR-V module, assembling it, parsing it, and then disassembling it:
extern crate rspirv;
extern crate spirv_headers as spirv;
use rspirv::binary::Assemble;
use rspirv::binary::Disassemble;
fn main() {
// Building
let mut b = rspirv::mr::Builder::new();
b.set_version(1, 0);
b.memory_model(spirv::AddressingModel::Logical, spirv::MemoryModel::GLSL450);
let void = b.type_void();
let voidf = b.type_function(void, vec![void]);
b.begin_function(void,
None,
(spirv::FunctionControl::DONT_INLINE |
spirv::FunctionControl::CONST),
voidf)
.unwrap();
b.begin_basic_block(None).unwrap();
b.ret().unwrap();
b.end_function().unwrap();
let module = b.module();
// Assembling
let code = module.assemble();
assert!(code.len() > 20); // Module header contains 5 words
assert_eq!(spirv::MAGIC_NUMBER, code[0]);
// Parsing
let mut loader = rspirv::mr::Loader::new();
rspirv::binary::parse_words(&code, &mut loader).unwrap();
let module = loader.module();
// Disassembling
assert_eq!(module.disassemble(),
"; SPIR-V\n\
; Version: 1.0\n\
; Generator: rspirv\n\
; Bound: 5\n\
OpMemoryModel Logical GLSL450\n\
%1 = OpTypeVoid\n\
%2 = OpTypeFunction %1 %1\n\
%3 = OpFunction %1 DontInline|Const %2\n\
%4 = OpLabel\n\
OpReturn\n\
OpFunctionEnd");
}
Directory Organization
There are multiple crates inside this repo:
codegen/
: Crate to generate various Rust code snippets used in the modules inspirv/
andrspirv/
, from SPIR-V's JSON grammar. If you are not modifyingspirv/
orrspirv/
, you don't need to care about this directory.spirv/
: Thespirv_headers
crate.rspirv/
: The corerspirv
crate.dis/
: A binary SPIR-V disassembler based on therspirv
crate.
Build
git clone https://github.com/gfx-rs/rspirv.git /path/to/rspirv
If you just want to compile and use the spirv_headers
crate:
cd /path/to/rspirv/spirv
cargo build
If you just want to compile and use the rspirv
crate:
cd /path/to/rspirv/rspirv
cargo build
If you want to refresh the spirv_headers
or rspirv
crate with new code
snippets generated from SPIR-V's JSON grammar,
cd /path/to/rspirv/codegen
# Clone the SPIRV-Headers repo
git submodule update --init
cargo build
Contributions
This project is licensed under the Apache 2 license. Please see CONTRIBUTING before contributing.
Authors
This project is initialized Lei Zhang (@antiagainst) and currently developed by the gfx-rs Translators team.