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