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 iteractively 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.
Disclaimer
This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.
Documentation
The current implementation supports SPIR-V 1.1 (Revision 5).
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 serveral functionalities:
- SPIR-V data representation (MR)
- SPIR-V module builder
- SPIR-V module assembler
- SPIR-V binary module parser
- SPIR-V binary module disassemebler
- 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 custom derive, which became available in the stable channel since 1.15. So to compile with a compiler from the stable channel, please make sure that the version is >= 1.15.
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.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::FUNCTION_CONTROL_DONT_INLINE |
spirv::FUNCTION_CONTROL_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.1\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");
}
Contributions
This project is licensed under the Apache 2 license. Please see CONTRIBUTING before contributing.
Authors
This project is initialized and mainly developed by Lei Zhang (@antiagainst).