Skip to content

Repository files navigation

rspirv

Actions StatusMatrix Room

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 (DR) as the medium for various purposes. rspirv also provides a builder to build the DR interactively and a parser to parse a given SPIR-V binary module into its DR. 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.5 (Revision 4).

Multiple crates are published from this project:

NameCrateDocs
rspirvCrateDocumentation
spirvCrateDocumentation

In total rspirv APIs contains:

The Khronos SPIR-V JSON grammar is leveraged to generate parts of the source code using rspirv-autogen.

Please see the links to docs.rs for detailed documentation.

Status

I plan to implement several functionalities:

  • SPIR-V data representation (DR)
  • 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 DR to LLVM IR transformation (maybe)

The DR doesn't handle OpLine and OpNoLine well right now.

The SPIR-V binary module parser is feature complete.

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:

use rspirv::binary::Assemble;use rspirv::binary::Disassemble;fnmain(){// Buildingletmut b = rspirv::dr::Builder::new();
b.set_version(1,0);
b.capability(spirv::Capability::Shader);
b.memory_model(spirv::AddressingModel::Logical, spirv::MemoryModel::GLSL450);let void = b.type_void();let voidf = b.type_function(void,vec![]);let fun = 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();
b.entry_point(spirv::ExecutionModel::Vertex, fun,"foo",vec![]);let module = b.module();// Assemblinglet code = module.assemble();assert!(code.len() > 20);// Module header contains 5 wordsassert_eq!(spirv::MAGIC_NUMBER, code[0]);// Parsingletmut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(&code,&mut loader).unwrap();let module = loader.module();// Disassemblingassert_eq!(
module.disassemble(),"; SPIR-V\n\ ; Version: 1.0\n\ ; Generator: rspirv\n\ ; Bound: 5\n\ OpCapability Shader\n\ OpMemoryModel Logical GLSL450\n\ OpEntryPoint Vertex %3 \"foo\"\n\ %1 = OpTypeVoid\n\ %2 = OpTypeFunction %1\n\ %3 = OpFunction %1 DontInline|Const %2\n\ %4 = OpLabel\n\ OpReturn\n\ OpFunctionEnd");}

Directory Organization

There are multiple crates inside this repo:

  • autogen/: Crate to generate various Rust code snippets used in the modules in spirv/ and rspirv/, from SPIR-V's JSON grammar. If you are not modifying spirv/ or rspirv/, you don't need to care about this directory.
  • spirv/: The spirv crate.
  • rspirv/: The core rspirv crate.
  • dis/: A binary SPIR-V disassembler based on the rspirv crate.
  • spirv-blobs: SPIR-V blobs provided by the user for testing.

Build

git clone https://github.com/gfx-rs/rspirv.git /path/to/rspirv

If you just want to compile and use the spirv 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 or rspirv crate with new code snippets generated from SPIR-V's JSON grammar:

cd /path/to/rspirv
# Clone the SPIRV-Headers repo
git submodule update --init
cargo run -p rspirv-autogen

Test

Running cargo test would scan spirv-blobs folder and its subfolders (with symlinks followed) for any SPIR-V binary blobs. The test will try to load them, disassemble them, and then compose back from the internal representations, ensuring the smooth round-trip.

Contributions

This project is licensed under the Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0). Please see CONTRIBUTING before contributing.

Authors

This project is initialized Lei Zhang (@antiagainst) and currently developed by the gfx-rs Translators team.

About

Rust implementation of SPIR-V module processing functionalities

Topics

Resources

Contributing

Stars

502 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages