# SPIR-V Toolchain

The Vulkan graphics API requires that all shaders be presented in SPIR-V format. SPIR-V is a binary intermediate representation for graphical shaders and compute kernels. The advantages and a high-level description of the representation are given in the SPIR-V White Paper. A more detailed description of the SPIR-V supported by this SDK can be found in The SPIR-V Specification.

The Vulkan SDK includes tools for SPIR-V shader generation, inspection, editing, validation, optimization, constant manipulation, and compression improvement. The SDK includes both command-line executables as well as libraries and headers to access these capabilities programmatically.

Command-line executables can be found in the `Bin` subdirectory of the SDK file structure. Static libraries as well as macOS and Linux dynamic libraries can be found in the `Lib` subdirectory. Windows dynamic libraries can be found in `Bin`. Header files can be found in the `Include` subdirectory. Only release build versions for these executables and libraries are included in the SDK.

For the Linux SDK, some of these tools are not included as binaries for possible compatibility issues. They can be built with an included script like so: `vulkansdk spirvtools`.

## glslangValidator (SPIR-V Generator)

`glslangValidator` is the tool used to compile GLSL and HLSL shaders into SPIR-V, Vulkan's shader format. Additional information on compiling HLSL can be found in the HLSL FAQ.

Executed without any options, `glslangValidator` returns its usage info. Information on using this tool programmatically through its library API can be found here. The glslang.lib static library requries the use of the following additional static libraries: OSDependent.lib, MachineIndependent.lib, GenericCodeGen.lib, and OGLCompiler.lib (note on Linux and macOS, these files have a 'lib' prefix and a .a suffix).

## SPIR-V Optimizer

A programmer may wish to reduce the size of a SPIR-V file, especially as it is initially generated by the `glslangValidator` frontend. The SPIR-V optimizer `spirv-opt` can be used to apply classic optimization transformations to SPIR-V to reduce its size without changing its functionality.

`spirv-opt` can also be used to manipulate a SPIR-V file's specialization constants.

`spirv-opt -h` returns its usage info. Information on using this tool programmatically through its library API can be found here. This requires both the SPIRV-Tools.lib and SPIRV-Tools-opt.lib static library files. (Note on Linux and macOS, these files have a 'lib' prefix and a .a suffix).

## SPIR-V Disassembler, Assembler and Validator

A programmer may wish to view or change the contents of a shader while debugging a Vulkan application. Since Vulkan accepts shaders only in SPIR-V, a binary format, the SDK provides `spirv-dis`, a standalone program which prints a SPIR-V shader in human-readable and parsable form, and `spirv-as`, which can assemble the possibly edited output of `spirv-dis`. Finally, `spirv-val` can be used to verify that the resulting SPIR-V code is valid.

Calling any of these programs with `-h` returns its usage info. Information on using these tools programmatically through their library API can be found here.

## SPIR-V diff

The diff tool takes two SPIR-V files, either in binary or text format and produces a diff-style comparison between the two. The instructions between the src and dst modules are matched as best as the tool can, and output is produced (in src id-space) that shows which instructions are removed in src, added in dst or modified between them. The order of instructions are not retained.

Matching instructions between two SPIR-V modules is not trivial, and thus a number of heuristics are applied in this tool. In particular, without debug information, match functions is nontrivial as they can be reordered. As such, this tool is primarily useful to produce the diff of two SPIR-V modules derived from the same source, for example before and after a modification to the shader, before and after a transformation, or SPIR-V produced from different tools.

More information can be found here.

## SPIR-V Remapper

The SPIR-V remapping tool, `spirv-remap`, enhances compression of SPIR-V binary files via entropy reduction, including optional stripping of debug information and dead functions. `spirv-remap` transforms SPIR-V to SPIR-V, remapping IDs to reduce the size of a compressed image containing multiple SPIR-V modules. This works with compression procedures that can find dictionary entries across multiple files.

The SPIR-V Remapper supports two modes of use: command line and a C++ API.

Remapping is accomplished via ID canonicalization. In this scheme, IDs become larger and are no longer tightly packed near zero, but should compress better when multiple modules are compressed together. The command line tool operates serially on multiple modules. The API accepts only a single module at a time.

Detailed usage instructions can be found here

### Command Line

`spirv-remap` supports multiple levels of verbosity, specified with `-v`, `-vv`, `-vvv`, etc or by providing an integer parameter to the `--verbose` option. Note that higher levels of verbosity provide a considerable quantity of `stdout` messages. With no verbosity, `spirv-remap` is silent, returning 0 on success and a positive integer error status on error.

The SPIR-V remapper provides basic ID remapping, ID remapping with debug symbol and line number stripping, and ID remapping with those features plus dead function and type elimination.

Executed without any options, `spirv-remap` returns its usage info.

## SPIR-V Control Flow Visualization

`spirv-cfg` shows the SPIR-V control flow in GraphiViz "dot" form. It is experimental. `spirv-cfg --help` prints its usage info.

## SPIR-V Cross-Compilation and Reflection

`spirv-cross` translates SPIR-V files into readable shader languages including GLSL, HLSL and MSL. It can also generate reflection information for a SPIR-V shader. `spirv-cross --help` shows the latest command line options. Additional information for using this tool can be found at the spirv-cross github page. Information on using this tool programmatically through its library API can be found here.

## Shaderc - SPIR-V Compilation Wrapper

Shaderc wraps around core functionality in glslang and SPIRV-Tools. Shaderc aims to to provide: a command line compiler with GCC and Clang-like usage for better integration with build systems, an API where functionality can be added without breaking existing clients, an API supporting standard concurrency patterns across multiple operating systems, and increased functionality such as file `#include` support.

Additional information for using shaderc can be found at the shaderc github page. Information on using this tool programmatically through its library API can be found here. Note: This requires linking either to the static library shaderc_combined, or the following libraries: shaderc.lib, glslang.lib, OSDependent.lib, OGLCompiler.lib, shaderc_util.lib, SPIRV.lib, HLSL.lib, SPIRV-Tools.lib, SPIRV-Tools-opt.lib, GenericCodeGen.lib, MachineIndependent.lib, shaderc_util.lib. (Note on Linux and macOS, these files have a 'lib' prefix and a .a suffix).

## DXC - DirectX Shader Compiler

The DirectX Shader Compiler is a compiler used to compile High-Level Shader Language (HLSL) programs into SPIR-V intermediate representation.

To learn how to use the DirectX Shader Compiler execute "dxc --help" from a command prompt.

Please note that there is another copy of DXC that is created through installation of Visual Studio. That copy supports the DirectX API and has Vulkan capability disabled. The copy available through the Vulkan SDK alone does not support DirectX. The behavior of the "dxc" command is thus dependent of the value of the PATH environment variable. Please keep this in mind as you invoke the "dxc" command.

The DXC Shader Compiler is also available as a shared library on 64-bit desktop operating systems (macOS, Windows, and Ubuntu). The headers and an import library for the DLL are included in the SDK. Information on using this tool programmatically through its library API can be found here.

## SPIRV Reflect

SPIRV-Reflect is a lightweight source code library that provides a C/C++ reflection API for SPIR-V shader bytecode in Vulkan applications. Full documentation for using the tool can be found here.

## slang

Slang is a shading language that makes it easier to build and maintain large shader codebases in a modular and extensible fashion, while also maintaining the highest possible performance on modern GPUs and graphics APIs. Slang is based on years of collaboration between researchers at NVIDIA, Carnegie Mellon University, Stanford, MIT, UCSD and the University of Washington. Full documentation for the tool can be found here