Rust
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

README.md

rspirv

Build Status Build status

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.

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.3 (Revision 1).

Multiple crates are published from this project:

Name Crate Docs
rspirv Crate Documentation
spirv_headers Crate Documentation

In total rspirv APIs contains:

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");
}

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