SPIR-V Toolchain
The LunarG Vulkan SDK includes tools and files for shader generation, inspection and compression improvement.
SPIR-V is a new binary intermediate representation for graphical shaders and compute kernels. This new intermediate representation has many advantages. The advantages and a high-level description of the representation are detailed in the SPIR-V white paper included in the SDK. The SPIR-V provisional specification for the version supported by the SDK is also included. These documents are located in $VULKAN_SDK/doc/khronos/spirv/
(Linux) and $VK_SDK_PATH\Doc
(Windows).
The Vulkan graphics API requires that all shaders be presented in SPIR-V format. As a binary format, it cannot easily be manually created. SPIR-V shaders can be automatically created from equivalent GLSL shaders using the glslangValidator
tool. The SPIR-V code can be read from the file into an application's memory and directly passed to the Vulkan API call vkCreateShader()
.
The SDK includes a SPIR-V disassembler named spirv
for debugging Vulkan applications. This disassembler can create a human-readable text from a SPIR-V file. This text represents the SPIR-V program in terms of SPIR-V objects. Note that the text is not an assembly language, and that the Vulkan SDK does not contain a program which can re-assemble the text into a binary SPIR-V program.
Some Vulkan application publishers will wish to include many SPIR-V files in their distribution package. The Vulkan SDK also includes spirv-remap
, a tool to improve the compressibility of collections of SPIR-V modules. This can result in up to a 50% reduction in the size of a compressed collection relative to the compressed originals, depending on the nature of the modules.
GLSL Validator (SPIR-V Generator)
glslangValidator
is the tool used to compile GLSL shaders into SPIR-V, Vulkan's shader format.
Executed without any options, glslangValidator
returns the message:
Usage: glslangValidator [option]... [file]...
Where: each 'file' ends in .<stage>, where <stage> is one of
.conf to provide an optional config file that replaces the default configuration
(see -c option below for generating a template)
.vert for a vertex shader
.tesc for a tessellation control shader
.tese for a tessellation evaluation shader
.geom for a geometry shader
.frag for a fragment shader
.comp for a compute shader
Compilation warnings and errors will be printed to stdout.
To get other information, use one of the following options:
Each option must be specified separately.
-V create SPIR-V binary, under Vulkan semantics; turns on -l;
default file name is <stage>.spv (-o overrides this)
-G create SPIR-V binary, under OpenGL semantics; turns on -l;
default file name is <stage>.spv (-o overrides this)
-H print human readable form of SPIR-V; turns on -V
-E print pre-processed GLSL; cannot be used with -l;
errors will appear on stderr.
-S <stage> uses explicit stage specified, rather then the file extension.
valid choices are vert, tesc, tese, geom, frag, or comp
-c configuration dump;
creates the default configuration file (redirect to a .conf file)
-C cascading errors; risks crashes from accumulation of error recoveries
-d default to desktop (#version 110) when there is no shader #version
(default is ES version 100)
-D input is HLSL
-e specify entry-point name
-h print this usage message
-i intermediate tree (glslang AST) is printed out
-l link all input files together to form a single module
-m memory leak mode
-o <file> save binary to <file>, requires a binary option (e.g., -V)
-q dump reflection query database
-r relaxed semantic error-checking mode
-s silent mode
-t multi-threaded mode
-v print version strings
-w suppress warnings (except as required by #extension : warn)
-x save 32-bit hexadecimal numbers as text, requires a binary option (e.g., -V)
--shift-sampler-binding [stage] num set base binding number for samplers
--ssb [stage] num synonym for --shift-sampler-binding
--shift-texture-binding [stage] num set base binding number for textures
--stb [stage] num synonym for --shift-texture-binding
--shift-UBO-binding [stage] num set base binding number for UBOs
--sub [stage] num synonym for --shift-UBO-binding
--auto-map-bindings automatically bind uniform variables without
explicit bindings.
--amb synonym for --auto-map-bindings
--flatten-uniform-arrays flatten uniform texture & sampler arrays to scalars
--fua synonym for --flatten-uniform-arrays
SPIR-V Disassembler and Assembler
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.
spirv-dis -h returns the message:
./spirv-dis - Disassemble a SPIR-V binary module
Usage: ./spirv-dis [options] [<filename>]
The SPIR-V binary is read from <filename>. If no file is specified,
or if the filename is "-", then the binary is read from standard input.
Options:
-h, --help Print this help.
--version Display disassembler version information.
-o <filename> Set the output filename.
Output goes to standard output if this option is
not specified, or if the filename is "-".
--no-color Don't print in color.
The default when output goes to a file.
--no-indent Don't indent instructions.
--offsets Show byte offsets for each instruction.
spirv-as -h returns the message:
./spirv-as - Create a SPIR-V binary module from SPIR-V assembly text
Usage: ./spirv-as [options] <filename>
The SPIR-V assembly text is read from <filename>. The SPIR-V binary
module is written to file "out.spv", unless the -o option is used.
Options:
-h Print this help.
-o <filename> Set the output filename.
--version Display assembler version information.
SPIR-V Remapper
The SPIR-V Remapper 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++11 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.
Note: The spirv-remap
tool is in early stages of development and should be considered alpha quality.
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 a message similar to:
Usage:
spirv-remap [-v[v[...]] | --verbose [int]] [--map (all|types|names|funcs)] [--dce (all|types|funcs)] [--opt (all|loadstore)] [--strip-all | --strip all | -s] [--do-everything] --input | -i file1 [file2...] --output|-o DESTDIR
spirv-remap [--version | -V]
spirv-remap [--help | -?]
Options supported by spirv-remap
are identified in the table below. Options can appear anywhere on the command line.
Option | Description |
---|---|
--dce | dead code elimination mode; eliminates dead functions and types |
-i, --input | *.spv shader input files |
--map | remap types, names, functions, or all |
-o, --output | write remapped shader files to this directory |
-s, --strip-all | strip debug symbol information and line numbers |
Examples:
-
Basic ID remapping example:
spirv-remap --map all --input *.spv --output /tmp/out_dir
Performs ID remapping on all shaders in the current directory, writing new files with the same basenames to /tmp/out_dir
.
-
ID remapping with debug symbol and line number stripping:
spirv-remap --map all --strip-all --input *.spv --output /tmp/out_dir
-
ID remapping with debug symbol and line number stripping plus dead function and type elimination:
spirv-remap --map all --dce all --strip-all --input *.spv --output /tmp/out_dir
API
API access to the SPIR-V Remapper may be provided in future SDKs.
SPIR-V Optimization
spirv-opt is a SPIR-V to SPIR-V optimizer. It is a work in progress. Its current capabilities primarily center around setting and optimizing specialization constants. spirv-opt --help
prints the following:
./spirv-opt - Optimize a SPIR-V binary file.
USAGE: ./spirv-opt [options] [<input>] -o <output>
The SPIR-V binary is read from <input>. If no file is specified,
or if <input> is "-", then the binary is read from standard input.
if <output> is "-", then the optimized output is written to
standard output.
NOTE: The optimizer is a work in progress.
Options:
--strip-debug
Remove all debug instructions.
--freeze-spec-const
Freeze the values of specialization constants to their default
values.
--eliminate-dead-const
Eliminate dead constants.
--fold-spec-const-op-composite
Fold the spec constants defined by OpSpecConstantOp or
OpSpecConstantComposite instructions to front-end constants
when possible.
--set-spec-const-default-value "<spec id>:<default value> ..."
Set the default values of the specialization constants with
<spec id>:<default value> pairs specified in a double-quoted
string. <spec id>:<default value> pairs must be separated by
blank spaces, and in each pair, spec id and default value must
be separated with colon ':' without any blank spaces in between.
e.g.: --set-spec-const-default-value "1:100 2:400"
--unify-const
Remove the duplicated constants.
-h, --help Print this help.
--version Display optimizer version information.
SPIR-V Validation
spirv-val is a SPIR-V validation program. It is a work in progress. spirv-val --help
prints the following:
./spirv-val - Validate a SPIR-V binary file.
USAGE: ./spirv-val [options] [<filename>]
The SPIR-V binary is read from <filename>. If no file is specified,
or if the filename is "-", then the binary is read from standard input.
NOTE: The validator is a work in progress.
Options:
-h, --help Print this help.
--version Display validator version information.
--target-env {vulkan1.0|spv1.0|spv1.1}
Use Vulkan1.0/SPIR-V1.0/SPIR-V1.1 validation rules.
SPIR-V Control Flow Visualization
spirv-cfg shows the SPIR-V control flow in GraphiViz "dot" form. It is experimental. spirv-cfg --help
prints the following:
./spirv-cfg - Show the control flow graph in GraphiViz "dot" form. EXPERIMENTAL
Usage: ./spirv-cfg [options] [<filename>]
The SPIR-V binary is read from <filename>. If no file is specified,
or if the filename is "-", then the binary is read from standard input.
Options:
-h, --help Print this help.
--version Display version information.
-o <filename> Set the output filename.
Output goes to standard output if this option is
not specified, or if the filename is "-".
SPIR-V Cross-Compilation and Reflection
spirv-cross translates SPIR-V files into readable shader languages including GLSL, MSL (experimental) and C++ (experimental). 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.
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.
Shaderc consists of two components: a command line compiler and a static library. The command line compiler (glslc) is provided by the SDK and is put in the user's path so that it can be used from the command prompt. glslc --help
shows the latest command line options.
Windows
On Windows, the static library is provided only as a release build. As such, to link a debuggable program to the shaderc included in the SDK, it is necessary to build the library from the source provided in the SDK. To build a 64-bit debuggable library from the SDK, use the folloing commands (you will need msbuild and cmake to be available from the command prompt):
cd %VULKAN_SDK%\shaderc
cmake -H. -Bbuild -G "Visual Studio 14 Win64"
cmake --build ./build --config Debug
Note that you may have to adjust the Visual Studio version, depending on which version you are using.
Linux
On Linux, shaderc is provided as source code only. The easiest way to build shaderc is to run the build_tools
script located in the root of the SDK. Alternatively, the library can also be build using:
cd <Version>/source/shaderc
python update_shaderc_sources.py
cd src
cmake -H. -Bbuild -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
make -Cbuild
Additional information for using shaderc can be found at the shaderc github page.