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
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