1# SPIR-V Tools 2 3[![Build status](https://ci.appveyor.com/api/projects/status/gpue87cesrx3pi0d/branch/master?svg=true)](https://ci.appveyor.com/project/Khronoswebmaster/spirv-tools/branch/master) 4<img alt="Linux" src="kokoro/img/linux.png" width="20px" height="20px" hspace="2px"/>![Linux Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_linux_release.svg) 5<img alt="MacOS" src="kokoro/img/macos.png" width="20px" height="20px" hspace="2px"/>![MacOS Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_macos_release.svg) 6<img alt="Windows" src="kokoro/img/windows.png" width="20px" height="20px" hspace="2px"/>![Windows Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_windows_release.svg) 7 8## Overview 9 10The SPIR-V Tools project provides an API and commands for processing SPIR-V 11modules. 12 13The project includes an assembler, binary module parser, disassembler, 14validator, and optimizer for SPIR-V. Except for the optimizer, all are based 15on a common static library. The library contains all of the implementation 16details, and is used in the standalone tools whilst also enabling integration 17into other code bases directly. The optimizer implementation resides in its 18own library, which depends on the core library. 19 20The interfaces have stabilized: 21We don't anticipate making a breaking change for existing features. 22 23SPIR-V is defined by the Khronos Group Inc. 24See the [SPIR-V Registry][spirv-registry] for the SPIR-V specification, 25headers, and XML registry. 26 27## Versioning SPIRV-Tools 28 29See [`CHANGES`](CHANGES) for a high level summary of recent changes, by version. 30 31SPIRV-Tools project version numbers are of the form `v`*year*`.`*index* and with 32an optional `-dev` suffix to indicate work in progress. For exampe, the 33following versions are ordered from oldest to newest: 34 35* `v2016.0` 36* `v2016.1-dev` 37* `v2016.1` 38* `v2016.2-dev` 39* `v2016.2` 40 41Use the `--version` option on each command line tool to see the software 42version. An API call reports the software version as a C-style string. 43 44## Supported features 45 46### Assembler, binary parser, and disassembler 47 48* Support for SPIR-V 1.0, 1.1, 1.2, and 1.3 49 * Based on SPIR-V syntax described by JSON grammar files in the 50 [SPIRV-Headers](spirv-headers) repository. 51* Support for extended instruction sets: 52 * GLSL std450 version 1.0 Rev 3 53 * OpenCL version 1.0 Rev 2 54* Assembler only does basic syntax checking. No cross validation of 55 IDs or types is performed, except to check literal arguments to 56 `OpConstant`, `OpSpecConstant`, and `OpSwitch`. 57 58See [`syntax.md`](syntax.md) for the assembly language syntax. 59 60### Validator 61 62The validator checks validation rules described by the SPIR-V specification. 63 64Khronos recommends that tools that create or transform SPIR-V modules use the 65validator to ensure their outputs are valid, and that tools that consume SPIR-V 66modules optionally use the validator to protect themselves from bad inputs. 67This is especially encouraged for debug and development scenarios. 68 69The validator has one-sided error: it will only return an error when it has 70implemented a rule check and the module violates that rule. 71 72The validator is incomplete. 73See the [CHANGES](CHANGES) file for reports on completed work, and 74the [Validator 75sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/1) for planned 76and in-progress work. 77 78*Note*: The validator checks some Universal Limits, from section 2.17 of the SPIR-V spec. 79The validator will fail on a module that exceeds those minimum upper bound limits. 80It is [future work](https://github.com/KhronosGroup/SPIRV-Tools/projects/1#card-1052403) 81to parameterize the validator to allow larger 82limits accepted by a more than minimally capable SPIR-V consumer. 83 84 85### Optimizer 86 87*Note:* The optimizer is still under development. 88 89Currently supported optimizations: 90* General 91 * Strip debug info 92* Specialization Constants 93 * Set spec constant default value 94 * Freeze spec constant 95 * Fold `OpSpecConstantOp` and `OpSpecConstantComposite` 96 * Unify constants 97 * Eliminate dead constant 98* Code Reduction 99 * Inline all function calls exhaustively 100 * Convert local access chains to inserts/extracts 101 * Eliminate local load/store in single block 102 * Eliminate local load/store with single store 103 * Eliminate local load/store with multiple stores 104 * Eliminate local extract from insert 105 * Eliminate dead instructions (aggressive) 106 * Eliminate dead branches 107 * Merge single successor / single predecessor block pairs 108 * Eliminate common uniform loads 109 * Remove duplicates: Capabilities, extended instruction imports, types, and 110 decorations. 111 112For the latest list with detailed documentation, please refer to 113[`include/spirv-tools/optimizer.hpp`](include/spirv-tools/optimizer.hpp). 114 115For suggestions on using the code reduction options, please refer to this [white paper](https://www.lunarg.com/shader-compiler-technologies/white-paper-spirv-opt/). 116 117 118### Linker 119 120*Note:* The linker is still under development. 121 122Current features: 123* Combine multiple SPIR-V binary modules together. 124* Combine into a library (exports are retained) or an executable (no symbols 125 are exported). 126 127See the [CHANGES](CHANGES) file for reports on completed work, and the [General 128sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/2) for 129planned and in-progress work. 130 131### Extras 132 133* [Utility filters](#utility-filters) 134* Build target `spirv-tools-vimsyntax` generates file `spvasm.vim`. 135 Copy that file into your `$HOME/.vim/syntax` directory to get SPIR-V assembly syntax 136 highlighting in Vim. This build target is not built by default. 137 138## Contributing 139 140The SPIR-V Tools project is maintained by members of the The Khronos Group Inc., 141and is hosted at https://github.com/KhronosGroup/SPIRV-Tools. 142 143Consider joining the `public_spirv_tools_dev@khronos.org` mailing list, via 144[https://www.khronos.org/spir/spirv-tools-mailing-list/](https://www.khronos.org/spir/spirv-tools-mailing-list/). 145The mailing list is used to discuss development plans for the SPIRV-Tools as an open source project. 146Once discussion is resolved, 147specific work is tracked via issues and sometimes in one of the 148[projects][spirv-tools-projects]. 149 150(To provide feedback on the SPIR-V _specification_, file an issue on the 151[SPIRV-Headers][spirv-headers] GitHub repository.) 152 153See [`projects.md`](projects.md) to see how we use the 154[GitHub Project 155feature](https://help.github.com/articles/tracking-the-progress-of-your-work-with-projects/) 156to organize planned and in-progress work. 157 158Contributions via merge request are welcome. Changes should: 159* Be provided under the [Apache 2.0](#license). 160* You'll be prompted with a one-time "click-through" 161 [Khronos Open Source Contributor License Agreement][spirv-tools-cla] 162 (CLA) dialog as part of submitting your pull request or 163 other contribution to GitHub. 164* Include tests to cover updated functionality. 165* C++ code should follow the [Google C++ Style Guide][cpp-style-guide]. 166* Code should be formatted with `clang-format`. 167 [kokoro/check-format/build.sh](kokoro/check-format/build.sh) 168 shows how to download it. Note that we currently use 169 `clang-format version 5.0.0` for SPIRV-Tools. Settings are defined by 170 the included [.clang-format](.clang-format) file. 171 172We intend to maintain a linear history on the GitHub `master` branch. 173 174### Source code organization 175 176* `example`: demo code of using SPIRV-Tools APIs 177* `external/googletest`: Intended location for the 178 [googletest][googletest] sources, not provided 179* `external/effcee`: Location of [Effcee][effcee] sources, if the `effcee` library 180 is not already configured by an enclosing project. 181* `external/re2`: Location of [RE2][re2] sources, if the `re2` library is not already 182 configured by an enclosing project. 183 (The Effcee project already requires RE2.) 184* `include/`: API clients should add this directory to the include search path 185* `external/spirv-headers`: Intended location for 186 [SPIR-V headers][spirv-headers], not provided 187* `include/spirv-tools/libspirv.h`: C API public interface 188* `source/`: API implementation 189* `test/`: Tests, using the [googletest][googletest] framework 190* `tools/`: Command line executables 191 192Example of getting sources, assuming SPIRV-Tools is configured as a standalone project: 193 194 git clone https://github.com/KhronosGroup/SPIRV-Tools.git spirv-tools 195 git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-tools/external/spirv-headers 196 git clone https://github.com/google/googletest.git spirv-tools/external/googletest 197 git clone https://github.com/google/effcee.git spirv-tools/external/effcee 198 git clone https://github.com/google/re2.git spirv-tools/external/re2 199 200### Tests 201 202The project contains a number of tests, used to drive development 203and ensure correctness. The tests are written using the 204[googletest][googletest] framework. The `googletest` 205source is not provided with this project. There are two ways to enable 206tests: 207* If SPIR-V Tools is configured as part of an enclosing project, then the 208 enclosing project should configure `googletest` before configuring SPIR-V Tools. 209* If SPIR-V Tools is configured as a standalone project, then download the 210 `googletest` source into the `<spirv-dir>/external/googletest` directory before 211 configuring and building the project. 212 213*Note*: You must use a version of googletest that includes 214[a fix][googletest-pull-612] for [googletest issue 610][googletest-issue-610]. 215The fix is included on the googletest master branch any time after 2015-11-10. 216In particular, googletest must be newer than version 1.7.0. 217 218### Dependency on Effcee 219 220Some tests depend on the [Effcee][effcee] library for stateful matching. 221Effcee itself depends on [RE2][re2]. 222 223* If SPIRV-Tools is configured as part of a larger project that already uses 224 Effcee, then that project should include Effcee before SPIRV-Tools. 225* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee` 226 and RE2 sources to appear in `external/re2`. 227 228 229## Build 230 231Instead of building manually, you can also download the binaries for your 232platform directly from the [master-tot release][master-tot-release] on GitHub. 233Those binaries are automatically uploaded by the buildbots after successful 234testing and they always reflect the current top of the tree of the master 235branch. 236 237The project uses [CMake][cmake] to generate platform-specific build 238configurations. Assume that `<spirv-dir>` is the root directory of the checked 239out code: 240 241```sh 242cd <spirv-dir> 243git clone https://github.com/KhronosGroup/SPIRV-Headers.git external/spirv-headers 244git clone https://github.com/google/effcee.git external/effcee 245git clone https://github.com/google/re2.git external/re2 246git clone https://github.com/google/googletest.git external/googletest # optional 247 248mkdir build && cd build 249cmake [-G <platform-generator>] <spirv-dir> 250``` 251 252Once the build files have been generated, build using your preferred 253development environment. 254 255### CMake options 256 257The following CMake options are supported: 258 259* `SPIRV_COLOR_TERMINAL={ON|OFF}`, default `ON` - Enables color console output. 260* `SPIRV_SKIP_TESTS={ON|OFF}`, default `OFF`- Build only the library and 261 the command line tools. This will prevent the tests from being built. 262* `SPIRV_SKIP_EXECUTABLES={ON|OFF}`, default `OFF`- Build only the library, not 263 the command line tools and tests. 264* `SPIRV_BUILD_COMPRESSION={ON|OFF}`, default `OFF`- Build SPIR-V compressing 265 codec. 266* `SPIRV_USE_SANITIZER=<sanitizer>`, default is no sanitizing - On UNIX 267 platforms with an appropriate version of `clang` this option enables the use 268 of the sanitizers documented [here][clang-sanitizers]. 269 This should only be used with a debug build. 270* `SPIRV_WARN_EVERYTHING={ON|OFF}`, default `OFF` - On UNIX platforms enable 271 more strict warnings. The code might not compile with this option enabled. 272 For Clang, enables `-Weverything`. For GCC, enables `-Wpedantic`. 273 See [`CMakeLists.txt`](CMakeLists.txt) for details. 274* `SPIRV_WERROR={ON|OFF}`, default `ON` - Forces a compilation error on any 275 warnings encountered by enabling the compiler-specific compiler front-end 276 option. No compiler front-end options are enabled when this option is OFF. 277 278Additionally, you can pass additional C preprocessor definitions to SPIRV-Tools 279via setting `SPIRV_TOOLS_EXTRA_DEFINITIONS`. For example, by setting it to 280`/D_ITERATOR_DEBUG_LEVEL=0` on Windows, you can disable checked iterators and 281iterator debugging. 282 283### Android 284 285SPIR-V Tools supports building static libraries `libSPIRV-Tools.a` and 286`libSPIRV-Tools-opt.a` for Android: 287 288``` 289cd <spirv-dir> 290 291export ANDROID_NDK=/path/to/your/ndk 292 293mkdir build && cd build 294mkdir libs 295mkdir app 296 297$ANDROID_NDK/ndk-build -C ../android_test \ 298 NDK_PROJECT_PATH=. \ 299 NDK_LIBS_OUT=`pwd`/libs \ 300 NDK_APP_OUT=`pwd`/app 301``` 302 303## Library 304 305### Usage 306 307The internals of the library use C++11 features, and are exposed via both a C 308and C++ API. 309 310In order to use the library from an application, the include path should point 311to `<spirv-dir>/include`, which will enable the application to include the 312header `<spirv-dir>/include/spirv-tools/libspirv.h{|pp}` then linking against 313the static library in `<spirv-build-dir>/source/libSPIRV-Tools.a` or 314`<spirv-build-dir>/source/SPIRV-Tools.lib`. 315For optimization, the header file is 316`<spirv-dir>/include/spirv-tools/optimizer.hpp`, and the static library is 317`<spirv-build-dir>/source/libSPIRV-Tools-opt.a` or 318`<spirv-build-dir>/source/SPIRV-Tools-opt.lib`. 319 320* `SPIRV-Tools` CMake target: Creates the static library: 321 * `<spirv-build-dir>/source/libSPIRV-Tools.a` on Linux and OS X. 322 * `<spirv-build-dir>/source/libSPIRV-Tools.lib` on Windows. 323* `SPIRV-Tools-opt` CMake target: Creates the static library: 324 * `<spirv-build-dir>/source/libSPIRV-Tools-opt.a` on Linux and OS X. 325 * `<spirv-build-dir>/source/libSPIRV-Tools-opt.lib` on Windows. 326 327#### Entry points 328 329The interfaces are still under development, and are expected to change. 330 331There are five main entry points into the library in the C interface: 332 333* `spvTextToBinary`: An assembler, translating text to a binary SPIR-V module. 334* `spvBinaryToText`: A disassembler, translating a binary SPIR-V module to 335 text. 336* `spvBinaryParse`: The entry point to a binary parser API. It issues callbacks 337 for the header and each parsed instruction. The disassembler is implemented 338 as a client of `spvBinaryParse`. 339* `spvValidate` implements the validator functionality. *Incomplete* 340* `spvValidateBinary` implements the validator functionality. *Incomplete* 341 342The C++ interface is comprised of three classes, `SpirvTools`, `Optimizer` and 343`Linker`, all in the `spvtools` namespace. 344* `SpirvTools` provides `Assemble`, `Disassemble`, and `Validate` methods. 345* `Optimizer` provides methods for registering and running optimization passes. 346* `Linker` provides methods for combining together multiple binaries. 347 348## Command line tools 349 350Command line tools, which wrap the above library functions, are provided to 351assemble or disassemble shader files. It's a convention to name SPIR-V 352assembly and binary files with suffix `.spvasm` and `.spv`, respectively. 353 354### Assembler tool 355 356The assembler reads the assembly language text, and emits the binary form. 357 358The standalone assembler is the exectuable called `spirv-as`, and is located in 359`<spirv-build-dir>/tools/spirv-as`. The functionality of the assembler is implemented 360by the `spvTextToBinary` library function. 361 362* `spirv-as` - the standalone assembler 363 * `<spirv-dir>/tools/as` 364 365Use option `-h` to print help. 366 367### Disassembler tool 368 369The disassembler reads the binary form, and emits assembly language text. 370 371The standalone disassembler is the executable called `spirv-dis`, and is located in 372`<spirv-build-dir>/tools/spirv-dis`. The functionality of the disassembler is implemented 373by the `spvBinaryToText` library function. 374 375* `spirv-dis` - the standalone disassembler 376 * `<spirv-dir>/tools/dis` 377 378Use option `-h` to print help. 379 380The output includes syntax colouring when printing to the standard output stream, 381on Linux, Windows, and OS X. 382 383### Linker tool 384 385The linker combines multiple SPIR-V binary modules together, resulting in a single 386binary module as output. 387 388This is a work in progress. 389The linker does not support OpenCL program linking options related to math 390flags. (See section 5.6.5.2 in OpenCL 1.2) 391 392* `spirv-link` - the standalone linker 393 * `<spirv-dir>/tools/link` 394 395### Optimizer tool 396 397The optimizer processes a SPIR-V binary module, applying transformations 398in the specified order. 399 400This is a work in progress, with initially only few available transformations. 401 402* `spirv-opt` - the standalone optimizer 403 * `<spirv-dir>/tools/opt` 404 405### Validator tool 406 407*Warning:* This functionality is under development, and is incomplete. 408 409The standalone validator is the executable called `spirv-val`, and is located in 410`<spirv-build-dir>/tools/spirv-val`. The functionality of the validator is implemented 411by the `spvValidate` library function. 412 413The validator operates on the binary form. 414 415* `spirv-val` - the standalone validator 416 * `<spirv-dir>/tools/val` 417 418### Control flow dumper tool 419 420The control flow dumper prints the control flow graph for a SPIR-V module as a 421[GraphViz](http://www.graphviz.org/) graph. 422 423This is experimental. 424 425* `spirv-cfg` - the control flow graph dumper 426 * `<spirv-dir>/tools/cfg` 427 428### Utility filters 429 430* `spirv-lesspipe.sh` - Automatically disassembles `.spv` binary files for the 431 `less` program, on compatible systems. For example, set the `LESSOPEN` 432 environment variable as follows, assuming both `spirv-lesspipe.sh` and 433 `spirv-dis` are on your executable search path: 434 ``` 435 export LESSOPEN='| spirv-lesspipe.sh "%s"' 436 ``` 437 Then you page through a disassembled module as follows: 438 ``` 439 less foo.spv 440 ``` 441 * The `spirv-lesspipe.sh` script will pass through any extra arguments to 442 `spirv-dis`. So, for example, you can turn off colours and friendly ID 443 naming as follows: 444 ``` 445 export LESSOPEN='| spirv-lesspipe.sh "%s" --no-color --raw-id' 446 ``` 447 448* [vim-spirv](https://github.com/kbenzie/vim-spirv) - A vim plugin which 449 supports automatic disassembly of `.spv` files using the `:edit` command and 450 assembly using the `:write` command. The plugin also provides additional 451 features which include; syntax highlighting; highlighting of all ID's matching 452 the ID under the cursor; and highlighting errors where the `Instruction` 453 operand of `OpExtInst` is used without an appropriate `OpExtInstImport`. 454 455* `50spirv-tools.el` - Automatically disassembles '.spv' binary files when 456 loaded into the emacs text editor, and re-assembles them when saved, 457 provided any modifications to the file are valid. This functionality 458 must be explicitly requested by defining the symbol 459 SPIRV_TOOLS_INSTALL_EMACS_HELPERS as follows: 460 ``` 461 cmake -DSPIRV_TOOLS_INSTALL_EMACS_HELPERS=true ... 462 ``` 463 464 In addition, this helper is only installed if the directory /etc/emacs/site-start.d 465 exists, which is typically true if emacs is installed on the system. 466 467 Note that symbol IDs are not currently preserved through a load/edit/save operation. 468 This may change if the ability is added to spirv-as. 469 470 471### Tests 472 473Tests are only built when googletest is found. Use `ctest` to run all the 474tests. 475 476## Future Work 477<a name="future"></a> 478 479_See the [projects pages](https://github.com/KhronosGroup/SPIRV-Tools/projects) 480for more information._ 481 482### Assembler and disassembler 483 484* The disassembler could emit helpful annotations in comments. For example: 485 * Use variable name information from debug instructions to annotate 486 key operations on variables. 487 * Show control flow information by annotating `OpLabel` instructions with 488 that basic block's predecessors. 489* Error messages could be improved. 490 491### Validator 492 493This is a work in progress. 494 495### Linker 496 497* The linker could accept math transformations such as allowing MADs, or other 498 math flags passed at linking-time in OpenCL. 499* Linkage attributes can not be applied through a group. 500* Check decorations of linked functions attributes. 501* Remove dead instructions, such as OpName targeting imported symbols. 502 503## Licence 504<a name="license"></a> 505Full license terms are in [LICENSE](LICENSE) 506``` 507Copyright (c) 2015-2016 The Khronos Group Inc. 508 509Licensed under the Apache License, Version 2.0 (the "License"); 510you may not use this file except in compliance with the License. 511You may obtain a copy of the License at 512 513 http://www.apache.org/licenses/LICENSE-2.0 514 515Unless required by applicable law or agreed to in writing, software 516distributed under the License is distributed on an "AS IS" BASIS, 517WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 518See the License for the specific language governing permissions and 519limitations under the License. 520``` 521 522[spirv-tools-cla]: https://cla-assistant.io/KhronosGroup/SPIRV-Tools 523[spirv-tools-projects]: https://github.com/KhronosGroup/SPIRV-Tools/projects 524[spirv-tools-mailing-list]: https://www.khronos.org/spir/spirv-tools-mailing-list 525[spirv-registry]: https://www.khronos.org/registry/spir-v/ 526[spirv-headers]: https://github.com/KhronosGroup/SPIRV-Headers 527[googletest]: https://github.com/google/googletest 528[googletest-pull-612]: https://github.com/google/googletest/pull/612 529[googletest-issue-610]: https://github.com/google/googletest/issues/610 530[effcee]: https://github.com/google/effcee 531[re2]: https://github.com/google/re2 532[CMake]: https://cmake.org/ 533[cpp-style-guide]: https://google.github.io/styleguide/cppguide.html 534[clang-sanitizers]: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation 535[master-tot-release]: https://github.com/KhronosGroup/SPIRV-Tools/releases/tag/master-tot 536