1 # SPIR-V Tools 2 3 [](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"/> 5 <img alt="MacOS" src="kokoro/img/macos.png" width="20px" height="20px" hspace="2px"/> 6 <img alt="Windows" src="kokoro/img/windows.png" width="20px" height="20px" hspace="2px"/> 7 8 ## Overview 9 10 The SPIR-V Tools project provides an API and commands for processing SPIR-V 11 modules. 12 13 The project includes an assembler, binary module parser, disassembler, 14 validator, and optimizer for SPIR-V. Except for the optimizer, all are based 15 on a common static library. The library contains all of the implementation 16 details, and is used in the standalone tools whilst also enabling integration 17 into other code bases directly. The optimizer implementation resides in its 18 own library, which depends on the core library. 19 20 The interfaces have stabilized: 21 We don't anticipate making a breaking change for existing features. 22 23 SPIR-V is defined by the Khronos Group Inc. 24 See the [SPIR-V Registry][spirv-registry] for the SPIR-V specification, 25 headers, and XML registry. 26 27 ## Versioning SPIRV-Tools 28 29 See [`CHANGES`](CHANGES) for a high level summary of recent changes, by version. 30 31 SPIRV-Tools project version numbers are of the form `v`*year*`.`*index* and with 32 an optional `-dev` suffix to indicate work in progress. For exampe, the 33 following 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 41 Use the `--version` option on each command line tool to see the software 42 version. 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 58 See [`syntax.md`](syntax.md) for the assembly language syntax. 59 60 ### Validator 61 62 The validator checks validation rules described by the SPIR-V specification. 63 64 Khronos recommends that tools that create or transform SPIR-V modules use the 65 validator to ensure their outputs are valid, and that tools that consume SPIR-V 66 modules optionally use the validator to protect themselves from bad inputs. 67 This is especially encouraged for debug and development scenarios. 68 69 The validator has one-sided error: it will only return an error when it has 70 implemented a rule check and the module violates that rule. 71 72 The validator is incomplete. 73 See the [CHANGES](CHANGES) file for reports on completed work, and 74 the [Validator 75 sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/1) for planned 76 and in-progress work. 77 78 *Note*: The validator checks some Universal Limits, from section 2.17 of the SPIR-V spec. 79 The validator will fail on a module that exceeds those minimum upper bound limits. 80 It is [future work](https://github.com/KhronosGroup/SPIRV-Tools/projects/1#card-1052403) 81 to parameterize the validator to allow larger 82 limits accepted by a more than minimally capable SPIR-V consumer. 83 84 85 ### Optimizer 86 87 *Note:* The optimizer is still under development. 88 89 Currently 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 112 For the latest list with detailed documentation, please refer to 113 [`include/spirv-tools/optimizer.hpp`](include/spirv-tools/optimizer.hpp). 114 115 For 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 122 Current 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 127 See the [CHANGES](CHANGES) file for reports on completed work, and the [General 128 sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/2) for 129 planned 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 140 The SPIR-V Tools project is maintained by members of the The Khronos Group Inc., 141 and is hosted at https://github.com/KhronosGroup/SPIRV-Tools. 142 143 Consider joining the `public_spirv_tools_dev (a] khronos.org` mailing list, via 144 [https://www.khronos.org/spir/spirv-tools-mailing-list/](https://www.khronos.org/spir/spirv-tools-mailing-list/). 145 The mailing list is used to discuss development plans for the SPIRV-Tools as an open source project. 146 Once discussion is resolved, 147 specific 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 153 See [`projects.md`](projects.md) to see how we use the 154 [GitHub Project 155 feature](https://help.github.com/articles/tracking-the-progress-of-your-work-with-projects/) 156 to organize planned and in-progress work. 157 158 Contributions 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 172 We 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 192 Example 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 202 The project contains a number of tests, used to drive development 203 and ensure correctness. The tests are written using the 204 [googletest][googletest] framework. The `googletest` 205 source is not provided with this project. There are two ways to enable 206 tests: 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]. 215 The fix is included on the googletest master branch any time after 2015-11-10. 216 In particular, googletest must be newer than version 1.7.0. 217 218 ### Dependency on Effcee 219 220 Some tests depend on the [Effcee][effcee] library for stateful matching. 221 Effcee 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 231 Instead of building manually, you can also download the binaries for your 232 platform directly from the [master-tot release][master-tot-release] on GitHub. 233 Those binaries are automatically uploaded by the buildbots after successful 234 testing and they always reflect the current top of the tree of the master 235 branch. 236 237 The project uses [CMake][cmake] to generate platform-specific build 238 configurations. Assume that `<spirv-dir>` is the root directory of the checked 239 out code: 240 241 ```sh 242 cd <spirv-dir> 243 git clone https://github.com/KhronosGroup/SPIRV-Headers.git external/spirv-headers 244 git clone https://github.com/google/effcee.git external/effcee 245 git clone https://github.com/google/re2.git external/re2 246 git clone https://github.com/google/googletest.git external/googletest # optional 247 248 mkdir build && cd build 249 cmake [-G <platform-generator>] <spirv-dir> 250 ``` 251 252 Once the build files have been generated, build using your preferred 253 development environment. 254 255 ### CMake options 256 257 The 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 278 Additionally, you can pass additional C preprocessor definitions to SPIRV-Tools 279 via 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 281 iterator debugging. 282 283 ### Android 284 285 SPIR-V Tools supports building static libraries `libSPIRV-Tools.a` and 286 `libSPIRV-Tools-opt.a` for Android: 287 288 ``` 289 cd <spirv-dir> 290 291 export ANDROID_NDK=/path/to/your/ndk 292 293 mkdir build && cd build 294 mkdir libs 295 mkdir 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 307 The internals of the library use C++11 features, and are exposed via both a C 308 and C++ API. 309 310 In order to use the library from an application, the include path should point 311 to `<spirv-dir>/include`, which will enable the application to include the 312 header `<spirv-dir>/include/spirv-tools/libspirv.h{|pp}` then linking against 313 the static library in `<spirv-build-dir>/source/libSPIRV-Tools.a` or 314 `<spirv-build-dir>/source/SPIRV-Tools.lib`. 315 For 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 329 The interfaces are still under development, and are expected to change. 330 331 There 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 342 The 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 350 Command line tools, which wrap the above library functions, are provided to 351 assemble or disassemble shader files. It's a convention to name SPIR-V 352 assembly and binary files with suffix `.spvasm` and `.spv`, respectively. 353 354 ### Assembler tool 355 356 The assembler reads the assembly language text, and emits the binary form. 357 358 The 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 360 by the `spvTextToBinary` library function. 361 362 * `spirv-as` - the standalone assembler 363 * `<spirv-dir>/tools/as` 364 365 Use option `-h` to print help. 366 367 ### Disassembler tool 368 369 The disassembler reads the binary form, and emits assembly language text. 370 371 The 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 373 by the `spvBinaryToText` library function. 374 375 * `spirv-dis` - the standalone disassembler 376 * `<spirv-dir>/tools/dis` 377 378 Use option `-h` to print help. 379 380 The output includes syntax colouring when printing to the standard output stream, 381 on Linux, Windows, and OS X. 382 383 ### Linker tool 384 385 The linker combines multiple SPIR-V binary modules together, resulting in a single 386 binary module as output. 387 388 This is a work in progress. 389 The linker does not support OpenCL program linking options related to math 390 flags. (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 397 The optimizer processes a SPIR-V binary module, applying transformations 398 in the specified order. 399 400 This 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 409 The 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 411 by the `spvValidate` library function. 412 413 The 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 420 The control flow dumper prints the control flow graph for a SPIR-V module as a 421 [GraphViz](http://www.graphviz.org/) graph. 422 423 This 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 473 Tests are only built when googletest is found. Use `ctest` to run all the 474 tests. 475 476 ## Future Work 477 <a name="future"></a> 478 479 _See the [projects pages](https://github.com/KhronosGroup/SPIRV-Tools/projects) 480 for 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 493 This 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> 505 Full license terms are in [LICENSE](LICENSE) 506 ``` 507 Copyright (c) 2015-2016 The Khronos Group Inc. 508 509 Licensed under the Apache License, Version 2.0 (the "License"); 510 you may not use this file except in compliance with the License. 511 You may obtain a copy of the License at 512 513 http://www.apache.org/licenses/LICENSE-2.0 514 515 Unless required by applicable law or agreed to in writing, software 516 distributed under the License is distributed on an "AS IS" BASIS, 517 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 518 See the License for the specific language governing permissions and 519 limitations 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