Updated spirv-tools.

This commit is contained in:
Бранимир Караџић 2021-01-27 15:15:47 -08:00
parent e14a070c29
commit 59858de278
33 changed files with 683 additions and 5043 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,708 +0,0 @@
# SPIR-V Tools
## Overview
The SPIR-V Tools project provides an API and commands for processing SPIR-V
modules.
The project includes an assembler, binary module parser, disassembler,
validator, and optimizer for SPIR-V. Except for the optimizer, all are based
on a common static library. The library contains all of the implementation
details, and is used in the standalone tools whilst also enabling integration
into other code bases directly. The optimizer implementation resides in its
own library, which depends on the core library.
The interfaces have stabilized:
We don't anticipate making a breaking change for existing features.
SPIR-V is defined by the Khronos Group Inc.
See the [SPIR-V Registry][spirv-registry] for the SPIR-V specification,
headers, and XML registry.
## Downloads
[![Build status](https://ci.appveyor.com/api/projects/status/gpue87cesrx3pi0d/branch/master?svg=true)](https://ci.appveyor.com/project/Khronoswebmaster/spirv-tools/branch/master)
<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_clang_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_release.html)
<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_clang_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_release.html)
<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)](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2017_release.html)
[More downloads](docs/downloads.md)
## Versioning SPIRV-Tools
See [`CHANGES`](CHANGES) for a high level summary of recent changes, by version.
SPIRV-Tools project version numbers are of the form `v`*year*`.`*index* and with
an optional `-dev` suffix to indicate work in progress. For example, the
following versions are ordered from oldest to newest:
* `v2016.0`
* `v2016.1-dev`
* `v2016.1`
* `v2016.2-dev`
* `v2016.2`
Use the `--version` option on each command line tool to see the software
version. An API call reports the software version as a C-style string.
## Supported features
### Assembler, binary parser, and disassembler
* Support for SPIR-V 1.0, through 1.5
* Based on SPIR-V syntax described by JSON grammar files in the
[SPIRV-Headers](https://github.com/KhronosGroup/SPIRV-Headers) repository.
* Usually, support for a new version of SPIR-V is ready within days after
publication.
* Support for extended instruction sets:
* GLSL std450 version 1.0 Rev 3
* OpenCL version 1.0 Rev 2
* Assembler only does basic syntax checking. No cross validation of
IDs or types is performed, except to check literal arguments to
`OpConstant`, `OpSpecConstant`, and `OpSwitch`.
See [`docs/syntax.md`](docs/syntax.md) for the assembly language syntax.
### Validator
The validator checks validation rules described by the SPIR-V specification.
Khronos recommends that tools that create or transform SPIR-V modules use the
validator to ensure their outputs are valid, and that tools that consume SPIR-V
modules optionally use the validator to protect themselves from bad inputs.
This is especially encouraged for debug and development scenarios.
The validator has one-sided error: it will only return an error when it has
implemented a rule check and the module violates that rule.
The validator is incomplete.
See the [CHANGES](CHANGES) file for reports on completed work, and
the [Validator
sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/1) for planned
and in-progress work.
*Note*: The validator checks some Universal Limits, from section 2.17 of the SPIR-V spec.
The validator will fail on a module that exceeds those minimum upper bound limits.
It is [future work](https://github.com/KhronosGroup/SPIRV-Tools/projects/1#card-1052403)
to parameterize the validator to allow larger
limits accepted by a more than minimally capable SPIR-V consumer.
### Optimizer
The optimizer is a collection of code transforms, or "passes".
Transforms are written for a diverse set of reasons:
* To restructure, simplify, or normalize the code for further processing.
* To eliminate undesirable code.
* To improve code quality in some metric such as size or performance.
**Note**: These transforms are not guaranteed to actually improve any
given metric. Users should always measure results for their own situation.
As of this writing, there are 67 transforms including examples such as:
* Simplification
* Strip debug info
* Strip reflection info
* Specialization Constants
* Set spec constant default value
* Freeze spec constant to default value
* Fold `OpSpecConstantOp` and `OpSpecConstantComposite`
* Unify constants
* Eliminate dead constant
* Code Reduction
* Inline all function calls exhaustively
* Convert local access chains to inserts/extracts
* Eliminate local load/store in single block
* Eliminate local load/store with single store
* Eliminate local load/store with multiple stores
* Eliminate local extract from insert
* Eliminate dead instructions (aggressive)
* Eliminate dead branches
* Merge single successor / single predecessor block pairs
* Eliminate common uniform loads
* Remove duplicates: Capabilities, extended instruction imports, types, and
decorations.
* Normalization
* Compact IDs
* CFG cleanup
* Flatten decorations
* Merge returns
* Convert AMD-specific instructions to KHR instructions
* Code improvement
* Conditional constant propagation
* If-conversion
* Loop fission
* Loop fusion
* Loop-invariant code motion
* Loop unroll
* Other
* Graphics robust access
* Upgrade memory model to VulkanKHR
Additionally, certain sets of transformations have been packaged into
higher-level recipes. These include:
* Optimization for size (`spirv-opt -Os`)
* Optimization for performance (`spirv-opt -O`)
For the latest list with detailed documentation, please refer to
[`include/spirv-tools/optimizer.hpp`](include/spirv-tools/optimizer.hpp).
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/).
### Linker
*Note:* The linker is still under development.
Current features:
* Combine multiple SPIR-V binary modules together.
* Combine into a library (exports are retained) or an executable (no symbols
are exported).
See the [CHANGES](CHANGES) file for reports on completed work, and the [General
sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/2) for
planned and in-progress work.
### Reducer
*Note:* The reducer is still under development.
The reducer simplifies and shrinks a SPIR-V module with respect to a
user-supplied *interestingness function*. For example, given a large
SPIR-V module that cause some SPIR-V compiler to fail with a given
fatal error message, the reducer could be used to look for a smaller
version of the module that causes the compiler to fail with the same
fatal error message.
To suggest an additional capability for the reducer, [file an
issue](https://github.com/KhronosGroup/SPIRV-Tools/issues]) with
"Reducer:" as the start of its title.
### Fuzzer
*Note:* The fuzzer is still under development.
The fuzzer applies semantics-preserving transformations to a SPIR-V binary
module, to produce an equivalent module. The original and transformed modules
should produce essentially identical results when executed on identical inputs:
their results should differ only due to floating-point round-off, if at all.
Significant differences in results can pinpoint bugs in tools that process
SPIR-V binaries, such as miscompilations. This *metamorphic testing* approach
is similar to the method used by the [GraphicsFuzz
project](https://github.com/google/graphicsfuzz) for fuzzing of GLSL shaders.
To suggest an additional capability for the fuzzer, [file an
issue](https://github.com/KhronosGroup/SPIRV-Tools/issues]) with
"Fuzzer:" as the start of its title.
### Extras
* [Utility filters](#utility-filters)
* Build target `spirv-tools-vimsyntax` generates file `spvasm.vim`.
Copy that file into your `$HOME/.vim/syntax` directory to get SPIR-V assembly syntax
highlighting in Vim. This build target is not built by default.
## Contributing
The SPIR-V Tools project is maintained by members of the The Khronos Group Inc.,
and is hosted at https://github.com/KhronosGroup/SPIRV-Tools.
Consider joining the `public_spirv_tools_dev@khronos.org` mailing list, via
[https://www.khronos.org/spir/spirv-tools-mailing-list/](https://www.khronos.org/spir/spirv-tools-mailing-list/).
The mailing list is used to discuss development plans for the SPIRV-Tools as an open source project.
Once discussion is resolved,
specific work is tracked via issues and sometimes in one of the
[projects][spirv-tools-projects].
(To provide feedback on the SPIR-V _specification_, file an issue on the
[SPIRV-Headers][spirv-headers] GitHub repository.)
See [`docs/projects.md`](docs/projects.md) to see how we use the
[GitHub Project
feature](https://help.github.com/articles/tracking-the-progress-of-your-work-with-projects/)
to organize planned and in-progress work.
Contributions via merge request are welcome. Changes should:
* Be provided under the [Apache 2.0](#license).
* You'll be prompted with a one-time "click-through"
[Khronos Open Source Contributor License Agreement][spirv-tools-cla]
(CLA) dialog as part of submitting your pull request or
other contribution to GitHub.
* Include tests to cover updated functionality.
* C++ code should follow the [Google C++ Style Guide][cpp-style-guide].
* Code should be formatted with `clang-format`.
[kokoro/check-format/build.sh](kokoro/check-format/build.sh)
shows how to download it. Note that we currently use
`clang-format version 5.0.0` for SPIRV-Tools. Settings are defined by
the included [.clang-format](.clang-format) file.
We intend to maintain a linear history on the GitHub `master` branch.
### Source code organization
* `example`: demo code of using SPIRV-Tools APIs
* `external/googletest`: Intended location for the
[googletest][googletest] sources, not provided
* `external/effcee`: Location of [Effcee][effcee] sources, if the `effcee` library
is not already configured by an enclosing project.
* `external/re2`: Location of [RE2][re2] sources, if the `re2` library is not already
configured by an enclosing project.
(The Effcee project already requires RE2.)
* `include/`: API clients should add this directory to the include search path
* `external/spirv-headers`: Intended location for
[SPIR-V headers][spirv-headers], not provided
* `include/spirv-tools/libspirv.h`: C API public interface
* `source/`: API implementation
* `test/`: Tests, using the [googletest][googletest] framework
* `tools/`: Command line executables
Example of getting sources, assuming SPIRV-Tools is configured as a standalone project:
git clone https://github.com/KhronosGroup/SPIRV-Tools.git spirv-tools
git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-tools/external/spirv-headers
git clone https://github.com/google/googletest.git spirv-tools/external/googletest
git clone https://github.com/google/effcee.git spirv-tools/external/effcee
git clone https://github.com/google/re2.git spirv-tools/external/re2
### Tests
The project contains a number of tests, used to drive development
and ensure correctness. The tests are written using the
[googletest][googletest] framework. The `googletest`
source is not provided with this project. There are two ways to enable
tests:
* If SPIR-V Tools is configured as part of an enclosing project, then the
enclosing project should configure `googletest` before configuring SPIR-V Tools.
* If SPIR-V Tools is configured as a standalone project, then download the
`googletest` source into the `<spirv-dir>/external/googletest` directory before
configuring and building the project.
*Note*: You must use a version of googletest that includes
[a fix][googletest-pull-612] for [googletest issue 610][googletest-issue-610].
The fix is included on the googletest master branch any time after 2015-11-10.
In particular, googletest must be newer than version 1.7.0.
### Dependency on Effcee
Some tests depend on the [Effcee][effcee] library for stateful matching.
Effcee itself depends on [RE2][re2].
* If SPIRV-Tools is configured as part of a larger project that already uses
Effcee, then that project should include Effcee before SPIRV-Tools.
* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee`
and RE2 sources to appear in `external/re2`.
## Build
Instead of building manually, you can also download the binaries for your
platform directly from the [master-tot release][master-tot-release] on GitHub.
Those binaries are automatically uploaded by the buildbots after successful
testing and they always reflect the current top of the tree of the master
branch.
In order to build the code, you first need to sync the external repositories
that it depends on. Assume that `<spirv-dir>` is the root directory of the
checked out code:
```sh
cd <spirv-dir>
git clone https://github.com/KhronosGroup/SPIRV-Headers.git external/spirv-headers
git clone https://github.com/google/effcee.git external/effcee
git clone https://github.com/google/re2.git external/re2
git clone https://github.com/google/googletest.git external/googletest # optional
```
*Note*:
The script `utils/git-sync-deps` can be used to checkout and/or update the
contents of the repos under `external/` instead of manually maintaining them.
### Build using CMake
You can build the project using [CMake][cmake]:
```sh
cd <spirv-dir>
mkdir build && cd build
cmake [-G <platform-generator>] <spirv-dir>
```
Once the build files have been generated, build using the appropriate build
command (e.g. `ninja`, `make`, `msbuild`, etc.; this depends on the platform
generator used above), or use your IDE, or use CMake to run the appropriate build
command for you:
```sh
cmake --build . [--config Debug] # runs `make` or `ninja` or `msbuild` etc.
```
#### Note about the fuzzer
The SPIR-V fuzzer, `spirv-fuzz`, can only be built via CMake, and is disabled by
default. To build it, clone protobuf and use the `SPIRV_BUILD_FUZZER` CMake
option, like so:
```sh
# In <spirv-dir> (the SPIRV-Tools repo root):
git clone --depth=1 --branch v3.13.0 https://github.com/protocolbuffers/protobuf external/protobuf
# In your build directory:
cmake [-G <platform-generator>] <spirv-dir> -DSPIRV_BUILD_FUZZER=ON
cmake --build . --config Debug
```
You can also add `-DSPIRV_ENABLE_LONG_FUZZER_TESTS=ON` to build additional
fuzzer tests.
### Build using Bazel
You can also use [Bazel](https://bazel.build/) to build the project.
```sh
cd <spirv-dir>
bazel build :all
```
### Tools you'll need
For building and testing SPIRV-Tools, the following tools should be
installed regardless of your OS:
- [CMake](http://www.cmake.org/): if using CMake for generating compilation
targets, you need to install CMake Version 2.8.12 or later.
- [Python 3](http://www.python.org/): for utility scripts and running the test
suite.
- [Bazel](https://bazel.build/) (optional): if building the source with Bazel,
you need to install Bazel Version 0.29.1 on your machine. Other versions may
also work, but are not verified.
SPIRV-Tools is regularly tested with the following compilers:
On Linux
- GCC version 4.8.5
- Clang version 3.8
On MacOS
- AppleClang 10.0
On Windows
- Visual Studio 2015
- Visual Studio 2017
Other compilers or later versions may work, but they are not tested.
### CMake options
The following CMake options are supported:
* `SPIRV_BUILD_FUZZER={ON|OFF}`, default `OFF` - Build the spirv-fuzz tool.
* `SPIRV_COLOR_TERMINAL={ON|OFF}`, default `ON` - Enables color console output.
* `SPIRV_SKIP_TESTS={ON|OFF}`, default `OFF`- Build only the library and
the command line tools. This will prevent the tests from being built.
* `SPIRV_SKIP_EXECUTABLES={ON|OFF}`, default `OFF`- Build only the library, not
the command line tools and tests.
* `SPIRV_USE_SANITIZER=<sanitizer>`, default is no sanitizing - On UNIX
platforms with an appropriate version of `clang` this option enables the use
of the sanitizers documented [here][clang-sanitizers].
This should only be used with a debug build.
* `SPIRV_WARN_EVERYTHING={ON|OFF}`, default `OFF` - On UNIX platforms enable
more strict warnings. The code might not compile with this option enabled.
For Clang, enables `-Weverything`. For GCC, enables `-Wpedantic`.
See [`CMakeLists.txt`](CMakeLists.txt) for details.
* `SPIRV_WERROR={ON|OFF}`, default `ON` - Forces a compilation error on any
warnings encountered by enabling the compiler-specific compiler front-end
option. No compiler front-end options are enabled when this option is OFF.
Additionally, you can pass additional C preprocessor definitions to SPIRV-Tools
via setting `SPIRV_TOOLS_EXTRA_DEFINITIONS`. For example, by setting it to
`/D_ITERATOR_DEBUG_LEVEL=0` on Windows, you can disable checked iterators and
iterator debugging.
### Android
SPIR-V Tools supports building static libraries `libSPIRV-Tools.a` and
`libSPIRV-Tools-opt.a` for Android:
```
cd <spirv-dir>
export ANDROID_NDK=/path/to/your/ndk
mkdir build && cd build
mkdir libs
mkdir app
$ANDROID_NDK/ndk-build -C ../android_test \
NDK_PROJECT_PATH=. \
NDK_LIBS_OUT=`pwd`/libs \
NDK_APP_OUT=`pwd`/app
```
### Updating DEPS
Occasionally the entries in DEPS will need to be updated. This is done on demand
when there is a request to do this, often due to downstream breakages. There is
a script `utils/roll_deps.sh` provided, which will generate a patch with the
updated DEPS values. This will still need to be tested in your checkout to
confirm that there are no integration issues that need to be resolved.
## Library
### Usage
The internals of the library use C++11 features, and are exposed via both a C
and C++ API.
In order to use the library from an application, the include path should point
to `<spirv-dir>/include`, which will enable the application to include the
header `<spirv-dir>/include/spirv-tools/libspirv.h{|pp}` then linking against
the static library in `<spirv-build-dir>/source/libSPIRV-Tools.a` or
`<spirv-build-dir>/source/SPIRV-Tools.lib`.
For optimization, the header file is
`<spirv-dir>/include/spirv-tools/optimizer.hpp`, and the static library is
`<spirv-build-dir>/source/libSPIRV-Tools-opt.a` or
`<spirv-build-dir>/source/SPIRV-Tools-opt.lib`.
* `SPIRV-Tools` CMake target: Creates the static library:
* `<spirv-build-dir>/source/libSPIRV-Tools.a` on Linux and OS X.
* `<spirv-build-dir>/source/libSPIRV-Tools.lib` on Windows.
* `SPIRV-Tools-opt` CMake target: Creates the static library:
* `<spirv-build-dir>/source/libSPIRV-Tools-opt.a` on Linux and OS X.
* `<spirv-build-dir>/source/libSPIRV-Tools-opt.lib` on Windows.
#### Entry points
The interfaces are still under development, and are expected to change.
There are five main entry points into the library in the C interface:
* `spvTextToBinary`: An assembler, translating text to a binary SPIR-V module.
* `spvBinaryToText`: A disassembler, translating a binary SPIR-V module to
text.
* `spvBinaryParse`: The entry point to a binary parser API. It issues callbacks
for the header and each parsed instruction. The disassembler is implemented
as a client of `spvBinaryParse`.
* `spvValidate` implements the validator functionality. *Incomplete*
* `spvValidateBinary` implements the validator functionality. *Incomplete*
The C++ interface is comprised of three classes, `SpirvTools`, `Optimizer` and
`Linker`, all in the `spvtools` namespace.
* `SpirvTools` provides `Assemble`, `Disassemble`, and `Validate` methods.
* `Optimizer` provides methods for registering and running optimization passes.
* `Linker` provides methods for combining together multiple binaries.
## Command line tools
Command line tools, which wrap the above library functions, are provided to
assemble or disassemble shader files. It's a convention to name SPIR-V
assembly and binary files with suffix `.spvasm` and `.spv`, respectively.
### Assembler tool
The assembler reads the assembly language text, and emits the binary form.
The standalone assembler is the executable called `spirv-as`, and is located in
`<spirv-build-dir>/tools/spirv-as`. The functionality of the assembler is implemented
by the `spvTextToBinary` library function.
* `spirv-as` - the standalone assembler
* `<spirv-dir>/tools/as`
Use option `-h` to print help.
### Disassembler tool
The disassembler reads the binary form, and emits assembly language text.
The standalone disassembler is the executable called `spirv-dis`, and is located in
`<spirv-build-dir>/tools/spirv-dis`. The functionality of the disassembler is implemented
by the `spvBinaryToText` library function.
* `spirv-dis` - the standalone disassembler
* `<spirv-dir>/tools/dis`
Use option `-h` to print help.
The output includes syntax colouring when printing to the standard output stream,
on Linux, Windows, and OS X.
### Linker tool
The linker combines multiple SPIR-V binary modules together, resulting in a single
binary module as output.
This is a work in progress.
The linker does not support OpenCL program linking options related to math
flags. (See section 5.6.5.2 in OpenCL 1.2)
* `spirv-link` - the standalone linker
* `<spirv-dir>/tools/link`
### Optimizer tool
The optimizer processes a SPIR-V binary module, applying transformations
in the specified order.
This is a work in progress, with initially only few available transformations.
* `spirv-opt` - the standalone optimizer
* `<spirv-dir>/tools/opt`
### Validator tool
*Warning:* This functionality is under development, and is incomplete.
The standalone validator is the executable called `spirv-val`, and is located in
`<spirv-build-dir>/tools/spirv-val`. The functionality of the validator is implemented
by the `spvValidate` library function.
The validator operates on the binary form.
* `spirv-val` - the standalone validator
* `<spirv-dir>/tools/val`
### Reducer tool
The reducer shrinks a SPIR-V binary module, guided by a user-supplied
*interestingness test*.
This is a work in progress, with initially only shrinks a module in a few ways.
* `spirv-reduce` - the standalone reducer
* `<spirv-dir>/tools/reduce`
Run `spirv-reduce --help` to see how to specify interestingness.
### Fuzzer tool
The fuzzer transforms a SPIR-V binary module into a semantically-equivalent
SPIR-V binary module by applying transformations in a randomized fashion.
This is a work in progress, with initially only a few semantics-preserving
transformations.
* `spirv-fuzz` - the standalone fuzzer
* `<spirv-dir>/tools/fuzz`
Run `spirv-fuzz --help` for a detailed list of options.
### Control flow dumper tool
The control flow dumper prints the control flow graph for a SPIR-V module as a
[GraphViz](http://www.graphviz.org/) graph.
This is experimental.
* `spirv-cfg` - the control flow graph dumper
* `<spirv-dir>/tools/cfg`
### Utility filters
* `spirv-lesspipe.sh` - Automatically disassembles `.spv` binary files for the
`less` program, on compatible systems. For example, set the `LESSOPEN`
environment variable as follows, assuming both `spirv-lesspipe.sh` and
`spirv-dis` are on your executable search path:
```
export LESSOPEN='| spirv-lesspipe.sh "%s"'
```
Then you page through a disassembled module as follows:
```
less foo.spv
```
* The `spirv-lesspipe.sh` script will pass through any extra arguments to
`spirv-dis`. So, for example, you can turn off colours and friendly ID
naming as follows:
```
export LESSOPEN='| spirv-lesspipe.sh "%s" --no-color --raw-id'
```
* [vim-spirv](https://github.com/kbenzie/vim-spirv) - A vim plugin which
supports automatic disassembly of `.spv` files using the `:edit` command and
assembly using the `:write` command. The plugin also provides additional
features which include; syntax highlighting; highlighting of all ID's matching
the ID under the cursor; and highlighting errors where the `Instruction`
operand of `OpExtInst` is used without an appropriate `OpExtInstImport`.
* `50spirv-tools.el` - Automatically disassembles '.spv' binary files when
loaded into the emacs text editor, and re-assembles them when saved,
provided any modifications to the file are valid. This functionality
must be explicitly requested by defining the symbol
SPIRV_TOOLS_INSTALL_EMACS_HELPERS as follows:
```
cmake -DSPIRV_TOOLS_INSTALL_EMACS_HELPERS=true ...
```
In addition, this helper is only installed if the directory /etc/emacs/site-start.d
exists, which is typically true if emacs is installed on the system.
Note that symbol IDs are not currently preserved through a load/edit/save operation.
This may change if the ability is added to spirv-as.
### Tests
Tests are only built when googletest is found. Use `ctest` to run all the
tests.
## Future Work
<a name="future"></a>
_See the [projects pages](https://github.com/KhronosGroup/SPIRV-Tools/projects)
for more information._
### Assembler and disassembler
* The disassembler could emit helpful annotations in comments. For example:
* Use variable name information from debug instructions to annotate
key operations on variables.
* Show control flow information by annotating `OpLabel` instructions with
that basic block's predecessors.
* Error messages could be improved.
### Validator
This is a work in progress.
### Linker
* The linker could accept math transformations such as allowing MADs, or other
math flags passed at linking-time in OpenCL.
* Linkage attributes can not be applied through a group.
* Check decorations of linked functions attributes.
* Remove dead instructions, such as OpName targeting imported symbols.
## Licence
<a name="license"></a>
Full license terms are in [LICENSE](LICENSE)
```
Copyright (c) 2015-2016 The Khronos Group Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
[spirv-tools-cla]: https://cla-assistant.io/KhronosGroup/SPIRV-Tools
[spirv-tools-projects]: https://github.com/KhronosGroup/SPIRV-Tools/projects
[spirv-tools-mailing-list]: https://www.khronos.org/spir/spirv-tools-mailing-list
[spirv-registry]: https://www.khronos.org/registry/spir-v/
[spirv-headers]: https://github.com/KhronosGroup/SPIRV-Headers
[googletest]: https://github.com/google/googletest
[googletest-pull-612]: https://github.com/google/googletest/pull/612
[googletest-issue-610]: https://github.com/google/googletest/issues/610
[effcee]: https://github.com/google/effcee
[re2]: https://github.com/google/re2
[CMake]: https://cmake.org/
[cpp-style-guide]: https://google.github.io/styleguide/cppguide.html
[clang-sanitizers]: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
[master-tot-release]: https://github.com/KhronosGroup/SPIRV-Tools/releases/tag/master-tot

View File

@ -1 +1 @@
"v2020.7-dev", "SPIRV-Tools v2020.7-dev 630263d1cbcdda5c28b5b80730ad90ce0b3b6e90"
"v2020.7-dev", "SPIRV-Tools v2020.7-dev 93efa0c36bc823ed865bd45418c57390547cef74"

View File

@ -2,6 +2,7 @@ static const SpvCapability pygen_variable_caps_Addresses[] = {SpvCapabilityAddre
static const SpvCapability pygen_variable_caps_AddressesPhysicalStorageBufferAddresses[] = {SpvCapabilityAddresses, SpvCapabilityPhysicalStorageBufferAddresses};
static const SpvCapability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBuffer[] = {SpvCapabilityAddresses, SpvCapabilityVariablePointers, SpvCapabilityVariablePointersStorageBuffer};
static const SpvCapability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses[] = {SpvCapabilityAddresses, SpvCapabilityVariablePointers, SpvCapabilityVariablePointersStorageBuffer, SpvCapabilityPhysicalStorageBufferAddresses};
static const SpvCapability pygen_variable_caps_AsmINTEL[] = {SpvCapabilityAsmINTEL};
static const SpvCapability pygen_variable_caps_AtomicFloat32AddEXTAtomicFloat64AddEXT[] = {SpvCapabilityAtomicFloat32AddEXT, SpvCapabilityAtomicFloat64AddEXT};
static const SpvCapability pygen_variable_caps_BlockingPipesINTEL[] = {SpvCapabilityBlockingPipesINTEL};
static const SpvCapability pygen_variable_caps_CooperativeMatrixNV[] = {SpvCapabilityCooperativeMatrixNV};
@ -29,6 +30,7 @@ static const SpvCapability pygen_variable_caps_IntegerFunctions2INTEL[] = {SpvCa
static const SpvCapability pygen_variable_caps_Kernel[] = {SpvCapabilityKernel};
static const SpvCapability pygen_variable_caps_KernelImageQuery[] = {SpvCapabilityKernel, SpvCapabilityImageQuery};
static const SpvCapability pygen_variable_caps_LiteralSampler[] = {SpvCapabilityLiteralSampler};
static const SpvCapability pygen_variable_caps_LongConstantCompositeINTEL[] = {SpvCapabilityLongConstantCompositeINTEL};
static const SpvCapability pygen_variable_caps_Matrix[] = {SpvCapabilityMatrix};
static const SpvCapability pygen_variable_caps_MeshShadingNV[] = {SpvCapabilityMeshShadingNV};
static const SpvCapability pygen_variable_caps_NamedBarrier[] = {SpvCapabilityNamedBarrier};
@ -53,7 +55,10 @@ static const SpvCapability pygen_variable_caps_SubgroupImageBlockIOINTEL[] = {Sp
static const SpvCapability pygen_variable_caps_SubgroupImageMediaBlockIOINTEL[] = {SpvCapabilitySubgroupImageMediaBlockIOINTEL};
static const SpvCapability pygen_variable_caps_SubgroupShuffleINTEL[] = {SpvCapabilitySubgroupShuffleINTEL};
static const SpvCapability pygen_variable_caps_SubgroupVoteKHR[] = {SpvCapabilitySubgroupVoteKHR};
static const SpvCapability pygen_variable_caps_USMStorageClassesINTEL[] = {SpvCapabilityUSMStorageClassesINTEL};
static const SpvCapability pygen_variable_caps_UnstructuredLoopControlsINTEL[] = {SpvCapabilityUnstructuredLoopControlsINTEL};
static const SpvCapability pygen_variable_caps_VariableLengthArrayINTEL[] = {SpvCapabilityVariableLengthArrayINTEL};
static const SpvCapability pygen_variable_caps_VectorComputeINTEL[] = {SpvCapabilityVectorComputeINTEL};
static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_ballot[] = {spvtools::Extension::kSPV_AMD_shader_ballot};
static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_fragment_mask[] = {spvtools::Extension::kSPV_AMD_shader_fragment_mask};
@ -500,8 +505,11 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"USubSatINTEL", SpvOpUSubSatINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"IMul32x16INTEL", SpvOpIMul32x16INTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"UMul32x16INTEL", SpvOpUMul32x16INTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"FunctionPointerINTEL", SpvOpFunctionPointerINTEL, 1, pygen_variable_caps_FunctionPointersINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_function_pointers, 0xffffffffu, 0xffffffffu},
{"ConstFunctionPointerINTEL", SpvOpConstFunctionPointerINTEL, 1, pygen_variable_caps_FunctionPointersINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_function_pointers, 0xffffffffu, 0xffffffffu},
{"FunctionPointerCallINTEL", SpvOpFunctionPointerCallINTEL, 1, pygen_variable_caps_FunctionPointersINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_function_pointers, 0xffffffffu, 0xffffffffu},
{"AsmTargetINTEL", SpvOpAsmTargetINTEL, 1, pygen_variable_caps_AsmINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"AsmINTEL", SpvOpAsmINTEL, 1, pygen_variable_caps_AsmINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"AsmCallINTEL", SpvOpAsmCallINTEL, 1, pygen_variable_caps_AsmINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"DecorateString", SpvOpDecorateString, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"DecorateStringGOOGLE", SpvOpDecorateStringGOOGLE, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"MemberDecorateString", SpvOpMemberDecorateString, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
@ -624,7 +632,12 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"SubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicGetInterRawSadsINTEL", SpvOpSubgroupAvcSicGetInterRawSadsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"VariableLengthArrayINTEL", SpvOpVariableLengthArrayINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SaveMemoryINTEL", SpvOpSaveMemoryINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"RestoreMemoryINTEL", SpvOpRestoreMemoryINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"LoopControlINTEL", SpvOpLoopControlINTEL, 1, pygen_variable_caps_UnstructuredLoopControlsINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 0, 0, 1, pygen_variable_exts_SPV_INTEL_unstructured_loop_controls, 0xffffffffu, 0xffffffffu},
{"PtrCastToCrossWorkgroupINTEL", SpvOpPtrCastToCrossWorkgroupINTEL, 1, pygen_variable_caps_USMStorageClassesINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"CrossWorkgroupCastToPtrINTEL", SpvOpCrossWorkgroupCastToPtrINTEL, 1, pygen_variable_caps_USMStorageClassesINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ReadPipeBlockingINTEL", SpvOpReadPipeBlockingINTEL, 1, pygen_variable_caps_BlockingPipesINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_blocking_pipes, 0xffffffffu, 0xffffffffu},
{"WritePipeBlockingINTEL", SpvOpWritePipeBlockingINTEL, 1, pygen_variable_caps_BlockingPipesINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_blocking_pipes, 0xffffffffu, 0xffffffffu},
{"FPGARegINTEL", SpvOpFPGARegINTEL, 1, pygen_variable_caps_FPGARegINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_fpga_reg, 0xffffffffu, 0xffffffffu},
@ -645,5 +658,9 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"RayQueryGetWorldRayOriginKHR", SpvOpRayQueryGetWorldRayOriginKHR, 1, pygen_variable_caps_RayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"RayQueryGetIntersectionObjectToWorldKHR", SpvOpRayQueryGetIntersectionObjectToWorldKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"RayQueryGetIntersectionWorldToObjectKHR", SpvOpRayQueryGetIntersectionWorldToObjectKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"AtomicFAddEXT", SpvOpAtomicFAddEXT, 2, pygen_variable_caps_AtomicFloat32AddEXTAtomicFloat64AddEXT, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, 0xffffffffu, 0xffffffffu}
{"AtomicFAddEXT", SpvOpAtomicFAddEXT, 2, pygen_variable_caps_AtomicFloat32AddEXTAtomicFloat64AddEXT, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, 0xffffffffu, 0xffffffffu},
{"TypeBufferSurfaceINTEL", SpvOpTypeBufferSurfaceINTEL, 1, pygen_variable_caps_VectorComputeINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeStructContinuedINTEL", SpvOpTypeStructContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ConstantCompositeContinuedINTEL", SpvOpConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SpecConstantCompositeContinuedINTEL", SpvOpSpecConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}
};

View File

@ -46,20 +46,40 @@ const char* ExtensionToString(Extension extension) {
return "SPV_GOOGLE_hlsl_functionality1";
case Extension::kSPV_GOOGLE_user_type:
return "SPV_GOOGLE_user_type";
case Extension::kSPV_INTEL_arbitrary_precision_integers:
return "SPV_INTEL_arbitrary_precision_integers";
case Extension::kSPV_INTEL_blocking_pipes:
return "SPV_INTEL_blocking_pipes";
case Extension::kSPV_INTEL_device_side_avc_motion_estimation:
return "SPV_INTEL_device_side_avc_motion_estimation";
case Extension::kSPV_INTEL_float_controls2:
return "SPV_INTEL_float_controls2";
case Extension::kSPV_INTEL_fp_fast_math_mode:
return "SPV_INTEL_fp_fast_math_mode";
case Extension::kSPV_INTEL_fpga_buffer_location:
return "SPV_INTEL_fpga_buffer_location";
case Extension::kSPV_INTEL_fpga_cluster_attributes:
return "SPV_INTEL_fpga_cluster_attributes";
case Extension::kSPV_INTEL_fpga_loop_controls:
return "SPV_INTEL_fpga_loop_controls";
case Extension::kSPV_INTEL_fpga_memory_accesses:
return "SPV_INTEL_fpga_memory_accesses";
case Extension::kSPV_INTEL_fpga_memory_attributes:
return "SPV_INTEL_fpga_memory_attributes";
case Extension::kSPV_INTEL_fpga_reg:
return "SPV_INTEL_fpga_reg";
case Extension::kSPV_INTEL_function_pointers:
return "SPV_INTEL_function_pointers";
case Extension::kSPV_INTEL_inline_assembly:
return "SPV_INTEL_inline_assembly";
case Extension::kSPV_INTEL_io_pipes:
return "SPV_INTEL_io_pipes";
case Extension::kSPV_INTEL_kernel_attributes:
return "SPV_INTEL_kernel_attributes";
case Extension::kSPV_INTEL_long_constant_composite:
return "SPV_INTEL_long_constant_composite";
case Extension::kSPV_INTEL_loop_fuse:
return "SPV_INTEL_loop_fuse";
case Extension::kSPV_INTEL_media_block_io:
return "SPV_INTEL_media_block_io";
case Extension::kSPV_INTEL_shader_integer_functions2:
@ -68,6 +88,12 @@ const char* ExtensionToString(Extension extension) {
return "SPV_INTEL_subgroups";
case Extension::kSPV_INTEL_unstructured_loop_controls:
return "SPV_INTEL_unstructured_loop_controls";
case Extension::kSPV_INTEL_usm_storage_classes:
return "SPV_INTEL_usm_storage_classes";
case Extension::kSPV_INTEL_variable_length_array:
return "SPV_INTEL_variable_length_array";
case Extension::kSPV_INTEL_vector_compute:
return "SPV_INTEL_vector_compute";
case Extension::kSPV_KHR_16bit_storage:
return "SPV_KHR_16bit_storage";
case Extension::kSPV_KHR_8bit_storage:
@ -110,6 +136,8 @@ const char* ExtensionToString(Extension extension) {
return "SPV_KHR_variable_pointers";
case Extension::kSPV_KHR_vulkan_memory_model:
return "SPV_KHR_vulkan_memory_model";
case Extension::kSPV_KHR_workgroup_memory_explicit_layout:
return "SPV_KHR_workgroup_memory_explicit_layout";
case Extension::kSPV_NVX_multiview_per_view_attributes:
return "SPV_NVX_multiview_per_view_attributes";
case Extension::kSPV_NV_compute_shader_derivatives:
@ -147,8 +175,8 @@ const char* ExtensionToString(Extension extension) {
bool GetExtensionFromString(const char* str, Extension* extension) {
static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_blocking_pipes", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_kernel_attributes", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_fragment_shading_rate", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" };
static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique };
static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_blocking_pipes", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_fragment_shading_rate", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" };
static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique };
const auto b = std::begin(known_ext_strs);
const auto e = std::end(known_ext_strs);
const auto found = std::equal_range(
@ -308,6 +336,12 @@ const char* CapabilityToString(SpvCapability capability) {
return "SubgroupBallotKHR";
case SpvCapabilityDrawParameters:
return "DrawParameters";
case SpvCapabilityWorkgroupMemoryExplicitLayoutKHR:
return "WorkgroupMemoryExplicitLayoutKHR";
case SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR:
return "WorkgroupMemoryExplicitLayout8BitAccessKHR";
case SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR:
return "WorkgroupMemoryExplicitLayout16BitAccessKHR";
case SpvCapabilitySubgroupVoteKHR:
return "SubgroupVoteKHR";
case SpvCapabilityStorageBuffer16BitAccess:
@ -450,20 +484,38 @@ const char* CapabilityToString(SpvCapability capability) {
return "SubgroupImageBlockIOINTEL";
case SpvCapabilitySubgroupImageMediaBlockIOINTEL:
return "SubgroupImageMediaBlockIOINTEL";
case SpvCapabilityRoundToInfinityINTEL:
return "RoundToInfinityINTEL";
case SpvCapabilityFloatingPointModeINTEL:
return "FloatingPointModeINTEL";
case SpvCapabilityIntegerFunctions2INTEL:
return "IntegerFunctions2INTEL";
case SpvCapabilityFunctionPointersINTEL:
return "FunctionPointersINTEL";
case SpvCapabilityIndirectReferencesINTEL:
return "IndirectReferencesINTEL";
case SpvCapabilityAsmINTEL:
return "AsmINTEL";
case SpvCapabilityVectorComputeINTEL:
return "VectorComputeINTEL";
case SpvCapabilityVectorAnyINTEL:
return "VectorAnyINTEL";
case SpvCapabilitySubgroupAvcMotionEstimationINTEL:
return "SubgroupAvcMotionEstimationINTEL";
case SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL:
return "SubgroupAvcMotionEstimationIntraINTEL";
case SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL:
return "SubgroupAvcMotionEstimationChromaINTEL";
case SpvCapabilityVariableLengthArrayINTEL:
return "VariableLengthArrayINTEL";
case SpvCapabilityFunctionFloatControlINTEL:
return "FunctionFloatControlINTEL";
case SpvCapabilityFPGAMemoryAttributesINTEL:
return "FPGAMemoryAttributesINTEL";
case SpvCapabilityFPFastMathModeINTEL:
return "FPFastMathModeINTEL";
case SpvCapabilityArbitraryPrecisionIntegersINTEL:
return "ArbitraryPrecisionIntegersINTEL";
case SpvCapabilityUnstructuredLoopControlsINTEL:
return "UnstructuredLoopControlsINTEL";
case SpvCapabilityFPGALoopControlsINTEL:
@ -472,6 +524,18 @@ const char* CapabilityToString(SpvCapability capability) {
return "KernelAttributesINTEL";
case SpvCapabilityFPGAKernelAttributesINTEL:
return "FPGAKernelAttributesINTEL";
case SpvCapabilityFPGAMemoryAccessesINTEL:
return "FPGAMemoryAccessesINTEL";
case SpvCapabilityFPGAClusterAttributesINTEL:
return "FPGAClusterAttributesINTEL";
case SpvCapabilityLoopFuseINTEL:
return "LoopFuseINTEL";
case SpvCapabilityFPGABufferLocationINTEL:
return "FPGABufferLocationINTEL";
case SpvCapabilityUSMStorageClassesINTEL:
return "USMStorageClassesINTEL";
case SpvCapabilityIOPipesINTEL:
return "IOPipesINTEL";
case SpvCapabilityBlockingPipesINTEL:
return "BlockingPipesINTEL";
case SpvCapabilityFPGARegINTEL:
@ -480,6 +544,8 @@ const char* CapabilityToString(SpvCapability capability) {
return "AtomicFloat32AddEXT";
case SpvCapabilityAtomicFloat64AddEXT:
return "AtomicFloat64AddEXT";
case SpvCapabilityLongConstantCompositeINTEL:
return "LongConstantCompositeINTEL";
case SpvCapabilityMax:
assert(0 && "Attempting to convert SpvCapabilityMax to string");
return "";

View File

@ -21,17 +21,30 @@ kSPV_EXT_shader_viewport_index_layer,
kSPV_GOOGLE_decorate_string,
kSPV_GOOGLE_hlsl_functionality1,
kSPV_GOOGLE_user_type,
kSPV_INTEL_arbitrary_precision_integers,
kSPV_INTEL_blocking_pipes,
kSPV_INTEL_device_side_avc_motion_estimation,
kSPV_INTEL_float_controls2,
kSPV_INTEL_fp_fast_math_mode,
kSPV_INTEL_fpga_buffer_location,
kSPV_INTEL_fpga_cluster_attributes,
kSPV_INTEL_fpga_loop_controls,
kSPV_INTEL_fpga_memory_accesses,
kSPV_INTEL_fpga_memory_attributes,
kSPV_INTEL_fpga_reg,
kSPV_INTEL_function_pointers,
kSPV_INTEL_inline_assembly,
kSPV_INTEL_io_pipes,
kSPV_INTEL_kernel_attributes,
kSPV_INTEL_long_constant_composite,
kSPV_INTEL_loop_fuse,
kSPV_INTEL_media_block_io,
kSPV_INTEL_shader_integer_functions2,
kSPV_INTEL_subgroups,
kSPV_INTEL_unstructured_loop_controls,
kSPV_INTEL_usm_storage_classes,
kSPV_INTEL_variable_length_array,
kSPV_INTEL_vector_compute,
kSPV_KHR_16bit_storage,
kSPV_KHR_8bit_storage,
kSPV_KHR_device_group,
@ -53,6 +66,7 @@ kSPV_KHR_subgroup_vote,
kSPV_KHR_terminate_invocation,
kSPV_KHR_variable_pointers,
kSPV_KHR_vulkan_memory_model,
kSPV_KHR_workgroup_memory_explicit_layout,
kSPV_NVX_multiview_per_view_attributes,
kSPV_NV_compute_shader_derivatives,
kSPV_NV_cooperative_matrix,

View File

@ -1,4 +1,5 @@
static const SpvCapability pygen_variable_caps_Addresses[] = {SpvCapabilityAddresses};
static const SpvCapability pygen_variable_caps_AsmINTEL[] = {SpvCapabilityAsmINTEL};
static const SpvCapability pygen_variable_caps_AtomicStorage[] = {SpvCapabilityAtomicStorage};
static const SpvCapability pygen_variable_caps_ClipDistance[] = {SpvCapabilityClipDistance};
static const SpvCapability pygen_variable_caps_ComputeDerivativeGroupLinearNV[] = {SpvCapabilityComputeDerivativeGroupLinearNV};
@ -10,8 +11,12 @@ static const SpvCapability pygen_variable_caps_DeviceEnqueue[] = {SpvCapabilityD
static const SpvCapability pygen_variable_caps_DeviceGroup[] = {SpvCapabilityDeviceGroup};
static const SpvCapability pygen_variable_caps_DrawParameters[] = {SpvCapabilityDrawParameters};
static const SpvCapability pygen_variable_caps_DrawParametersMeshShadingNV[] = {SpvCapabilityDrawParameters, SpvCapabilityMeshShadingNV};
static const SpvCapability pygen_variable_caps_FPFastMathModeINTEL[] = {SpvCapabilityFPFastMathModeINTEL};
static const SpvCapability pygen_variable_caps_FPGABufferLocationINTEL[] = {SpvCapabilityFPGABufferLocationINTEL};
static const SpvCapability pygen_variable_caps_FPGAClusterAttributesINTEL[] = {SpvCapabilityFPGAClusterAttributesINTEL};
static const SpvCapability pygen_variable_caps_FPGAKernelAttributesINTEL[] = {SpvCapabilityFPGAKernelAttributesINTEL};
static const SpvCapability pygen_variable_caps_FPGALoopControlsINTEL[] = {SpvCapabilityFPGALoopControlsINTEL};
static const SpvCapability pygen_variable_caps_FPGAMemoryAccessesINTEL[] = {SpvCapabilityFPGAMemoryAccessesINTEL};
static const SpvCapability pygen_variable_caps_FPGAMemoryAttributesINTEL[] = {SpvCapabilityFPGAMemoryAttributesINTEL};
static const SpvCapability pygen_variable_caps_FragmentBarycentricNV[] = {SpvCapabilityFragmentBarycentricNV};
static const SpvCapability pygen_variable_caps_FragmentDensityEXTShadingRateNV[] = {SpvCapabilityFragmentDensityEXT, SpvCapabilityShadingRateNV};
@ -20,6 +25,7 @@ static const SpvCapability pygen_variable_caps_FragmentShaderPixelInterlockEXT[]
static const SpvCapability pygen_variable_caps_FragmentShaderSampleInterlockEXT[] = {SpvCapabilityFragmentShaderSampleInterlockEXT};
static const SpvCapability pygen_variable_caps_FragmentShaderShadingRateInterlockEXT[] = {SpvCapabilityFragmentShaderShadingRateInterlockEXT};
static const SpvCapability pygen_variable_caps_FragmentShadingRateKHR[] = {SpvCapabilityFragmentShadingRateKHR};
static const SpvCapability pygen_variable_caps_FunctionFloatControlINTEL[] = {SpvCapabilityFunctionFloatControlINTEL};
static const SpvCapability pygen_variable_caps_FunctionPointersINTEL[] = {SpvCapabilityFunctionPointersINTEL};
static const SpvCapability pygen_variable_caps_GenericPointer[] = {SpvCapabilityGenericPointer};
static const SpvCapability pygen_variable_caps_Geometry[] = {SpvCapabilityGeometry};
@ -33,6 +39,7 @@ static const SpvCapability pygen_variable_caps_GeometryStreams[] = {SpvCapabilit
static const SpvCapability pygen_variable_caps_GroupNonUniform[] = {SpvCapabilityGroupNonUniform};
static const SpvCapability pygen_variable_caps_GroupNonUniformClustered[] = {SpvCapabilityGroupNonUniformClustered};
static const SpvCapability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {SpvCapabilityGroupNonUniformPartitionedNV};
static const SpvCapability pygen_variable_caps_IOPipesINTEL[] = {SpvCapabilityIOPipesINTEL};
static const SpvCapability pygen_variable_caps_ImageBasic[] = {SpvCapabilityImageBasic};
static const SpvCapability pygen_variable_caps_ImageBuffer[] = {SpvCapabilityImageBuffer};
static const SpvCapability pygen_variable_caps_ImageBufferShaderNonUniform[] = {SpvCapabilityImageBuffer, SpvCapabilityShaderNonUniform};
@ -48,6 +55,7 @@ static const SpvCapability pygen_variable_caps_KernelGroupNonUniformSubgroupBall
static const SpvCapability pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot[] = {SpvCapabilityKernel, SpvCapabilityGroupNonUniformArithmetic, SpvCapabilityGroupNonUniformBallot};
static const SpvCapability pygen_variable_caps_KernelAttributesINTEL[] = {SpvCapabilityKernelAttributesINTEL};
static const SpvCapability pygen_variable_caps_Linkage[] = {SpvCapabilityLinkage};
static const SpvCapability pygen_variable_caps_LoopFuseINTEL[] = {SpvCapabilityLoopFuseINTEL};
static const SpvCapability pygen_variable_caps_Matrix[] = {SpvCapabilityMatrix};
static const SpvCapability pygen_variable_caps_MeshShadingNV[] = {SpvCapabilityMeshShadingNV};
static const SpvCapability pygen_variable_caps_MinLod[] = {SpvCapabilityMinLod};
@ -63,6 +71,7 @@ static const SpvCapability pygen_variable_caps_RayTracingKHR[] = {SpvCapabilityR
static const SpvCapability pygen_variable_caps_RayTracingNV[] = {SpvCapabilityRayTracingNV};
static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingKHR};
static const SpvCapability pygen_variable_caps_RayTraversalPrimitiveCullingKHR[] = {SpvCapabilityRayTraversalPrimitiveCullingKHR};
static const SpvCapability pygen_variable_caps_RoundToInfinityINTEL[] = {SpvCapabilityRoundToInfinityINTEL};
static const SpvCapability pygen_variable_caps_RoundingModeRTE[] = {SpvCapabilityRoundingModeRTE};
static const SpvCapability pygen_variable_caps_RoundingModeRTZ[] = {SpvCapabilityRoundingModeRTZ};
static const SpvCapability pygen_variable_caps_SampleMaskOverrideCoverageNV[] = {SpvCapabilitySampleMaskOverrideCoverageNV};
@ -96,8 +105,12 @@ static const SpvCapability pygen_variable_caps_SubgroupBallotKHRGroupNonUniformB
static const SpvCapability pygen_variable_caps_SubgroupDispatch[] = {SpvCapabilitySubgroupDispatch};
static const SpvCapability pygen_variable_caps_Tessellation[] = {SpvCapabilityTessellation};
static const SpvCapability pygen_variable_caps_TransformFeedback[] = {SpvCapabilityTransformFeedback};
static const SpvCapability pygen_variable_caps_USMStorageClassesINTEL[] = {SpvCapabilityUSMStorageClassesINTEL};
static const SpvCapability pygen_variable_caps_VariablePointersStorageBuffer[] = {SpvCapabilityVariablePointersStorageBuffer};
static const SpvCapability pygen_variable_caps_VectorAnyINTEL[] = {SpvCapabilityVectorAnyINTEL};
static const SpvCapability pygen_variable_caps_VectorComputeINTEL[] = {SpvCapabilityVectorComputeINTEL};
static const SpvCapability pygen_variable_caps_VulkanMemoryModel[] = {SpvCapabilityVulkanMemoryModel};
static const SpvCapability pygen_variable_caps_WorkgroupMemoryExplicitLayoutKHR[] = {SpvCapabilityWorkgroupMemoryExplicitLayoutKHR};
static const spvtools::Extension pygen_variable_exts_SPV_AMD_gpu_shader_half_float_fetch[] = {spvtools::Extension::kSPV_AMD_gpu_shader_half_float_fetch};
static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_ballot[] = {spvtools::Extension::kSPV_AMD_shader_ballot};
@ -117,17 +130,30 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_stencil_expo
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_EXT_shader_viewport_index_layer, spvtools::Extension::kSPV_NV_viewport_array2};
static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1};
static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_user_type[] = {spvtools::Extension::kSPV_GOOGLE_user_type};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_arbitrary_precision_integers[] = {spvtools::Extension::kSPV_INTEL_arbitrary_precision_integers};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_blocking_pipes[] = {spvtools::Extension::kSPV_INTEL_blocking_pipes};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation[] = {spvtools::Extension::kSPV_INTEL_device_side_avc_motion_estimation};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_float_controls2[] = {spvtools::Extension::kSPV_INTEL_float_controls2};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fp_fast_math_mode[] = {spvtools::Extension::kSPV_INTEL_fp_fast_math_mode};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_buffer_location[] = {spvtools::Extension::kSPV_INTEL_fpga_buffer_location};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_cluster_attributes[] = {spvtools::Extension::kSPV_INTEL_fpga_cluster_attributes};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_loop_controls[] = {spvtools::Extension::kSPV_INTEL_fpga_loop_controls};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_memory_accesses[] = {spvtools::Extension::kSPV_INTEL_fpga_memory_accesses};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_memory_attributes[] = {spvtools::Extension::kSPV_INTEL_fpga_memory_attributes};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_reg[] = {spvtools::Extension::kSPV_INTEL_fpga_reg};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_function_pointers[] = {spvtools::Extension::kSPV_INTEL_function_pointers};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_inline_assembly[] = {spvtools::Extension::kSPV_INTEL_inline_assembly};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_io_pipes[] = {spvtools::Extension::kSPV_INTEL_io_pipes};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_kernel_attributes[] = {spvtools::Extension::kSPV_INTEL_kernel_attributes};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_long_constant_composite[] = {spvtools::Extension::kSPV_INTEL_long_constant_composite};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_loop_fuse[] = {spvtools::Extension::kSPV_INTEL_loop_fuse};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_media_block_io[] = {spvtools::Extension::kSPV_INTEL_media_block_io};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_shader_integer_functions2[] = {spvtools::Extension::kSPV_INTEL_shader_integer_functions2};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_subgroups[] = {spvtools::Extension::kSPV_INTEL_subgroups};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_unstructured_loop_controls[] = {spvtools::Extension::kSPV_INTEL_unstructured_loop_controls};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_usm_storage_classes[] = {spvtools::Extension::kSPV_INTEL_usm_storage_classes};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_variable_length_array[] = {spvtools::Extension::kSPV_INTEL_variable_length_array};
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_vector_compute[] = {spvtools::Extension::kSPV_INTEL_vector_compute};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_16bit_storage[] = {spvtools::Extension::kSPV_KHR_16bit_storage};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_8bit_storage[] = {spvtools::Extension::kSPV_KHR_8bit_storage};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_device_group[] = {spvtools::Extension::kSPV_KHR_device_group};
@ -149,6 +175,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_storage_buffer_stor
static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_vote[] = {spvtools::Extension::kSPV_KHR_subgroup_vote};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_variable_pointers};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_vulkan_memory_model[] = {spvtools::Extension::kSPV_KHR_vulkan_memory_model};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout[] = {spvtools::Extension::kSPV_KHR_workgroup_memory_explicit_layout};
static const spvtools::Extension pygen_variable_exts_SPV_NVX_multiview_per_view_attributes[] = {spvtools::Extension::kSPV_NVX_multiview_per_view_attributes};
static const spvtools::Extension pygen_variable_exts_SPV_NVX_multiview_per_view_attributesSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NVX_multiview_per_view_attributes, spvtools::Extension::kSPV_NV_mesh_shader};
static const spvtools::Extension pygen_variable_exts_SPV_NV_compute_shader_derivatives[] = {spvtools::Extension::kSPV_NV_compute_shader_derivatives};
@ -193,7 +220,9 @@ static const spv_operand_desc_t pygen_variable_FPFastMathModeEntries[] = {
{"NotInf", 0x0002, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"NSZ", 0x0004, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AllowRecip", 0x0008, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Fast", 0x0010, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
{"Fast", 0x0010, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AllowContractFastINTEL", 0x10000, 1, pygen_variable_caps_FPFastMathModeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"AllowReassocINTEL", 0x20000, 1, pygen_variable_caps_FPFastMathModeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_SelectionControlEntries[] = {
@ -219,7 +248,8 @@ static const spv_operand_desc_t pygen_variable_LoopControlEntries[] = {
{"PipelineEnableINTEL", 0x80000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"LoopCoalesceINTEL", 0x100000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"MaxInterleavingINTEL", 0x200000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"SpeculatedIterationsINTEL", 0x400000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}
{"SpeculatedIterationsINTEL", 0x400000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"NoFusionINTEL", 0x800000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_FunctionControlEntries[] = {
@ -397,10 +427,16 @@ static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = {
{"SampleInterlockUnorderedEXT", 5369, 1, pygen_variable_caps_FragmentShaderSampleInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu},
{"ShadingRateInterlockOrderedEXT", 5370, 1, pygen_variable_caps_FragmentShaderShadingRateInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu},
{"ShadingRateInterlockUnorderedEXT", 5371, 1, pygen_variable_caps_FragmentShaderShadingRateInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu},
{"SharedLocalMemorySizeINTEL", 5618, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"RoundingModeRTPINTEL", 5620, 1, pygen_variable_caps_RoundToInfinityINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"RoundingModeRTNINTEL", 5621, 1, pygen_variable_caps_RoundToInfinityINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"FloatingPointModeALTINTEL", 5622, 1, pygen_variable_caps_RoundToInfinityINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"FloatingPointModeIEEEINTEL", 5623, 1, pygen_variable_caps_RoundToInfinityINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"MaxWorkgroupSizeINTEL", 5893, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"MaxWorkDimINTEL", 5894, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"NoGlobalOffsetINTEL", 5895, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu},
{"NumSIMDWorkitemsINTEL", 5896, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}
{"NumSIMDWorkitemsINTEL", 5896, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"SchedulerTargetFmaxMhzINTEL", 5903, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = {
@ -431,7 +467,9 @@ static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = {
{"ShaderRecordBufferKHR", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"PhysicalStorageBuffer", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"CodeSectionINTEL", 5605, 1, pygen_variable_caps_FunctionPointersINTEL, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu}
{"CodeSectionINTEL", 5605, 1, pygen_variable_caps_FunctionPointersINTEL, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu},
{"DeviceOnlyINTEL", 5936, 1, pygen_variable_caps_USMStorageClassesINTEL, 1, pygen_variable_exts_SPV_INTEL_usm_storage_classes, {}, 0xffffffffu, 0xffffffffu},
{"HostOnlyINTEL", 5937, 1, pygen_variable_caps_USMStorageClassesINTEL, 1, pygen_variable_exts_SPV_INTEL_usm_storage_classes, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_DimEntries[] = {
@ -552,6 +590,16 @@ static const spv_operand_desc_t pygen_variable_FPRoundingModeEntries[] = {
{"RTN", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_FPDenormModeEntries[] = {
{"Preserve", 0, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"FlushToZero", 1, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_FPOperationModeEntries[] = {
{"IEEE", 0, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"ALT", 1, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_LinkageTypeEntries[] = {
{"Export", 0, 1, pygen_variable_caps_Linkage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Import", 1, 1, pygen_variable_caps_Linkage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
@ -639,12 +687,22 @@ static const spv_operand_desc_t pygen_variable_DecorationEntries[] = {
{"RestrictPointerEXT", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"AliasedPointer", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"AliasedPointerEXT", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"SIMTCallINTEL", 5599, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"ReferencedIndirectlyINTEL", 5602, 1, pygen_variable_caps_IndirectReferencesINTEL, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu},
{"ClobberINTEL", 5607, 1, pygen_variable_caps_AsmINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu},
{"SideEffectsINTEL", 5608, 1, pygen_variable_caps_AsmINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"VectorComputeVariableINTEL", 5624, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"FuncParamIOKindINTEL", 5625, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"VectorComputeFunctionINTEL", 5626, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"StackCallINTEL", 5627, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"GlobalVariableOffsetINTEL", 5628, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"CounterBuffer", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"HlslCounterBufferGOOGLE", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu},
{"UserSemantic", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"HlslSemanticGOOGLE", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu},
{"UserTypeGOOGLE", 5636, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_user_type, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu},
{"FunctionRoundingModeINTEL", 5822, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_FP_ROUNDING_MODE}, 0xffffffffu, 0xffffffffu},
{"FunctionDenormModeINTEL", 5823, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_FPDENORM_MODE}, 0xffffffffu, 0xffffffffu},
{"RegisterINTEL", 5825, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu},
{"MemoryINTEL", 5826, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu},
{"NumbanksINTEL", 5827, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
@ -656,7 +714,18 @@ static const spv_operand_desc_t pygen_variable_DecorationEntries[] = {
{"SimpleDualPortINTEL", 5833, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu},
{"MergeINTEL", 5834, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu},
{"BankBitsINTEL", 5835, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"ForcePow2DepthINTEL", 5836, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}
{"ForcePow2DepthINTEL", 5836, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"BurstCoalesceINTEL", 5899, 1, pygen_variable_caps_FPGAMemoryAccessesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"CacheSizeINTEL", 5900, 1, pygen_variable_caps_FPGAMemoryAccessesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"DontStaticallyCoalesceINTEL", 5901, 1, pygen_variable_caps_FPGAMemoryAccessesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"PrefetchINTEL", 5902, 1, pygen_variable_caps_FPGAMemoryAccessesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"StallEnableINTEL", 5905, 1, pygen_variable_caps_FPGAClusterAttributesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"FuseLoopsInFunctionINTEL", 5907, 1, pygen_variable_caps_LoopFuseINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"BufferLocationINTEL", 5921, 1, pygen_variable_caps_FPGABufferLocationINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"IOPipeStorageINTEL", 5944, 1, pygen_variable_caps_IOPipesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
{"FunctionFloatingPointModeINTEL", 6080, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_FPOPERATION_MODE}, 0xffffffffu, 0xffffffffu},
{"SingleElementVectorINTEL", 6085, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"VectorComputeCallableFunctionINTEL", 6087, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
@ -880,6 +949,9 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"FragmentShadingRateKHR", 4422, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupBallotKHR", 4423, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, 0xffffffffu, 0xffffffffu},
{"DrawParameters", 4427, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"WorkgroupMemoryExplicitLayoutKHR", 4428, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout, {}, 0xffffffffu, 0xffffffffu},
{"WorkgroupMemoryExplicitLayout8BitAccessKHR", 4429, 1, pygen_variable_caps_WorkgroupMemoryExplicitLayoutKHR, 1, pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout, {}, 0xffffffffu, 0xffffffffu},
{"WorkgroupMemoryExplicitLayout16BitAccessKHR", 4430, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupVoteKHR", 4431, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, {}, 0xffffffffu, 0xffffffffu},
{"StorageBuffer16BitAccess", 4433, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"StorageUniformBufferBlock16", 4433, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
@ -970,21 +1042,37 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"SubgroupBufferBlockIOINTEL", 5569, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupImageBlockIOINTEL", 5570, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupImageMediaBlockIOINTEL", 5579, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_media_block_io, {}, 0xffffffffu, 0xffffffffu},
{"RoundToInfinityINTEL", 5582, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_float_controls2, {}, 0xffffffffu, 0xffffffffu},
{"FloatingPointModeINTEL", 5583, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_float_controls2, {}, 0xffffffffu, 0xffffffffu},
{"IntegerFunctions2INTEL", 5584, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_INTEL_shader_integer_functions2, {}, 0xffffffffu, 0xffffffffu},
{"FunctionPointersINTEL", 5603, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu},
{"IndirectReferencesINTEL", 5604, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu},
{"AsmINTEL", 5606, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_inline_assembly, {}, 0xffffffffu, 0xffffffffu},
{"VectorComputeINTEL", 5617, 1, pygen_variable_caps_VectorAnyINTEL, 1, pygen_variable_exts_SPV_INTEL_vector_compute, {}, 0xffffffffu, 0xffffffffu},
{"VectorAnyINTEL", 5619, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_vector_compute, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMotionEstimationINTEL", 5696, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMotionEstimationIntraINTEL", 5697, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMotionEstimationChromaINTEL", 5698, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation, {}, 0xffffffffu, 0xffffffffu},
{"VariableLengthArrayINTEL", 5817, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_variable_length_array, {}, 0xffffffffu, 0xffffffffu},
{"FunctionFloatControlINTEL", 5821, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_float_controls2, {}, 0xffffffffu, 0xffffffffu},
{"FPGAMemoryAttributesINTEL", 5824, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu},
{"FPFastMathModeINTEL", 5837, 1, pygen_variable_caps_Kernel, 1, pygen_variable_exts_SPV_INTEL_fp_fast_math_mode, {}, 0xffffffffu, 0xffffffffu},
{"ArbitraryPrecisionIntegersINTEL", 5844, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_arbitrary_precision_integers, {}, 0xffffffffu, 0xffffffffu},
{"UnstructuredLoopControlsINTEL", 5886, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_unstructured_loop_controls, {}, 0xffffffffu, 0xffffffffu},
{"FPGALoopControlsINTEL", 5888, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {}, 0xffffffffu, 0xffffffffu},
{"KernelAttributesINTEL", 5892, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu},
{"FPGAKernelAttributesINTEL", 5897, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu},
{"FPGAMemoryAccessesINTEL", 5898, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_accesses, {}, 0xffffffffu, 0xffffffffu},
{"FPGAClusterAttributesINTEL", 5904, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_cluster_attributes, {}, 0xffffffffu, 0xffffffffu},
{"LoopFuseINTEL", 5906, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_loop_fuse, {}, 0xffffffffu, 0xffffffffu},
{"FPGABufferLocationINTEL", 5920, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_buffer_location, {}, 0xffffffffu, 0xffffffffu},
{"USMStorageClassesINTEL", 5935, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_usm_storage_classes, {}, 0xffffffffu, 0xffffffffu},
{"IOPipesINTEL", 5943, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_io_pipes, {}, 0xffffffffu, 0xffffffffu},
{"BlockingPipesINTEL", 5945, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_blocking_pipes, {}, 0xffffffffu, 0xffffffffu},
{"FPGARegINTEL", 5948, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_reg, {}, 0xffffffffu, 0xffffffffu},
{"AtomicFloat32AddEXT", 6033, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, {}, 0xffffffffu, 0xffffffffu},
{"AtomicFloat64AddEXT", 6034, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, {}, 0xffffffffu, 0xffffffffu}
{"AtomicFloat64AddEXT", 6034, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, {}, 0xffffffffu, 0xffffffffu},
{"LongConstantCompositeINTEL", 6089, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_long_constant_composite, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_RayQueryIntersectionEntries[] = {
@ -1143,6 +1231,8 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = {
{SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER, ARRAY_SIZE(pygen_variable_ImageChannelOrderEntries), pygen_variable_ImageChannelOrderEntries},
{SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE, ARRAY_SIZE(pygen_variable_ImageChannelDataTypeEntries), pygen_variable_ImageChannelDataTypeEntries},
{SPV_OPERAND_TYPE_FP_ROUNDING_MODE, ARRAY_SIZE(pygen_variable_FPRoundingModeEntries), pygen_variable_FPRoundingModeEntries},
{SPV_OPERAND_TYPE_FPDENORM_MODE, ARRAY_SIZE(pygen_variable_FPDenormModeEntries), pygen_variable_FPDenormModeEntries},
{SPV_OPERAND_TYPE_FPOPERATION_MODE, ARRAY_SIZE(pygen_variable_FPOperationModeEntries), pygen_variable_FPOperationModeEntries},
{SPV_OPERAND_TYPE_LINKAGE_TYPE, ARRAY_SIZE(pygen_variable_LinkageTypeEntries), pygen_variable_LinkageTypeEntries},
{SPV_OPERAND_TYPE_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries},
{SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE, ARRAY_SIZE(pygen_variable_FunctionParameterAttributeEntries), pygen_variable_FunctionParameterAttributeEntries},

View File

@ -261,6 +261,11 @@ typedef enum spv_operand_type_t {
SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, // Sec 3.6
SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, // Sec 3.7
// The following are concrete enum types from SPV_INTEL_float_controls2
// https://github.com/intel/llvm/blob/39fa9b0cbfbae88327118990a05c5b387b56d2ef/sycl/doc/extensions/SPIRV/SPV_INTEL_float_controls2.asciidoc
SPV_OPERAND_TYPE_FPDENORM_MODE, // Sec 3.17 FP Denorm Mode
SPV_OPERAND_TYPE_FPOPERATION_MODE, // Sec 3.18 FP Operation Mode
// This is a sentinel value, and does not represent an operand type.
// It should come last.
SPV_OPERAND_TYPE_NUM_OPERAND_TYPES,

View File

@ -1,426 +0,0 @@
# Copyright (c) 2015-2016 The Khronos Group Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(GRAMMAR_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_grammar_tables.py")
set(VIMSYNTAX_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_vim_syntax.py")
set(XML_REGISTRY_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_registry_tables.py")
set(LANG_HEADER_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_language_headers.py")
# For now, assume the DebugInfo grammar file is in the current directory.
# It might migrate to SPIRV-Headers.
set(DEBUGINFO_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/unified1/extinst.debuginfo.grammar.json")
set(CLDEBUGINFO100_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json")
# macro() definitions are used in the following because we need to append .inc
# file paths into some global lists (*_CPP_DEPENDS). And those global lists are
# later used by set_source_files_properties() calls.
# function() definitions are not suitable because they create new scopes.
macro(spvtools_core_tables CONFIG_VERSION)
set(GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json")
set(GRAMMAR_INSTS_INC_FILE "${spirv-tools_BINARY_DIR}/core.insts-${CONFIG_VERSION}.inc")
set(GRAMMAR_KINDS_INC_FILE "${spirv-tools_BINARY_DIR}/operand.kinds-${CONFIG_VERSION}.inc")
add_custom_command(OUTPUT ${GRAMMAR_INSTS_INC_FILE} ${GRAMMAR_KINDS_INC_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
--spirv-core-grammar=${GRAMMAR_JSON_FILE}
--extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE}
--extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
--core-insts-output=${GRAMMAR_INSTS_INC_FILE}
--operand-kinds-output=${GRAMMAR_KINDS_INC_FILE}
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT}
${GRAMMAR_JSON_FILE}
${DEBUGINFO_GRAMMAR_JSON_FILE}
${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
COMMENT "Generate info tables for SPIR-V v${CONFIG_VERSION} core instructions and operands.")
list(APPEND OPCODE_CPP_DEPENDS ${GRAMMAR_INSTS_INC_FILE})
list(APPEND OPERAND_CPP_DEPENDS ${GRAMMAR_KINDS_INC_FILE})
endmacro(spvtools_core_tables)
macro(spvtools_enum_string_mapping CONFIG_VERSION)
set(GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json")
set(GRAMMAR_EXTENSION_ENUM_INC_FILE "${spirv-tools_BINARY_DIR}/extension_enum.inc")
set(GRAMMAR_ENUM_STRING_MAPPING_INC_FILE "${spirv-tools_BINARY_DIR}/enum_string_mapping.inc")
add_custom_command(OUTPUT ${GRAMMAR_EXTENSION_ENUM_INC_FILE}
${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
--spirv-core-grammar=${GRAMMAR_JSON_FILE}
--extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE}
--extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
--extension-enum-output=${GRAMMAR_EXTENSION_ENUM_INC_FILE}
--enum-string-mapping-output=${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE}
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT}
${GRAMMAR_JSON_FILE}
${DEBUGINFO_GRAMMAR_JSON_FILE}
${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
COMMENT "Generate enum-string mapping for SPIR-V v${CONFIG_VERSION}.")
list(APPEND EXTENSION_H_DEPENDS ${GRAMMAR_EXTENSION_ENUM_INC_FILE})
list(APPEND ENUM_STRING_MAPPING_CPP_DEPENDS ${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE})
endmacro(spvtools_enum_string_mapping)
macro(spvtools_vimsyntax CONFIG_VERSION CLVERSION)
set(GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json")
set(GLSL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.glsl.std.450.grammar.json")
set(OPENCL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.opencl.std.100.grammar.json")
set(VIMSYNTAX_FILE "${spirv-tools_BINARY_DIR}/spvasm.vim")
add_custom_command(OUTPUT ${VIMSYNTAX_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${VIMSYNTAX_PROCESSING_SCRIPT}
--spirv-core-grammar=${GRAMMAR_JSON_FILE}
--extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE}
--extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE}
--extinst-opencl-grammar=${OPENCL_GRAMMAR_JSON_FILE}
>${VIMSYNTAX_FILE}
DEPENDS ${VIMSYNTAX_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE}
${GLSL_GRAMMAR_JSON_FILE} ${OPENCL_GRAMMAR_JSON_FILE} ${DEBUGINFO_GRAMMAR_JSON_FILE}
COMMENT "Generate spvasm.vim: Vim syntax file for SPIR-V assembly.")
endmacro(spvtools_vimsyntax)
macro(spvtools_glsl_tables CONFIG_VERSION)
set(CORE_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json")
set(GLSL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.glsl.std.450.grammar.json")
set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/glsl.std.450.insts.inc")
add_custom_command(OUTPUT ${GRAMMAR_INC_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
--extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE}
--glsl-insts-output=${GRAMMAR_INC_FILE}
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${GLSL_GRAMMAR_JSON_FILE}
COMMENT "Generate info tables for GLSL extended instructions and operands v${CONFIG_VERSION}.")
list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE})
endmacro(spvtools_glsl_tables)
macro(spvtools_opencl_tables CONFIG_VERSION)
set(CORE_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json")
set(OPENCL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.opencl.std.100.grammar.json")
set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/opencl.std.insts.inc")
add_custom_command(OUTPUT ${GRAMMAR_INC_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
--extinst-opencl-grammar=${OPENCL_GRAMMAR_JSON_FILE}
--opencl-insts-output=${GRAMMAR_INC_FILE}
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${OPENCL_GRAMMAR_JSON_FILE}
COMMENT "Generate info tables for OpenCL extended instructions and operands v${CONFIG_VERSION}.")
list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE})
endmacro(spvtools_opencl_tables)
macro(spvtools_vendor_tables VENDOR_TABLE SHORT_NAME OPERAND_KIND_PREFIX)
set(INSTS_FILE "${spirv-tools_BINARY_DIR}/${VENDOR_TABLE}.insts.inc")
set(GRAMMAR_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/unified1/extinst.${VENDOR_TABLE}.grammar.json")
add_custom_command(OUTPUT ${INSTS_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
--extinst-vendor-grammar=${GRAMMAR_FILE}
--vendor-insts-output=${INSTS_FILE}
--vendor-operand-kind-prefix=${OPERAND_KIND_PREFIX}
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_FILE}
COMMENT "Generate extended instruction tables for ${VENDOR_TABLE}.")
add_custom_target(spv-tools-${SHORT_NAME} DEPENDS ${INSTS_FILE})
set_property(TARGET spv-tools-${SHORT_NAME} PROPERTY FOLDER "SPIRV-Tools build")
list(APPEND EXTINST_CPP_DEPENDS spv-tools-${SHORT_NAME})
endmacro(spvtools_vendor_tables)
macro(spvtools_extinst_lang_headers NAME GRAMMAR_FILE)
set(OUT_H ${spirv-tools_BINARY_DIR}/${NAME}.h)
add_custom_command(OUTPUT ${OUT_H}
COMMAND ${PYTHON_EXECUTABLE} ${LANG_HEADER_PROCESSING_SCRIPT}
--extinst-grammar=${GRAMMAR_FILE}
--extinst-output-path=${OUT_H}
DEPENDS ${LANG_HEADER_PROCESSING_SCRIPT} ${GRAMMAR_FILE}
COMMENT "Generate language specific header for ${NAME}.")
add_custom_target(spirv-tools-header-${NAME} DEPENDS ${OUT_H})
set_property(TARGET spirv-tools-header-${NAME} PROPERTY FOLDER "SPIRV-Tools build")
list(APPEND EXTINST_CPP_DEPENDS spirv-tools-header-${NAME})
endmacro(spvtools_extinst_lang_headers)
spvtools_core_tables("unified1")
spvtools_enum_string_mapping("unified1")
spvtools_opencl_tables("unified1")
spvtools_glsl_tables("unified1")
spvtools_vendor_tables("spv-amd-shader-explicit-vertex-parameter" "spv-amd-sevp" "")
spvtools_vendor_tables("spv-amd-shader-trinary-minmax" "spv-amd-stm" "")
spvtools_vendor_tables("spv-amd-gcn-shader" "spv-amd-gs" "")
spvtools_vendor_tables("spv-amd-shader-ballot" "spv-amd-sb" "")
spvtools_vendor_tables("debuginfo" "debuginfo" "")
spvtools_vendor_tables("opencl.debuginfo.100" "cldi100" "CLDEBUG100_")
spvtools_vendor_tables("nonsemantic.clspvreflection" "clspvreflection" "")
spvtools_extinst_lang_headers("DebugInfo" ${DEBUGINFO_GRAMMAR_JSON_FILE})
spvtools_extinst_lang_headers("OpenCLDebugInfo100" ${CLDEBUGINFO100_GRAMMAR_JSON_FILE})
spvtools_vimsyntax("unified1" "1.0")
add_custom_target(spirv-tools-vimsyntax DEPENDS ${VIMSYNTAX_FILE})
set_property(TARGET spirv-tools-vimsyntax PROPERTY FOLDER "SPIRV-Tools utilities")
# Extract the list of known generators from the SPIR-V XML registry file.
set(GENERATOR_INC_FILE ${spirv-tools_BINARY_DIR}/generators.inc)
set(SPIRV_XML_REGISTRY_FILE ${SPIRV_HEADER_INCLUDE_DIR}/spirv/spir-v.xml)
add_custom_command(OUTPUT ${GENERATOR_INC_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${XML_REGISTRY_PROCESSING_SCRIPT}
--xml=${SPIRV_XML_REGISTRY_FILE}
--generator-output=${GENERATOR_INC_FILE}
DEPENDS ${XML_REGISTRY_PROCESSING_SCRIPT} ${SPIRV_XML_REGISTRY_FILE}
COMMENT "Generate tables based on the SPIR-V XML registry.")
list(APPEND OPCODE_CPP_DEPENDS ${GENERATOR_INC_FILE})
# The following .cpp files include the above generated .inc files.
# Add those .inc files as their dependencies.
#
# We need to wrap the .inc files with a custom target to avoid problems when
# multiple targets depend on the same custom command.
add_custom_target(core_tables
DEPENDS ${OPCODE_CPP_DEPENDS} ${OPERAND_CPP_DEPENDS})
add_custom_target(enum_string_mapping
DEPENDS ${EXTENSION_H_DEPENDS} ${ENUM_STRING_MAPPING_CPP_DEPENDS})
add_custom_target(extinst_tables
DEPENDS ${EXTINST_CPP_DEPENDS})
set_source_files_properties(
${CMAKE_CURRENT_SOURCE_DIR}/extensions.h
PROPERTIES HEADER_FILE_ONLY TRUE)
set(SPIRV_TOOLS_BUILD_VERSION_INC
${spirv-tools_BINARY_DIR}/build-version.inc)
set(SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR
${spirv-tools_SOURCE_DIR}/utils/update_build_version.py)
set(SPIRV_TOOLS_CHANGES_FILE
${spirv-tools_SOURCE_DIR}/CHANGES)
add_custom_command(OUTPUT ${SPIRV_TOOLS_BUILD_VERSION_INC}
COMMAND ${PYTHON_EXECUTABLE}
${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR}
${spirv-tools_SOURCE_DIR} ${SPIRV_TOOLS_BUILD_VERSION_INC}
DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR}
${SPIRV_TOOLS_CHANGES_FILE}
COMMENT "Update build-version.inc in the SPIRV-Tools build directory (if necessary).")
# Convenience target for standalone generation of the build-version.inc file.
# This is not required for any dependence chain.
add_custom_target(spirv-tools-build-version
DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC})
set_property(TARGET spirv-tools-build-version PROPERTY FOLDER "SPIRV-Tools build")
list(APPEND PCH_DEPENDS ${ENUM_STRING_MAPPING_CPP_DEPENDS} ${OPCODE_CPP_DEPENDS} ${OPERAND_CPP_DEPENDS} ${EXTENSION_H_DEPENDS} ${EXTINST_CPP_DEPENDS} ${SPIRV_TOOLS_BUILD_VERSION_INC})
set_source_files_properties(
${CMAKE_CURRENT_SOURCE_DIR}/pch_source.cpp
PROPERTIES OBJECT_DEPENDS "${PCH_DEPENDS}")
add_subdirectory(opt)
add_subdirectory(reduce)
add_subdirectory(fuzz)
add_subdirectory(link)
set(SPIRV_SOURCES
${spirv-tools_SOURCE_DIR}/include/spirv-tools/libspirv.h
${CMAKE_CURRENT_SOURCE_DIR}/util/bitutils.h
${CMAKE_CURRENT_SOURCE_DIR}/util/bit_vector.h
${CMAKE_CURRENT_SOURCE_DIR}/util/hex_float.h
${CMAKE_CURRENT_SOURCE_DIR}/util/make_unique.h
${CMAKE_CURRENT_SOURCE_DIR}/util/parse_number.h
${CMAKE_CURRENT_SOURCE_DIR}/util/small_vector.h
${CMAKE_CURRENT_SOURCE_DIR}/util/string_utils.h
${CMAKE_CURRENT_SOURCE_DIR}/util/timer.h
${CMAKE_CURRENT_SOURCE_DIR}/assembly_grammar.h
${CMAKE_CURRENT_SOURCE_DIR}/binary.h
${CMAKE_CURRENT_SOURCE_DIR}/cfa.h
${CMAKE_CURRENT_SOURCE_DIR}/diagnostic.h
${CMAKE_CURRENT_SOURCE_DIR}/disassemble.h
${CMAKE_CURRENT_SOURCE_DIR}/enum_set.h
${CMAKE_CURRENT_SOURCE_DIR}/enum_string_mapping.h
${CMAKE_CURRENT_SOURCE_DIR}/ext_inst.h
${CMAKE_CURRENT_SOURCE_DIR}/extensions.h
${CMAKE_CURRENT_SOURCE_DIR}/instruction.h
${CMAKE_CURRENT_SOURCE_DIR}/latest_version_glsl_std_450_header.h
${CMAKE_CURRENT_SOURCE_DIR}/latest_version_opencl_std_header.h
${CMAKE_CURRENT_SOURCE_DIR}/latest_version_spirv_header.h
${CMAKE_CURRENT_SOURCE_DIR}/macro.h
${CMAKE_CURRENT_SOURCE_DIR}/name_mapper.h
${CMAKE_CURRENT_SOURCE_DIR}/opcode.h
${CMAKE_CURRENT_SOURCE_DIR}/operand.h
${CMAKE_CURRENT_SOURCE_DIR}/parsed_operand.h
${CMAKE_CURRENT_SOURCE_DIR}/print.h
${CMAKE_CURRENT_SOURCE_DIR}/spirv_constant.h
${CMAKE_CURRENT_SOURCE_DIR}/spirv_definition.h
${CMAKE_CURRENT_SOURCE_DIR}/spirv_endian.h
${CMAKE_CURRENT_SOURCE_DIR}/spirv_fuzzer_options.h
${CMAKE_CURRENT_SOURCE_DIR}/spirv_optimizer_options.h
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reducer_options.h
${CMAKE_CURRENT_SOURCE_DIR}/spirv_target_env.h
${CMAKE_CURRENT_SOURCE_DIR}/spirv_validator_options.h
${CMAKE_CURRENT_SOURCE_DIR}/table.h
${CMAKE_CURRENT_SOURCE_DIR}/text.h
${CMAKE_CURRENT_SOURCE_DIR}/text_handler.h
${CMAKE_CURRENT_SOURCE_DIR}/val/validate.h
${CMAKE_CURRENT_SOURCE_DIR}/util/bit_vector.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/parse_number.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/string_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/assembly_grammar.cpp
${CMAKE_CURRENT_SOURCE_DIR}/binary.cpp
${CMAKE_CURRENT_SOURCE_DIR}/diagnostic.cpp
${CMAKE_CURRENT_SOURCE_DIR}/disassemble.cpp
${CMAKE_CURRENT_SOURCE_DIR}/enum_string_mapping.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext_inst.cpp
${CMAKE_CURRENT_SOURCE_DIR}/extensions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libspirv.cpp
${CMAKE_CURRENT_SOURCE_DIR}/name_mapper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/opcode.cpp
${CMAKE_CURRENT_SOURCE_DIR}/operand.cpp
${CMAKE_CURRENT_SOURCE_DIR}/parsed_operand.cpp
${CMAKE_CURRENT_SOURCE_DIR}/print.cpp
${CMAKE_CURRENT_SOURCE_DIR}/software_version.cpp
${CMAKE_CURRENT_SOURCE_DIR}/spirv_endian.cpp
${CMAKE_CURRENT_SOURCE_DIR}/spirv_fuzzer_options.cpp
${CMAKE_CURRENT_SOURCE_DIR}/spirv_optimizer_options.cpp
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reducer_options.cpp
${CMAKE_CURRENT_SOURCE_DIR}/spirv_target_env.cpp
${CMAKE_CURRENT_SOURCE_DIR}/spirv_validator_options.cpp
${CMAKE_CURRENT_SOURCE_DIR}/table.cpp
${CMAKE_CURRENT_SOURCE_DIR}/text.cpp
${CMAKE_CURRENT_SOURCE_DIR}/text_handler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_adjacency.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_annotation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_arithmetics.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_atomics.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_barriers.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_bitwise.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_builtins.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_capability.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_cfg.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_composites.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_constants.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_conversion.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_debug.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_decorations.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_derivatives.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_extensions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_execution_limitations.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_function.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_id.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_image.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_interfaces.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_instruction.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_layout.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_literals.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_logicals.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_memory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_memory_semantics.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_misc.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_mode_setting.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_non_uniform.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_primitives.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_scopes.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_small_type_uses.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_type.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/decoration.h
${CMAKE_CURRENT_SOURCE_DIR}/val/basic_block.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/construct.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/function.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/instruction.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validation_state.cpp)
if (${SPIRV_TIMER_ENABLED})
set(SPIRV_SOURCES
${SPIRV_SOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/util/timer.cpp)
endif()
# The software_version.cpp file includes build-version.inc.
# Rebuild the software_version.cpp object file if it is older than
# build-version.inc or whenever build-version.inc itself is out of
# date. In the latter case, rebuild build-version.inc first.
# CMake is not smart enough to detect this dependency automatically.
# Without this, the dependency detection system for #included files
# does not kick in on a clean build for the following reason: The
# build will fail early because it doesn't know how to build the
# missing source file build-version.inc. That occurs before the
# preprocessor is run on software_version.cpp to detect the
# #include dependency.
set_source_files_properties(
${CMAKE_CURRENT_SOURCE_DIR}/software_version.cpp
PROPERTIES OBJECT_DEPENDS "${SPIRV_TOOLS_BUILD_VERSION_INC}")
spvtools_pch(SPIRV_SOURCES pch_source)
# spirv_tools_default_target_options() sets the target options that are common
# for all ${SPIRV_TOOLS} targets.
function(spirv_tools_default_target_options target)
spvtools_default_compile_options(${target})
target_include_directories(${target}
PUBLIC
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE ${spirv-tools_BINARY_DIR}
PRIVATE ${SPIRV_HEADER_INCLUDE_DIR}
)
set_property(TARGET ${target} PROPERTY FOLDER "SPIRV-Tools libraries")
spvtools_check_symbol_exports(${target})
add_dependencies(${target} core_tables enum_string_mapping extinst_tables)
endfunction()
# Always build ${SPIRV_TOOLS}-shared. This is expected distro packages, and
# unlike the other SPIRV_TOOLS target, defaults to hidden symbol visibility.
add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
spirv_tools_default_target_options(${SPIRV_TOOLS}-shared)
set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES CXX_VISIBILITY_PRESET hidden)
target_compile_definitions(${SPIRV_TOOLS}-shared
PRIVATE SPIRV_TOOLS_IMPLEMENTATION
PUBLIC SPIRV_TOOLS_SHAREDLIB
)
if(SPIRV_TOOLS_BUILD_STATIC)
add_library(${SPIRV_TOOLS}-static STATIC ${SPIRV_SOURCES})
spirv_tools_default_target_options(${SPIRV_TOOLS}-static)
# The static target does not have the '-static' suffix.
set_target_properties(${SPIRV_TOOLS}-static PROPERTIES OUTPUT_NAME "${SPIRV_TOOLS}")
# Create the "${SPIRV_TOOLS}" target as an alias to either "${SPIRV_TOOLS}-static"
# or "${SPIRV_TOOLS}-shared" depending on the value of BUILD_SHARED_LIBS.
if(BUILD_SHARED_LIBS)
add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-shared)
else()
add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-static)
endif()
set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static ${SPIRV_TOOLS}-shared)
else()
add_library(${SPIRV_TOOLS} ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_SOURCES})
spirv_tools_default_target_options(${SPIRV_TOOLS})
set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS} ${SPIRV_TOOLS}-shared)
endif()
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
find_library(LIBRT rt)
if(LIBRT)
foreach(target ${SPIRV_TOOLS_TARGETS})
target_link_libraries(${target} ${LIBRT})
endforeach()
endif()
endif()
if(ENABLE_SPIRV_TOOLS_INSTALL)
install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
export(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake)
spvtools_config_package_dir(${SPIRV_TOOLS} PACKAGE_DIR)
install(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake DESTINATION ${PACKAGE_DIR})
# Special config file for root library compared to other libs.
file(WRITE ${CMAKE_BINARY_DIR}/${SPIRV_TOOLS}Config.cmake
"include(\${CMAKE_CURRENT_LIST_DIR}/${SPIRV_TOOLS}Target.cmake)\n"
"set(${SPIRV_TOOLS}_LIBRARIES ${SPIRV_TOOLS})\n"
"get_target_property(${SPIRV_TOOLS}_INCLUDE_DIRS ${SPIRV_TOOLS} INTERFACE_INCLUDE_DIRECTORIES)\n")
install(FILES ${CMAKE_BINARY_DIR}/${SPIRV_TOOLS}Config.cmake DESTINATION ${PACKAGE_DIR})
endif(ENABLE_SPIRV_TOOLS_INSTALL)
if(MSVC AND (NOT ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
# Enable parallel builds across four cores for this lib
add_definitions(/MP4)
endif()

View File

@ -655,7 +655,9 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: {
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
case SPV_OPERAND_TYPE_FPDENORM_MODE:
case SPV_OPERAND_TYPE_FPOPERATION_MODE: {
// A single word that is a plain enum value.
// Map an optional operand type to its corresponding concrete type.

View File

@ -326,7 +326,9 @@ void Disassembler::EmitOperand(const spv_parsed_instruction_t& inst,
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: {
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
case SPV_OPERAND_TYPE_FPDENORM_MODE:
case SPV_OPERAND_TYPE_FPOPERATION_MODE: {
spv_operand_desc entry;
if (grammar_.lookupOperand(operand.type, word, &entry))
assert(false && "should have caught this earlier");

View File

@ -1,46 +0,0 @@
# Copyright (c) 2017 Pierre Moreau
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
add_library(SPIRV-Tools-link ${SPIRV_TOOLS_LIBRARY_TYPE}
linker.cpp
)
spvtools_default_compile_options(SPIRV-Tools-link)
target_include_directories(SPIRV-Tools-link
PUBLIC
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${SPIRV_HEADER_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE ${spirv-tools_BINARY_DIR}
)
# We need the IR functionnalities from the optimizer
target_link_libraries(SPIRV-Tools-link
PUBLIC SPIRV-Tools-opt)
set_property(TARGET SPIRV-Tools-link PROPERTY FOLDER "SPIRV-Tools libraries")
spvtools_check_symbol_exports(SPIRV-Tools-link)
if(ENABLE_SPIRV_TOOLS_INSTALL)
install(TARGETS SPIRV-Tools-link EXPORT SPIRV-Tools-linkTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
export(EXPORT SPIRV-Tools-linkTargets FILE SPIRV-Tools-linkTargets.cmake)
spvtools_config_package_dir(SPIRV-Tools-link PACKAGE_DIR)
install(EXPORT SPIRV-Tools-linkTargets FILE SPIRV-Tools-linkTargets.cmake
DESTINATION ${PACKAGE_DIR})
spvtools_generate_config_file(SPIRV-Tools-link)
install(FILES ${CMAKE_BINARY_DIR}/SPIRV-Tools-linkConfig.cmake DESTINATION ${PACKAGE_DIR})
endif(ENABLE_SPIRV_TOOLS_INSTALL)

View File

@ -265,6 +265,11 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
return "image channel data type";
case SPV_OPERAND_TYPE_FPDENORM_MODE:
return "FP denorm mode";
case SPV_OPERAND_TYPE_FPOPERATION_MODE:
return "FP operation mode";
case SPV_OPERAND_TYPE_NONE:
return "NONE";
default:
@ -348,6 +353,8 @@ bool spvOperandIsConcrete(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
case SPV_OPERAND_TYPE_FPDENORM_MODE:
case SPV_OPERAND_TYPE_FPOPERATION_MODE:
return true;
default:
break;

View File

@ -1,256 +0,0 @@
# Copyright (c) 2016 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(SPIRV_TOOLS_OPT_SOURCES
aggressive_dead_code_elim_pass.h
amd_ext_to_khr.h
basic_block.h
block_merge_pass.h
block_merge_util.h
build_module.h
ccp_pass.h
cfg_cleanup_pass.h
cfg.h
code_sink.h
combine_access_chains.h
compact_ids_pass.h
composite.h
const_folding_rules.h
constants.h
convert_to_half_pass.h
copy_prop_arrays.h
dead_branch_elim_pass.h
dead_insert_elim_pass.h
dead_variable_elimination.h
decoration_manager.h
debug_info_manager.h
def_use_manager.h
desc_sroa.h
dominator_analysis.h
dominator_tree.h
eliminate_dead_constant_pass.h
eliminate_dead_functions_pass.h
eliminate_dead_functions_util.h
eliminate_dead_members_pass.h
empty_pass.h
feature_manager.h
fix_storage_class.h
flatten_decoration_pass.h
fold.h
folding_rules.h
fold_spec_constant_op_and_composite_pass.h
freeze_spec_constant_value_pass.h
function.h
graphics_robust_access_pass.h
if_conversion.h
inline_exhaustive_pass.h
inline_opaque_pass.h
inline_pass.h
inst_bindless_check_pass.h
inst_buff_addr_check_pass.h
inst_debug_printf_pass.h
instruction.h
instruction_list.h
instrument_pass.h
ir_builder.h
ir_context.h
ir_loader.h
licm_pass.h
local_access_chain_convert_pass.h
local_redundancy_elimination.h
local_single_block_elim_pass.h
local_single_store_elim_pass.h
log.h
loop_dependence.h
loop_descriptor.h
loop_fission.h
loop_fusion.h
loop_fusion_pass.h
loop_peeling.h
loop_unroller.h
loop_utils.h
loop_unswitch_pass.h
mem_pass.h
merge_return_pass.h
module.h
null_pass.h
passes.h
pass.h
pass_manager.h
private_to_local_pass.h
propagator.h
reduce_load_size.h
redundancy_elimination.h
reflect.h
register_pressure.h
relax_float_ops_pass.h
remove_duplicates_pass.h
replace_invalid_opc.h
scalar_analysis.h
scalar_analysis_nodes.h
scalar_replacement_pass.h
set_spec_constant_default_value_pass.h
simplification_pass.h
ssa_rewrite_pass.h
strength_reduction_pass.h
strip_debug_info_pass.h
strip_reflect_info_pass.h
struct_cfg_analysis.h
tree_iterator.h
type_manager.h
types.h
unify_const_pass.h
upgrade_memory_model.h
value_number_table.h
vector_dce.h
workaround1209.h
wrap_opkill.h
aggressive_dead_code_elim_pass.cpp
amd_ext_to_khr.cpp
basic_block.cpp
block_merge_pass.cpp
block_merge_util.cpp
build_module.cpp
ccp_pass.cpp
cfg_cleanup_pass.cpp
cfg.cpp
code_sink.cpp
combine_access_chains.cpp
compact_ids_pass.cpp
composite.cpp
const_folding_rules.cpp
constants.cpp
convert_to_half_pass.cpp
copy_prop_arrays.cpp
dead_branch_elim_pass.cpp
dead_insert_elim_pass.cpp
dead_variable_elimination.cpp
decoration_manager.cpp
debug_info_manager.cpp
def_use_manager.cpp
desc_sroa.cpp
dominator_analysis.cpp
dominator_tree.cpp
eliminate_dead_constant_pass.cpp
eliminate_dead_functions_pass.cpp
eliminate_dead_functions_util.cpp
eliminate_dead_members_pass.cpp
feature_manager.cpp
fix_storage_class.cpp
flatten_decoration_pass.cpp
fold.cpp
folding_rules.cpp
fold_spec_constant_op_and_composite_pass.cpp
freeze_spec_constant_value_pass.cpp
function.cpp
graphics_robust_access_pass.cpp
if_conversion.cpp
inline_exhaustive_pass.cpp
inline_opaque_pass.cpp
inline_pass.cpp
inst_bindless_check_pass.cpp
inst_buff_addr_check_pass.cpp
inst_debug_printf_pass.cpp
instruction.cpp
instruction_list.cpp
instrument_pass.cpp
ir_context.cpp
ir_loader.cpp
licm_pass.cpp
local_access_chain_convert_pass.cpp
local_redundancy_elimination.cpp
local_single_block_elim_pass.cpp
local_single_store_elim_pass.cpp
loop_dependence.cpp
loop_dependence_helpers.cpp
loop_descriptor.cpp
loop_fission.cpp
loop_fusion.cpp
loop_fusion_pass.cpp
loop_peeling.cpp
loop_utils.cpp
loop_unroller.cpp
loop_unswitch_pass.cpp
mem_pass.cpp
merge_return_pass.cpp
module.cpp
optimizer.cpp
pass.cpp
pass_manager.cpp
private_to_local_pass.cpp
propagator.cpp
reduce_load_size.cpp
redundancy_elimination.cpp
register_pressure.cpp
relax_float_ops_pass.cpp
remove_duplicates_pass.cpp
replace_invalid_opc.cpp
scalar_analysis.cpp
scalar_analysis_simplification.cpp
scalar_replacement_pass.cpp
set_spec_constant_default_value_pass.cpp
simplification_pass.cpp
ssa_rewrite_pass.cpp
strength_reduction_pass.cpp
strip_debug_info_pass.cpp
strip_reflect_info_pass.cpp
struct_cfg_analysis.cpp
type_manager.cpp
types.cpp
unify_const_pass.cpp
upgrade_memory_model.cpp
value_number_table.cpp
vector_dce.cpp
workaround1209.cpp
wrap_opkill.cpp
)
if(MSVC AND (NOT ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
# Enable parallel builds across four cores for this lib
add_definitions(/MP4)
endif()
spvtools_pch(SPIRV_TOOLS_OPT_SOURCES pch_source_opt)
add_library(SPIRV-Tools-opt ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_TOOLS_OPT_SOURCES})
spvtools_default_compile_options(SPIRV-Tools-opt)
target_include_directories(SPIRV-Tools-opt
PUBLIC
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${SPIRV_HEADER_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE ${spirv-tools_BINARY_DIR}
)
# We need the assembling and disassembling functionalities in the main library.
target_link_libraries(SPIRV-Tools-opt
PUBLIC ${SPIRV_TOOLS_FULL_VISIBILITY})
set_property(TARGET SPIRV-Tools-opt PROPERTY FOLDER "SPIRV-Tools libraries")
spvtools_check_symbol_exports(SPIRV-Tools-opt)
if(ENABLE_SPIRV_TOOLS_INSTALL)
install(TARGETS SPIRV-Tools-opt EXPORT SPIRV-Tools-optTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
export(EXPORT SPIRV-Tools-optTargets FILE SPIRV-Tools-optTargets.cmake)
spvtools_config_package_dir(SPIRV-Tools-opt PACKAGE_DIR)
install(EXPORT SPIRV-Tools-optTargets FILE SPIRV-Tools-optTargets.cmake
DESTINATION ${PACKAGE_DIR})
spvtools_generate_config_file(SPIRV-Tools-opt)
install(FILES ${CMAKE_BINARY_DIR}/SPIRV-Tools-optConfig.cmake DESTINATION ${PACKAGE_DIR})
endif(ENABLE_SPIRV_TOOLS_INSTALL)

View File

@ -97,10 +97,14 @@ struct Operand {
assert(type == SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER);
assert(1 <= words.size());
assert(words.size() <= 2);
// Load the low word.
uint64_t result = uint64_t(words[0]);
uint64_t result = 0;
if (words.size() > 0) { // Needed to avoid maybe-uninitialized GCC warning
uint32_t low = words[0];
result = uint64_t(low);
}
if (words.size() > 1) {
result = result | (uint64_t(words[1]) << 32);
uint32_t high = words[1];
result = result | (uint64_t(high) << 32);
}
return result;
}

View File

@ -1,112 +0,0 @@
# Copyright (c) 2018 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(SPIRV_TOOLS_REDUCE_SOURCES
change_operand_reduction_opportunity.h
change_operand_to_undef_reduction_opportunity.h
merge_blocks_reduction_opportunity.h
merge_blocks_reduction_opportunity_finder.h
operand_to_const_reduction_opportunity_finder.h
operand_to_undef_reduction_opportunity_finder.h
operand_to_dominating_id_reduction_opportunity_finder.h
reducer.h
reduction_opportunity.h
reduction_opportunity_finder.h
reduction_pass.h
reduction_util.h
remove_block_reduction_opportunity.h
remove_block_reduction_opportunity_finder.h
remove_function_reduction_opportunity.h
remove_function_reduction_opportunity_finder.h
remove_instruction_reduction_opportunity.h
remove_selection_reduction_opportunity.h
remove_selection_reduction_opportunity_finder.h
remove_struct_member_reduction_opportunity.h
remove_unused_instruction_reduction_opportunity_finder.h
remove_unused_struct_member_reduction_opportunity_finder.h
structured_loop_to_selection_reduction_opportunity.h
structured_loop_to_selection_reduction_opportunity_finder.h
conditional_branch_to_simple_conditional_branch_opportunity_finder.h
conditional_branch_to_simple_conditional_branch_reduction_opportunity.h
simple_conditional_branch_to_branch_opportunity_finder.h
simple_conditional_branch_to_branch_reduction_opportunity.h
change_operand_reduction_opportunity.cpp
change_operand_to_undef_reduction_opportunity.cpp
merge_blocks_reduction_opportunity.cpp
merge_blocks_reduction_opportunity_finder.cpp
operand_to_const_reduction_opportunity_finder.cpp
operand_to_undef_reduction_opportunity_finder.cpp
operand_to_dominating_id_reduction_opportunity_finder.cpp
reducer.cpp
reduction_opportunity.cpp
reduction_opportunity_finder.cpp
reduction_pass.cpp
reduction_util.cpp
remove_block_reduction_opportunity.cpp
remove_block_reduction_opportunity_finder.cpp
remove_function_reduction_opportunity.cpp
remove_function_reduction_opportunity_finder.cpp
remove_instruction_reduction_opportunity.cpp
remove_selection_reduction_opportunity.cpp
remove_selection_reduction_opportunity_finder.cpp
remove_struct_member_reduction_opportunity.cpp
remove_unused_instruction_reduction_opportunity_finder.cpp
remove_unused_struct_member_reduction_opportunity_finder.cpp
structured_loop_to_selection_reduction_opportunity.cpp
structured_loop_to_selection_reduction_opportunity_finder.cpp
conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp
conditional_branch_to_simple_conditional_branch_reduction_opportunity.cpp
simple_conditional_branch_to_branch_opportunity_finder.cpp
simple_conditional_branch_to_branch_reduction_opportunity.cpp
)
if(MSVC AND (NOT ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
# Enable parallel builds across four cores for this lib
add_definitions(/MP4)
endif()
spvtools_pch(SPIRV_TOOLS_REDUCE_SOURCES pch_source_reduce)
add_library(SPIRV-Tools-reduce ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_TOOLS_REDUCE_SOURCES})
spvtools_default_compile_options(SPIRV-Tools-reduce)
target_include_directories(SPIRV-Tools-reduce
PUBLIC
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${SPIRV_HEADER_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE ${spirv-tools_BINARY_DIR}
)
# The reducer reuses a lot of functionality from the SPIRV-Tools library.
target_link_libraries(SPIRV-Tools-reduce
PUBLIC ${SPIRV_TOOLS_FULL_VISIBILITY}
PUBLIC SPIRV-Tools-opt)
set_property(TARGET SPIRV-Tools-reduce PROPERTY FOLDER "SPIRV-Tools libraries")
spvtools_check_symbol_exports(SPIRV-Tools-reduce)
if(ENABLE_SPIRV_TOOLS_INSTALL)
install(TARGETS SPIRV-Tools-reduce EXPORT SPIRV-Tools-reduceTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
export(EXPORT SPIRV-Tools-reduceTargets FILE SPIRV-Tools-reduceTarget.cmake)
spvtools_config_package_dir(SPIRV-Tools-reduce PACKAGE_DIR)
install(EXPORT SPIRV-Tools-reduceTargets FILE SPIRV-Tools-reduceTarget.cmake
DESTINATION ${PACKAGE_DIR})
spvtools_generate_config_file(SPIRV-Tools-reduce)
install(FILES ${CMAKE_BINARY_DIR}/SPIRV-Tools-reduceConfig.cmake DESTINATION ${PACKAGE_DIR})
endif(ENABLE_SPIRV_TOOLS_INSTALL)

View File

@ -120,7 +120,7 @@ typedef enum VUIDError_ {
VUIDErrorMax,
} VUIDError;
const static uint32_t NumVUIDBuiltins = 29;
const static uint32_t NumVUIDBuiltins = 33;
typedef struct {
SpvBuiltIn builtIn;
@ -158,6 +158,10 @@ std::array<BuiltinVUIDMapping, NumVUIDBuiltins> builtinVUIDInfo = {{
{SpvBuiltInWorldRayOriginKHR, {4431, 4432, 4433}},
{SpvBuiltInLaunchIdKHR, {4266, 4267, 4268}},
{SpvBuiltInLaunchSizeKHR, {4269, 4270, 4271}},
{SpvBuiltInFragInvocationCountEXT, {4217, 4218, 4219}},
{SpvBuiltInFragSizeEXT, {4220, 4221, 4222}},
{SpvBuiltInFragStencilRefEXT, {4223, 4224, 4225}},
{SpvBuiltInFullyCoveredEXT, {4232, 4233, 4234}},
// clang-format off
} };
@ -314,6 +318,14 @@ class BuiltInsValidator {
const Instruction& inst);
spv_result_t ValidateDeviceIndexAtDefinition(const Decoration& decoration,
const Instruction& inst);
spv_result_t ValidateFragInvocationCountAtDefinition(const Decoration& decoration,
const Instruction& inst);
spv_result_t ValidateFragSizeAtDefinition(const Decoration& decoration,
const Instruction& inst);
spv_result_t ValidateFragStencilRefAtDefinition(const Decoration& decoration,
const Instruction& inst);
spv_result_t ValidateFullyCoveredAtDefinition(const Decoration& decoration,
const Instruction& inst);
// Used for GlobalInvocationId, LocalInvocationId, NumWorkgroups, WorkgroupId.
spv_result_t ValidateComputeShaderI32Vec3InputAtDefinition(
const Decoration& decoration, const Instruction& inst);
@ -472,6 +484,26 @@ class BuiltInsValidator {
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
spv_result_t ValidateFragInvocationCountAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
spv_result_t ValidateFragSizeAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
spv_result_t ValidateFragStencilRefAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
spv_result_t ValidateFullyCoveredAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
// Used for GlobalInvocationId, LocalInvocationId, NumWorkgroups, WorkgroupId.
spv_result_t ValidateComputeShaderI32Vec3InputAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
@ -525,6 +557,9 @@ class BuiltInsValidator {
spv_result_t ValidateBool(
const Decoration& decoration, const Instruction& inst,
const std::function<spv_result_t(const std::string& message)>& diag);
spv_result_t ValidateI(
const Decoration& decoration, const Instruction& inst,
const std::function<spv_result_t(const std::string& message)>& diag);
spv_result_t ValidateI32(
const Decoration& decoration, const Instruction& inst,
const std::function<spv_result_t(const std::string& message)>& diag);
@ -717,6 +752,22 @@ spv_result_t BuiltInsValidator::ValidateBool(
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateI(
const Decoration& decoration, const Instruction& inst,
const std::function<spv_result_t(const std::string& message)>& diag) {
uint32_t underlying_type = 0;
if (spv_result_t error =
GetUnderlyingType(_, decoration, inst, &underlying_type)) {
return error;
}
if (!_.IsIntScalarType(underlying_type)) {
return diag(GetDefinitionDesc(decoration, inst) + " is not an int scalar.");
}
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateI32(
const Decoration& decoration, const Instruction& inst,
const std::function<spv_result_t(const std::string& message)>& diag) {
@ -3296,6 +3347,287 @@ spv_result_t BuiltInsValidator::ValidateDeviceIndexAtReference(
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtDefinition(const Decoration& decoration,
const Instruction& inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
if (spv_result_t error = ValidateI32(
decoration, inst,
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
builtin)
<< " variable needs to be a 32-bit int scalar. "
<< message;
})) {
return error;
}
}
return ValidateFragInvocationCountAtReference(decoration, inst, inst, inst);
}
spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
if (storage_class != SpvStorageClassMax &&
storage_class != SpvStorageClassInput) {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " to be only used for variables with Input storage class. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst)
<< " " << GetStorageClassDesc(referenced_from_inst);
}
for (const SpvExecutionModel execution_model : execution_models_) {
if (execution_model != SpvExecutionModelFragment) {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid)
<< spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " to be used only with Fragment execution model. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
}
}
}
if (function_id_ == 0) {
// Propagate this rule to all dependant ids in the global scope.
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateFragInvocationCountAtReference, this, decoration,
built_in_inst, referenced_from_inst, std::placeholders::_1));
}
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateFragSizeAtDefinition(const Decoration& decoration,
const Instruction& inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
if (spv_result_t error = ValidateI32Vec(
decoration, inst, 2,
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
builtin)
<< " variable needs to be a 2-component 32-bit int vector. "
<< message;
})) {
return error;
}
}
return ValidateFragSizeAtReference(decoration, inst, inst, inst);
}
spv_result_t BuiltInsValidator::ValidateFragSizeAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
if (storage_class != SpvStorageClassMax &&
storage_class != SpvStorageClassInput) {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " to be only used for variables with Input storage class. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst)
<< " " << GetStorageClassDesc(referenced_from_inst);
}
for (const SpvExecutionModel execution_model : execution_models_) {
if (execution_model != SpvExecutionModelFragment) {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid)
<< spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " to be used only with Fragment execution model. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
}
}
}
if (function_id_ == 0) {
// Propagate this rule to all dependant ids in the global scope.
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateFragSizeAtReference, this, decoration,
built_in_inst, referenced_from_inst, std::placeholders::_1));
}
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateFragStencilRefAtDefinition(const Decoration& decoration,
const Instruction& inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
if (spv_result_t error = ValidateI(
decoration, inst,
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
builtin)
<< " variable needs to be a int scalar. "
<< message;
})) {
return error;
}
}
return ValidateFragStencilRefAtReference(decoration, inst, inst, inst);
}
spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
if (storage_class != SpvStorageClassMax &&
storage_class != SpvStorageClassOutput) {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " to be only used for variables with Output storage class. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst)
<< " " << GetStorageClassDesc(referenced_from_inst);
}
for (const SpvExecutionModel execution_model : execution_models_) {
if (execution_model != SpvExecutionModelFragment) {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid)
<< spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " to be used only with Fragment execution model. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
}
}
}
if (function_id_ == 0) {
// Propagate this rule to all dependant ids in the global scope.
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateFragStencilRefAtReference, this, decoration,
built_in_inst, referenced_from_inst, std::placeholders::_1));
}
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateFullyCoveredAtDefinition(const Decoration& decoration,
const Instruction& inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
if (spv_result_t error = ValidateBool(
decoration, inst,
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid) << "According to the "
<< spvLogStringForEnv(_.context()->target_env)
<< " spec BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
builtin)
<< " variable needs to be a bool scalar. "
<< message;
})) {
return error;
}
}
return ValidateFullyCoveredAtReference(decoration, inst, inst, inst);
}
spv_result_t BuiltInsValidator::ValidateFullyCoveredAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
if (storage_class != SpvStorageClassMax &&
storage_class != SpvStorageClassInput) {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " to be only used for variables with Input storage class. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst)
<< " " << GetStorageClassDesc(referenced_from_inst);
}
for (const SpvExecutionModel execution_model : execution_models_) {
if (execution_model != SpvExecutionModelFragment) {
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid)
<< spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " to be used only with Fragment execution model. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
}
}
}
if (function_id_ == 0) {
// Propagate this rule to all dependant ids in the global scope.
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateFullyCoveredAtReference, this, decoration,
built_in_inst, referenced_from_inst, std::placeholders::_1));
}
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateSMBuiltinsAtDefinition(
const Decoration& decoration, const Instruction& inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
@ -3793,6 +4125,20 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case SpvBuiltInDeviceIndex: {
return ValidateDeviceIndexAtDefinition(decoration, inst);
}
case SpvBuiltInFragInvocationCountEXT: {
// alias SpvBuiltInInvocationsPerPixelNV
return ValidateFragInvocationCountAtDefinition(decoration, inst);
}
case SpvBuiltInFragSizeEXT: {
// alias SpvBuiltInFragmentSizeNV
return ValidateFragSizeAtDefinition(decoration, inst);
}
case SpvBuiltInFragStencilRefEXT: {
return ValidateFragStencilRefAtDefinition(decoration, inst);
}
case SpvBuiltInFullyCoveredEXT:{
return ValidateFullyCoveredAtDefinition(decoration, inst);
}
// Ray tracing builtins
case SpvBuiltInHitKindKHR: // alias SpvBuiltInHitKindNV
case SpvBuiltInHitTNV: // NOT present in KHR
@ -3828,13 +4174,11 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case SpvBuiltInBaryCoordSmoothCentroidAMD:
case SpvBuiltInBaryCoordSmoothSampleAMD:
case SpvBuiltInBaryCoordPullModelAMD:
case SpvBuiltInFragStencilRefEXT:
case SpvBuiltInViewportMaskNV:
case SpvBuiltInSecondaryPositionNV:
case SpvBuiltInSecondaryViewportMaskNV:
case SpvBuiltInPositionPerViewNV:
case SpvBuiltInViewportMaskPerViewNV:
case SpvBuiltInFullyCoveredEXT:
case SpvBuiltInMax:
case SpvBuiltInTaskCountNV:
case SpvBuiltInPrimitiveCountNV:
@ -3846,9 +4190,6 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case SpvBuiltInMeshViewIndicesNV:
case SpvBuiltInBaryCoordNV:
case SpvBuiltInBaryCoordNoPerspNV:
case SpvBuiltInFragmentSizeNV: // alias SpvBuiltInFragSizeEXT
case SpvBuiltInInvocationsPerPixelNV: // alias
// SpvBuiltInFragInvocationCountEXT
// No validation rules (for the moment).
break;

View File

@ -285,6 +285,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
mask & (SpvImageOperandsOffsetMask | SpvImageOperandsConstOffsetMask |
SpvImageOperandsConstOffsetsMask)) > 1) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4662)
<< "Image Operands Offset, ConstOffset, ConstOffsets cannot be used "
<< "together";
}
@ -877,6 +878,20 @@ spv_result_t ValidateTypeSampledImage(ValidationState_t& _,
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Image to be of type OpTypeImage";
}
ImageTypeInfo info;
if (!GetImageTypeInfo(_, image_type, &info)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Corrupt image type definition";
}
// OpenCL requires Sampled=0, checked elsewhere.
// Vulkan uses the Sampled=1 case.
if ((info.sampled != 0) && (info.sampled != 1)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Sampled image type requires an image type with \"Sampled\" "
"operand set to 0 or 1";
}
return SPV_SUCCESS;
}
@ -1728,6 +1743,16 @@ spv_result_t ValidateImageQuerySizeLod(ValidationState_t& _,
return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'MS' must be 0";
}
const auto target_env = _.context()->target_env;
if (spvIsVulkanEnv(target_env)) {
if (info.sampled != 1) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4659)
<< "OpImageQuerySizeLod must only consume an \"Image\" operand "
"whose type has its \"Sampled\" operand set to 1";
}
}
uint32_t result_num_components = _.GetDimension(result_type);
if (result_num_components != expected_num_components) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
@ -1902,6 +1927,13 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _,
<< "Expected Coordinate to have at least " << min_coord_size
<< " components, but given only " << actual_coord_size;
}
// The operad is a sampled image.
// The sampled image type is already checked to be parameterized by an image
// type with Sampled=0 or Sampled=1. Vulkan bans Sampled=0, and so we have
// Sampled=1. So the validator already enforces Vulkan VUID 4659:
// OpImageQuerySizeLod must only consume an “Image” operand whose type has
// its "Sampled" operand set to 1
return SPV_SUCCESS;
}
@ -1938,6 +1970,15 @@ spv_result_t ValidateImageQueryLevelsOrSamples(ValidationState_t& _,
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Image 'Dim' must be 1D, 2D, 3D or Cube";
}
const auto target_env = _.context()->target_env;
if (spvIsVulkanEnv(target_env)) {
if (info.sampled != 1) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4659)
<< "OpImageQueryLevels must only consume an \"Image\" operand "
"whose type has its \"Sampled\" operand set to 1";
}
}
} else {
assert(opcode == SpvOpImageQuerySamples);
if (info.dim != SpvDim2D) {

View File

@ -172,7 +172,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _,
if (opcode == SpvOpMemoryBarrier && !num_memory_order_set_bits) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4649) << spvOpcodeString(opcode)
<< _.VkErrorID(4732) << spvOpcodeString(opcode)
<< ": Vulkan specification requires Memory Semantics to have "
"one "
"of the following bits set: Acquire, Release, "
@ -182,7 +182,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _,
if (opcode == SpvOpMemoryBarrier && !includes_storage_class) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4649) << spvOpcodeString(opcode)
<< _.VkErrorID(4733) << spvOpcodeString(opcode)
<< ": expected Memory Semantics to include a Vulkan-supported "
"storage class";
}
@ -223,6 +223,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _,
value & SpvMemorySemanticsAcquireReleaseMask ||
value & SpvMemorySemanticsSequentiallyConsistentMask)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4731)
<< "Vulkan spec disallows OpAtomicLoad with Memory Semantics "
"Release, AcquireRelease and SequentiallyConsistent";
}
@ -232,6 +233,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _,
value & SpvMemorySemanticsAcquireReleaseMask ||
value & SpvMemorySemanticsSequentiallyConsistentMask)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4730)
<< "Vulkan spec disallows OpAtomicStore with Memory Semantics "
"Acquire, AcquireRelease and SequentiallyConsistent";
}

View File

@ -228,6 +228,7 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) {
}
if (!ok) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4683)
<< "In the Vulkan environment, GLCompute execution model "
"entry points require either the LocalSize execution "
"mode or an object decorated with WorkgroupSize must be "

View File

@ -190,7 +190,7 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst,
if (spvIsVulkanEnv(_.context()->target_env)) {
if (value == SpvScopeCrossDevice) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
<< _.VkErrorID(4638) << spvOpcodeString(opcode)
<< ": in Vulkan environment, Memory Scope cannot be CrossDevice";
}
// Vulkan 1.0 specifc rules
@ -198,7 +198,7 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst,
value != SpvScopeDevice && value != SpvScopeWorkgroup &&
value != SpvScopeInvocation) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
<< _.VkErrorID(4638) << spvOpcodeString(opcode)
<< ": in Vulkan 1.0 environment Memory Scope is limited to "
<< "Device, Workgroup and Invocation";
}
@ -209,15 +209,16 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst,
value != SpvScopeSubgroup && value != SpvScopeInvocation &&
value != SpvScopeShaderCallKHR) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
<< _.VkErrorID(4638) << spvOpcodeString(opcode)
<< ": in Vulkan 1.1 and 1.2 environment Memory Scope is limited "
<< "to Device, Workgroup, Invocation, and ShaderCall";
}
if (value == SpvScopeShaderCallKHR) {
std::string errorVUID = _.VkErrorID(4640);
_.function(inst->function()->id())
->RegisterExecutionModelLimitation(
[](SpvExecutionModel model, std::string* message) {
[errorVUID](SpvExecutionModel model, std::string* message) {
if (model != SpvExecutionModelRayGenerationKHR &&
model != SpvExecutionModelIntersectionKHR &&
model != SpvExecutionModelAnyHitKHR &&
@ -226,6 +227,7 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst,
model != SpvExecutionModelCallableKHR) {
if (message) {
*message =
errorVUID +
"ShaderCallKHR Memory Scope requires a ray tracing "
"execution model";
}
@ -234,6 +236,25 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst,
return true;
});
}
if (value == SpvScopeWorkgroup) {
std::string errorVUID = _.VkErrorID(4639);
_.function(inst->function()->id())
->RegisterExecutionModelLimitation(
[errorVUID](SpvExecutionModel model, std::string* message) {
if (model != SpvExecutionModelGLCompute &&
model != SpvExecutionModelTaskNV &&
model != SpvExecutionModelMeshNV) {
if (message) {
*message = errorVUID +
"Workgroup Memory Scope is limited to MeshNV, "
"TaskNV, and GLCompute execution model";
}
return false;
}
return true;
});
}
}
// TODO(atgoo@github.com) Add checks for OpenCL and OpenGL environments.

View File

@ -1340,12 +1340,36 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-FragDepth-FragDepth-04215);
case 4216:
return VUID_WRAP(VUID-FragDepth-FragDepth-04216);
case 4217:
return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04217);
case 4218:
return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04218);
case 4219:
return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04219);
case 4220:
return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04220);
case 4221:
return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04221);
case 4222:
return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04222);
case 4223:
return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04223);
case 4224:
return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04224);
case 4225:
return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04225);
case 4229:
return VUID_WRAP(VUID-FrontFacing-FrontFacing-04229);
case 4230:
return VUID_WRAP(VUID-FrontFacing-FrontFacing-04230);
case 4231:
return VUID_WRAP(VUID-FrontFacing-FrontFacing-04231);
case 4232:
return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04232);
case 4233:
return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04233);
case 4234:
return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04234);
case 4236:
return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04236);
case 4237:
@ -1652,10 +1676,14 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-None-04633);
case 4635:
return VUID_WRAP(VUID-StandaloneSpirv-None-04635);
case 4638:
return VUID_WRAP(VUID-StandaloneSpirv-None-04638);
case 4639:
return VUID_WRAP(VUID-StandaloneSpirv-None-04639);
case 4640:
return VUID_WRAP(VUID-StandaloneSpirv-None-04640);
case 4642:
return VUID_WRAP(VUID-StandaloneSpirv-None-04642);
case 4649:
return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04649);
case 4651:
return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04651);
case 4652:
@ -1670,16 +1698,28 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04657);
case 4658:
return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658);
case 4662:
return VUID_WRAP(VUID-StandaloneSpirv-Offset-04662);
case 4669:
return VUID_WRAP(VUID-StandaloneSpirv-GLSLShared-04669);
case 4675:
return VUID_WRAP(VUID-StandaloneSpirv-FPRoundingMode-04675);
case 4683:
return VUID_WRAP(VUID-StandaloneSpirv-LocalSize-04683);
case 4685:
return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685);
case 4686:
return VUID_WRAP(VUID-StandaloneSpirv-None-04686);
case 4711:
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeForwardPointer-04711);
case 4730:
return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicStore-04730);
case 4731:
return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicLoad-04731);
case 4732:
return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04732);
case 4733:
return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733);
default:
return ""; // unknown id
};

View File

@ -1,39 +0,0 @@
#!/bin/bash
# Copyright (c) 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Script to determine if source code in Pull Request is properly formatted.
# Exits with non 0 exit code if formatting is needed.
#
# This script assumes to be invoked at the project root directory.
BASE_BRANCH=${1:-master}
FILES_TO_CHECK=$(git diff --name-only ${BASE_BRANCH} | grep -E ".*\.(cpp|cc|c\+\+|cxx|c|h|hpp)$")
if [ -z "${FILES_TO_CHECK}" ]; then
echo "No source code to check for formatting."
exit 0
fi
FORMAT_DIFF=$(git diff -U0 ${BASE_BRANCH} -- ${FILES_TO_CHECK} | python ./utils/clang-format-diff.py -p1 -style=file)
if [ -z "${FORMAT_DIFF}" ]; then
echo "All source code in PR properly formatted."
exit 0
else
echo "Found formatting errors!"
echo "${FORMAT_DIFF}"
exit 1
fi

View File

@ -1,227 +0,0 @@
#!/usr/bin/env python
# coding=utf-8
# Copyright (c) 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Checks for copyright notices in all the files that need them under the
current directory. Optionally insert them. When inserting, replaces
an MIT or Khronos free use license with Apache 2.
"""
import argparse
import fileinput
import fnmatch
import inspect
import os
import re
import sys
# List of designated copyright owners.
AUTHORS = ['The Khronos Group Inc.',
'LunarG Inc.',
'Google Inc.',
'Google LLC',
'Pierre Moreau',
'Samsung Inc',
'André Perez Maselco',
'Vasyl Teliman',
'Advanced Micro Devices, Inc.',
'Stefano Milizia']
CURRENT_YEAR='2020'
YEARS = '(2014-2016|2015-2016|2015-2020|2016|2016-2017|2017|2017-2019|2018|2019|2020)'
COPYRIGHT_RE = re.compile(
'Copyright \(c\) {} ({})'.format(YEARS, '|'.join(AUTHORS)))
MIT_BEGIN_RE = re.compile('Permission is hereby granted, '
'free of charge, to any person obtaining a')
MIT_END_RE = re.compile('MATERIALS OR THE USE OR OTHER DEALINGS IN '
'THE MATERIALS.')
APACHE2_BEGIN_RE = re.compile('Licensed under the Apache License, '
'Version 2.0 \(the "License"\);')
APACHE2_END_RE = re.compile('limitations under the License.')
LICENSED = """Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License."""
LICENSED_LEN = 10 # Number of lines in LICENSED
def find(top, filename_glob, skip_glob_dir_list, skip_glob_files_list):
"""Returns files in the tree rooted at top matching filename_glob but not
in directories matching skip_glob_dir_list nor files matching
skip_glob_dir_list."""
file_list = []
for path, dirs, files in os.walk(top):
for glob in skip_glob_dir_list:
for match in fnmatch.filter(dirs, glob):
dirs.remove(match)
for filename in fnmatch.filter(files, filename_glob):
full_file = os.path.join(path, filename)
if full_file not in skip_glob_files_list:
file_list.append(full_file)
return file_list
def filtered_descendants(glob):
"""Returns glob-matching filenames under the current directory, but skips
some irrelevant paths."""
return find('.', glob, ['third_party', 'external', 'CompilerIdCXX',
'build*', 'out*'], ['./utils/clang-format-diff.py'])
def skip(line):
"""Returns true if line is all whitespace or shebang."""
stripped = line.lstrip()
return stripped == '' or stripped.startswith('#!')
def comment(text, prefix):
"""Returns commented-out text.
Each line of text will be prefixed by prefix and a space character. Any
trailing whitespace will be trimmed.
"""
accum = ['{} {}'.format(prefix, line).rstrip() for line in text.split('\n')]
return '\n'.join(accum)
def insert_copyright(author, glob, comment_prefix):
"""Finds all glob-matching files under the current directory and inserts the
copyright message, and license notice. An MIT license or Khronos free
use license (modified MIT) is replaced with an Apache 2 license.
The copyright message goes into the first non-whitespace, non-shebang line
in a file. The license notice follows it. Both are prefixed on each line
by comment_prefix and a space.
"""
copyright = comment('Copyright (c) {} {}'.format(CURRENT_YEAR, author),
comment_prefix) + '\n\n'
licensed = comment(LICENSED, comment_prefix) + '\n\n'
for file in filtered_descendants(glob):
# Parsing states are:
# 0 Initial: Have not seen a copyright declaration.
# 1 Seen a copyright line and no other interesting lines
# 2 In the middle of an MIT or Khronos free use license
# 9 Exited any of the above
state = 0
update_file = False
for line in fileinput.input(file, inplace=1):
emit = True
if state is 0:
if COPYRIGHT_RE.search(line):
state = 1
elif skip(line):
pass
else:
# Didn't see a copyright. Inject copyright and license.
sys.stdout.write(copyright)
sys.stdout.write(licensed)
# Assume there isn't a previous license notice.
state = 1
elif state is 1:
if MIT_BEGIN_RE.search(line):
state = 2
emit = False
elif APACHE2_BEGIN_RE.search(line):
# Assume an Apache license is preceded by a copyright
# notice. So just emit it like the rest of the file.
state = 9
elif state is 2:
# Replace the MIT license with Apache 2
emit = False
if MIT_END_RE.search(line):
state = 9
sys.stdout.write(licensed)
if emit:
sys.stdout.write(line)
def alert_if_no_copyright(glob, comment_prefix):
"""Prints names of all files missing either a copyright or Apache 2 license.
Finds all glob-matching files under the current directory and checks if they
contain the copyright message and license notice. Prints the names of all the
files that don't meet both criteria.
Returns the total number of file names printed.
"""
printed_count = 0
for file in filtered_descendants(glob):
has_copyright = False
has_apache2 = False
line_num = 0
apache_expected_end = 0
with open(file, encoding='utf-8') as contents:
for line in contents:
line_num += 1
if COPYRIGHT_RE.search(line):
has_copyright = True
if APACHE2_BEGIN_RE.search(line):
apache_expected_end = line_num + LICENSED_LEN
if (line_num is apache_expected_end) and APACHE2_END_RE.search(line):
has_apache2 = True
if not (has_copyright and has_apache2):
message = file
if not has_copyright:
message += ' has no copyright'
if not has_apache2:
message += ' has no Apache 2 license notice'
print(message)
printed_count += 1
return printed_count
class ArgParser(argparse.ArgumentParser):
def __init__(self):
super(ArgParser, self).__init__(
description=inspect.getdoc(sys.modules[__name__]))
self.add_argument('--update', dest='author', action='store',
help='For files missing a copyright notice, insert '
'one for the given author, and add a license '
'notice. The author must be in the AUTHORS '
'list in the script.')
def main():
glob_comment_pairs = [('*.h', '//'), ('*.hpp', '//'), ('*.sh', '#'),
('*.py', '#'), ('*.cpp', '//'),
('CMakeLists.txt', '#')]
argparser = ArgParser()
args = argparser.parse_args()
if args.author:
if args.author not in AUTHORS:
print('error: --update argument must be in the AUTHORS list in '
'check_copyright.py: {}'.format(AUTHORS))
sys.exit(1)
for pair in glob_comment_pairs:
insert_copyright(args.author, *pair)
sys.exit(0)
else:
count = sum([alert_if_no_copyright(*p) for p in glob_comment_pairs])
sys.exit(count > 0)
if __name__ == '__main__':
main()

View File

@ -1,98 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Checks names of global exports from a library."""
import os.path
import re
import subprocess
import sys
PROG = 'check_symbol_exports'
def command_output(cmd, directory):
"""Runs a command in a directory and returns its standard output stream.
Captures the standard error stream.
Raises a RuntimeError if the command fails to launch or otherwise fails.
"""
p = subprocess.Popen(cmd,
cwd=directory,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
(stdout, _) = p.communicate()
if p.returncode != 0:
raise RuntimeError('Failed to run %s in %s' % (cmd, directory))
return stdout
def check_library(library):
"""Scans the given library file for global exports. If all such
exports are namespaced or begin with spv (in either C or C++ styles)
then return 0. Otherwise emit a message and return 1."""
# The pattern for a global symbol record
symbol_pattern = re.compile(r'^[0-aA-Fa-f]+ g *F \.text.*[0-9A-Fa-f]+ +(.*)')
# Ok patterns are as follows, assuming Itanium name mangling:
# spv[A-Z] : extern "C" symbol starting with spv
# _ZN : something in a namespace
# _Z[0-9]+spv[A-Z_] : C++ symbol starting with spv[A-Z_]
symbol_ok_pattern = re.compile(r'^(spv[A-Z]|_ZN|_Z[0-9]+spv[A-Z_])')
# In addition, the following pattern allowlists global functions that are added
# by the protobuf compiler:
# - AddDescriptors_spvtoolsfuzz_2eproto()
# - InitDefaults_spvtoolsfuzz_2eproto()
symbol_allowlist_pattern = re.compile(r'_Z[0-9]+(InitDefaults|AddDescriptors)_spvtoolsfuzz_2eprotov')
seen = set()
result = 0
for line in command_output(['objdump', '-t', library], '.').split('\n'):
match = symbol_pattern.search(line)
if match:
symbol = match.group(1)
if symbol not in seen:
seen.add(symbol)
#print("look at '{}'".format(symbol))
if not (symbol_allowlist_pattern.match(symbol) or symbol_ok_pattern.match(symbol)):
print('{}: error: Unescaped exported symbol: {}'.format(PROG, symbol))
result = 1
return result
def main():
import argparse
parser = argparse.ArgumentParser(description='Check global names exported from a library')
parser.add_argument('library', help='The static library to examine')
args = parser.parse_args()
if not os.path.isfile(args.library):
print('{}: error: {} does not exist'.format(PROG, args.library))
sys.exit(1)
if os.name == 'posix':
status = check_library(args.library)
sys.exit(status)
else:
print('Passing test since not on Posix')
sys.exit(0)
if __name__ == '__main__':
main()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
if len(sys.argv) < 1:
print("Need file to chop");
with open(sys.argv[1], mode='rb') as file:
file_content = file.read()
content = file_content[:len(file_content) - (len(file_content) % 4)]
sys.stdout.write(content)

View File

@ -1,874 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2016 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generates various info tables from SPIR-V JSON grammar."""
import errno
import json
import os.path
import re
# Prefix for all C variables generated by this script.
PYGEN_VARIABLE_PREFIX = 'pygen_variable'
# Extensions to recognize, but which don't necessarily come from the SPIR-V
# core or KHR grammar files. Get this list from the SPIR-V registery web page.
# NOTE: Only put things on this list if it is not in those grammar files.
EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS = """
SPV_AMD_gcn_shader
SPV_AMD_gpu_shader_half_float
SPV_AMD_gpu_shader_int16
SPV_AMD_shader_trinary_minmax
SPV_KHR_non_semantic_info
"""
def make_path_to_file(f):
"""Makes all ancestor directories to the given file, if they don't yet
exist.
Arguments:
f: The file whose ancestor directories are to be created.
"""
dir = os.path.dirname(os.path.abspath(f))
try:
os.makedirs(dir)
except OSError as e:
if e.errno == errno.EEXIST and os.path.isdir(dir):
pass
else:
raise
def convert_min_required_version(version):
"""Converts the minimal required SPIR-V version encoded in the grammar to
the symbol in SPIRV-Tools."""
if version is None:
return 'SPV_SPIRV_VERSION_WORD(1, 0)'
if version == 'None':
return '0xffffffffu'
return 'SPV_SPIRV_VERSION_WORD({})'.format(version.replace('.', ','))
def convert_max_required_version(version):
"""Converts the maximum required SPIR-V version encoded in the grammar to
the symbol in SPIRV-Tools."""
if version is None:
return '0xffffffffu'
return 'SPV_SPIRV_VERSION_WORD({})'.format(version.replace('.', ','))
def compose_capability_list(caps):
"""Returns a string containing a braced list of capabilities as enums.
Arguments:
- caps: a sequence of capability names
Returns:
a string containing the braced list of SpvCapability* enums named by caps.
"""
return '{' + ', '.join(['SpvCapability{}'.format(c) for c in caps]) + '}'
def get_capability_array_name(caps):
"""Returns the name of the array containing all the given capabilities.
Args:
- caps: a sequence of capability names
"""
if not caps:
return 'nullptr'
return '{}_caps_{}'.format(PYGEN_VARIABLE_PREFIX, ''.join(caps))
def generate_capability_arrays(caps):
"""Returns the arrays of capabilities.
Arguments:
- caps: a sequence of sequence of capability names
"""
caps = sorted(set([tuple(c) for c in caps if c]))
arrays = [
'static const SpvCapability {}[] = {};'.format(
get_capability_array_name(c), compose_capability_list(c))
for c in caps]
return '\n'.join(arrays)
def compose_extension_list(exts):
"""Returns a string containing a braced list of extensions as enums.
Arguments:
- exts: a sequence of extension names
Returns:
a string containing the braced list of extensions named by exts.
"""
return '{' + ', '.join(
['spvtools::Extension::k{}'.format(e) for e in exts]) + '}'
def get_extension_array_name(extensions):
"""Returns the name of the array containing all the given extensions.
Args:
- extensions: a sequence of extension names
"""
if not extensions:
return 'nullptr'
else:
return '{}_exts_{}'.format(
PYGEN_VARIABLE_PREFIX, ''.join(extensions))
def generate_extension_arrays(extensions):
"""Returns the arrays of extensions.
Arguments:
- caps: a sequence of sequence of extension names
"""
extensions = sorted(set([tuple(e) for e in extensions if e]))
arrays = [
'static const spvtools::Extension {}[] = {};'.format(
get_extension_array_name(e), compose_extension_list(e))
for e in extensions]
return '\n'.join(arrays)
def convert_operand_kind(operand_tuple):
"""Returns the corresponding operand type used in spirv-tools for the given
operand kind and quantifier used in the JSON grammar.
Arguments:
- operand_tuple: a tuple of two elements:
- operand kind: used in the JSON grammar
- quantifier: '', '?', or '*'
Returns:
a string of the enumerant name in spv_operand_type_t
"""
kind, quantifier = operand_tuple
# The following cases are where we differ between the JSON grammar and
# spirv-tools.
if kind == 'IdResultType':
kind = 'TypeId'
elif kind == 'IdResult':
kind = 'ResultId'
elif kind == 'IdMemorySemantics' or kind == 'MemorySemantics':
kind = 'MemorySemanticsId'
elif kind == 'IdScope' or kind == 'Scope':
kind = 'ScopeId'
elif kind == 'IdRef':
kind = 'Id'
elif kind == 'ImageOperands':
kind = 'Image'
elif kind == 'Dim':
kind = 'Dimensionality'
elif kind == 'ImageFormat':
kind = 'SamplerImageFormat'
elif kind == 'KernelEnqueueFlags':
kind = 'KernelEnqFlags'
elif kind == 'LiteralExtInstInteger':
kind = 'ExtensionInstructionNumber'
elif kind == 'LiteralSpecConstantOpInteger':
kind = 'SpecConstantOpNumber'
elif kind == 'LiteralContextDependentNumber':
kind = 'TypedLiteralNumber'
elif kind == 'PairLiteralIntegerIdRef':
kind = 'LiteralIntegerId'
elif kind == 'PairIdRefLiteralInteger':
kind = 'IdLiteralInteger'
elif kind == 'PairIdRefIdRef': # Used by OpPhi in the grammar
kind = 'Id'
if kind == 'FPRoundingMode':
kind = 'FpRoundingMode'
elif kind == 'FPFastMathMode':
kind = 'FpFastMathMode'
if quantifier == '?':
kind = 'Optional{}'.format(kind)
elif quantifier == '*':
kind = 'Variable{}'.format(kind)
return 'SPV_OPERAND_TYPE_{}'.format(
re.sub(r'([a-z])([A-Z])', r'\1_\2', kind).upper())
class InstInitializer(object):
"""Instances holds a SPIR-V instruction suitable for printing as the
initializer for spv_opcode_desc_t."""
def __init__(self, opname, caps, exts, operands, version, lastVersion):
"""Initialization.
Arguments:
- opname: opcode name (with the 'Op' prefix)
- caps: a sequence of capability names required by this opcode
- exts: a sequence of names of extensions enabling this enumerant
- operands: a sequence of (operand-kind, operand-quantifier) tuples
- version: minimal SPIR-V version required for this opcode
- lastVersion: last version of SPIR-V that includes this opcode
"""
assert opname.startswith('Op')
self.opname = opname[2:] # Remove the "Op" prefix.
self.num_caps = len(caps)
self.caps_mask = get_capability_array_name(caps)
self.num_exts = len(exts)
self.exts = get_extension_array_name(exts)
self.operands = [convert_operand_kind(o) for o in operands]
self.fix_syntax()
operands = [o[0] for o in operands]
self.ref_type_id = 'IdResultType' in operands
self.def_result_id = 'IdResult' in operands
self.version = convert_min_required_version(version)
self.lastVersion = convert_max_required_version(lastVersion)
def fix_syntax(self):
"""Fix an instruction's syntax, adjusting for differences between the
officially released grammar and how SPIRV-Tools uses the grammar.
Fixes:
- ExtInst should not end with SPV_OPERAND_VARIABLE_ID.
https://github.com/KhronosGroup/SPIRV-Tools/issues/233
"""
if (self.opname == 'ExtInst'
and self.operands[-1] == 'SPV_OPERAND_TYPE_VARIABLE_ID'):
self.operands.pop()
def __str__(self):
template = ['{{"{opname}"', 'SpvOp{opname}',
'{num_caps}', '{caps_mask}',
'{num_operands}', '{{{operands}}}',
'{def_result_id}', '{ref_type_id}',
'{num_exts}', '{exts}',
'{min_version}', '{max_version}}}']
return ', '.join(template).format(
opname=self.opname,
num_caps=self.num_caps,
caps_mask=self.caps_mask,
num_operands=len(self.operands),
operands=', '.join(self.operands),
def_result_id=(1 if self.def_result_id else 0),
ref_type_id=(1 if self.ref_type_id else 0),
num_exts=self.num_exts,
exts=self.exts,
min_version=self.version,
max_version=self.lastVersion)
class ExtInstInitializer(object):
"""Instances holds a SPIR-V extended instruction suitable for printing as
the initializer for spv_ext_inst_desc_t."""
def __init__(self, opname, opcode, caps, operands):
"""Initialization.
Arguments:
- opname: opcode name
- opcode: enumerant value for this opcode
- caps: a sequence of capability names required by this opcode
- operands: a sequence of (operand-kind, operand-quantifier) tuples
"""
self.opname = opname
self.opcode = opcode
self.num_caps = len(caps)
self.caps_mask = get_capability_array_name(caps)
self.operands = [convert_operand_kind(o) for o in operands]
self.operands.append('SPV_OPERAND_TYPE_NONE')
def __str__(self):
template = ['{{"{opname}"', '{opcode}', '{num_caps}', '{caps_mask}',
'{{{operands}}}}}']
return ', '.join(template).format(
opname=self.opname,
opcode=self.opcode,
num_caps=self.num_caps,
caps_mask=self.caps_mask,
operands=', '.join(self.operands))
def generate_instruction(inst, is_ext_inst):
"""Returns the C initializer for the given SPIR-V instruction.
Arguments:
- inst: a dict containing information about a SPIR-V instruction
- is_ext_inst: a bool indicating whether |inst| is an extended
instruction.
Returns:
a string containing the C initializer for spv_opcode_desc_t or
spv_ext_inst_desc_t
"""
opname = inst.get('opname')
opcode = inst.get('opcode')
caps = inst.get('capabilities', [])
exts = inst.get('extensions', [])
operands = inst.get('operands', {})
operands = [(o['kind'], o.get('quantifier', '')) for o in operands]
min_version = inst.get('version', None)
max_version = inst.get('lastVersion', None)
assert opname is not None
if is_ext_inst:
return str(ExtInstInitializer(opname, opcode, caps, operands))
else:
return str(InstInitializer(opname, caps, exts, operands, min_version, max_version))
def generate_instruction_table(inst_table):
"""Returns the info table containing all SPIR-V instructions, sorted by
opcode, and prefixed by capability arrays.
Note:
- the built-in sorted() function is guaranteed to be stable.
https://docs.python.org/3/library/functions.html#sorted
Arguments:
- inst_table: a list containing all SPIR-V instructions.
"""
inst_table = sorted(inst_table, key=lambda k: (k['opcode'], k['opname']))
caps_arrays = generate_capability_arrays(
[inst.get('capabilities', []) for inst in inst_table])
exts_arrays = generate_extension_arrays(
[inst.get('extensions', []) for inst in inst_table])
insts = [generate_instruction(inst, False) for inst in inst_table]
insts = ['static const spv_opcode_desc_t kOpcodeTableEntries[] = {{\n'
' {}\n}};'.format(',\n '.join(insts))]
return '{}\n\n{}\n\n{}'.format(caps_arrays, exts_arrays, '\n'.join(insts))
def generate_extended_instruction_table(json_grammar, set_name, operand_kind_prefix=""):
"""Returns the info table containing all SPIR-V extended instructions,
sorted by opcode, and prefixed by capability arrays.
Arguments:
- inst_table: a list containing all SPIR-V instructions.
- set_name: the name of the extended instruction set.
- operand_kind_prefix: the prefix, if any, to add to the front
of operand kind names.
"""
if operand_kind_prefix:
prefix_operand_kind_names(operand_kind_prefix, json_grammar)
inst_table = json_grammar["instructions"]
set_name = set_name.replace(".", "_")
inst_table = sorted(inst_table, key=lambda k: k['opcode'])
caps = [inst.get('capabilities', []) for inst in inst_table]
caps_arrays = generate_capability_arrays(caps)
insts = [generate_instruction(inst, True) for inst in inst_table]
insts = ['static const spv_ext_inst_desc_t {}_entries[] = {{\n'
' {}\n}};'.format(set_name, ',\n '.join(insts))]
return '{}\n\n{}'.format(caps_arrays, '\n'.join(insts))
class EnumerantInitializer(object):
"""Prints an enumerant as the initializer for spv_operand_desc_t."""
def __init__(self, enumerant, value, caps, exts, parameters, version, lastVersion):
"""Initialization.
Arguments:
- enumerant: enumerant name
- value: enumerant value
- caps: a sequence of capability names required by this enumerant
- exts: a sequence of names of extensions enabling this enumerant
- parameters: a sequence of (operand-kind, operand-quantifier) tuples
- version: minimal SPIR-V version required for this opcode
- lastVersion: last SPIR-V version this opode appears
"""
self.enumerant = enumerant
self.value = value
self.num_caps = len(caps)
self.caps = get_capability_array_name(caps)
self.num_exts = len(exts)
self.exts = get_extension_array_name(exts)
self.parameters = [convert_operand_kind(p) for p in parameters]
self.version = convert_min_required_version(version)
self.lastVersion = convert_max_required_version(lastVersion)
def __str__(self):
template = ['{{"{enumerant}"', '{value}', '{num_caps}',
'{caps}', '{num_exts}', '{exts}',
'{{{parameters}}}', '{min_version}',
'{max_version}}}']
return ', '.join(template).format(
enumerant=self.enumerant,
value=self.value,
num_caps=self.num_caps,
caps=self.caps,
num_exts=self.num_exts,
exts=self.exts,
parameters=', '.join(self.parameters),
min_version=self.version,
max_version=self.lastVersion)
def generate_enum_operand_kind_entry(entry, extension_map):
"""Returns the C initializer for the given operand enum entry.
Arguments:
- entry: a dict containing information about an enum entry
- extension_map: a dict mapping enum value to list of extensions
Returns:
a string containing the C initializer for spv_operand_desc_t
"""
enumerant = entry.get('enumerant')
value = entry.get('value')
caps = entry.get('capabilities', [])
if value in extension_map:
exts = extension_map[value]
else:
exts = []
params = entry.get('parameters', [])
params = [p.get('kind') for p in params]
params = zip(params, [''] * len(params))
version = entry.get('version', None)
max_version = entry.get('lastVersion', None)
assert enumerant is not None
assert value is not None
return str(EnumerantInitializer(
enumerant, value, caps, exts, params, version, max_version))
def generate_enum_operand_kind(enum, synthetic_exts_list):
"""Returns the C definition for the given operand kind.
It's a static const named array of spv_operand_desc_t.
Also appends to |synthetic_exts_list| a list of extension lists
used.
"""
kind = enum.get('kind')
assert kind is not None
# Sort all enumerants according to their values, but otherwise
# preserve their order so the first name listed in the grammar
# as the preferred name for disassembly.
if enum.get('category') == 'ValueEnum':
def functor(k): return (k['value'])
else:
def functor(k): return (int(k['value'], 16))
entries = sorted(enum.get('enumerants', []), key=functor)
# SubgroupEqMask and SubgroupEqMaskKHR are the same number with
# same semantics, but one has no extension list while the other
# does. Both should have the extension list.
# So create a mapping from enum value to the union of the extensions
# across all those grammar entries. Preserve order.
extension_map = {}
for e in entries:
value = e.get('value')
extension_map[value] = []
for e in entries:
value = e.get('value')
exts = e.get('extensions', [])
for ext in exts:
if ext not in extension_map[value]:
extension_map[value].append(ext)
synthetic_exts_list.extend(extension_map.values())
name = '{}_{}Entries'.format(PYGEN_VARIABLE_PREFIX, kind)
entries = [' {}'.format(generate_enum_operand_kind_entry(e, extension_map))
for e in entries]
template = ['static const spv_operand_desc_t {name}[] = {{',
'{entries}', '}};']
entries = '\n'.join(template).format(
name=name,
entries=',\n'.join(entries))
return kind, name, entries
def generate_operand_kind_table(enums):
"""Returns the info table containing all SPIR-V operand kinds."""
# We only need to output info tables for those operand kinds that are enums.
enums = [e for e in enums if e.get('category') in ['ValueEnum', 'BitEnum']]
caps = [entry.get('capabilities', [])
for enum in enums
for entry in enum.get('enumerants', [])]
caps_arrays = generate_capability_arrays(caps)
exts = [entry.get('extensions', [])
for enum in enums
for entry in enum.get('enumerants', [])]
enums = [generate_enum_operand_kind(e, exts) for e in enums]
exts_arrays = generate_extension_arrays(exts)
# We have three operand kinds that requires their optional counterpart to
# exist in the operand info table.
three_optional_enums = ['ImageOperands', 'AccessQualifier', 'MemoryAccess']
three_optional_enums = [e for e in enums if e[0] in three_optional_enums]
enums.extend(three_optional_enums)
enum_kinds, enum_names, enum_entries = zip(*enums)
# Mark the last three as optional ones.
enum_quantifiers = [''] * (len(enums) - 3) + ['?'] * 3
# And we don't want redefinition of them.
enum_entries = enum_entries[:-3]
enum_kinds = [convert_operand_kind(e)
for e in zip(enum_kinds, enum_quantifiers)]
table_entries = zip(enum_kinds, enum_names, enum_names)
table_entries = [' {{{}, ARRAY_SIZE({}), {}}}'.format(*e)
for e in table_entries]
template = [
'static const spv_operand_desc_group_t {p}_OperandInfoTable[] = {{',
'{enums}', '}};']
table = '\n'.join(template).format(
p=PYGEN_VARIABLE_PREFIX, enums=',\n'.join(table_entries))
return '\n\n'.join((caps_arrays,) + (exts_arrays,) + enum_entries + (table,))
def get_extension_list(instructions, operand_kinds):
"""Returns extensions as an alphabetically sorted list of strings."""
things_with_an_extensions_field = [item for item in instructions]
enumerants = sum([item.get('enumerants', [])
for item in operand_kinds], [])
things_with_an_extensions_field.extend(enumerants)
extensions = sum([item.get('extensions', [])
for item in things_with_an_extensions_field
if item.get('extensions')], [])
for item in EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split():
# If it's already listed in a grammar, then don't put it in the
# special exceptions list.
assert item not in extensions, 'Extension %s is already in a grammar file' % item
extensions.extend(
EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split())
# Validator would ignore type declaration unique check. Should only be used
# for legacy autogenerated test files containing multiple instances of the
# same type declaration, if fixing the test by other methods is too
# difficult. Shouldn't be used for any other reasons.
extensions.append('SPV_VALIDATOR_ignore_type_decl_unique')
return sorted(set(extensions))
def get_capabilities(operand_kinds):
"""Returns capabilities as a list of JSON objects, in order of
appearance."""
enumerants = sum([item.get('enumerants', []) for item in operand_kinds
if item.get('kind') in ['Capability']], [])
return enumerants
def generate_extension_enum(extensions):
"""Returns enumeration containing extensions declared in the grammar."""
return ',\n'.join(['k' + extension for extension in extensions])
def generate_extension_to_string_mapping(extensions):
"""Returns mapping function from extensions to corresponding strings."""
function = 'const char* ExtensionToString(Extension extension) {\n'
function += ' switch (extension) {\n'
template = ' case Extension::k{extension}:\n' \
' return "{extension}";\n'
function += ''.join([template.format(extension=extension)
for extension in extensions])
function += ' };\n\n return "";\n}'
return function
def generate_string_to_extension_mapping(extensions):
"""Returns mapping function from strings to corresponding extensions."""
function = '''
bool GetExtensionFromString(const char* str, Extension* extension) {{
static const char* known_ext_strs[] = {{ {strs} }};
static const Extension known_ext_ids[] = {{ {ids} }};
const auto b = std::begin(known_ext_strs);
const auto e = std::end(known_ext_strs);
const auto found = std::equal_range(
b, e, str, [](const char* str1, const char* str2) {{
return std::strcmp(str1, str2) < 0;
}});
if (found.first == e || found.first == found.second) return false;
*extension = known_ext_ids[found.first - b];
return true;
}}
'''.format(strs=', '.join(['"{}"'.format(e) for e in extensions]),
ids=', '.join(['Extension::k{}'.format(e) for e in extensions]))
return function
def generate_capability_to_string_mapping(operand_kinds):
"""Returns mapping function from capabilities to corresponding strings.
We take care to avoid emitting duplicate values.
"""
function = 'const char* CapabilityToString(SpvCapability capability) {\n'
function += ' switch (capability) {\n'
template = ' case SpvCapability{capability}:\n' \
' return "{capability}";\n'
emitted = set() # The values of capabilities we already have emitted
for capability in get_capabilities(operand_kinds):
value = capability.get('value')
if value not in emitted:
emitted.add(value)
function += template.format(capability=capability.get('enumerant'))
function += ' case SpvCapabilityMax:\n' \
' assert(0 && "Attempting to convert SpvCapabilityMax to string");\n' \
' return "";\n'
function += ' };\n\n return "";\n}'
return function
def generate_all_string_enum_mappings(extensions, operand_kinds):
"""Returns all string-to-enum / enum-to-string mapping tables."""
tables = []
tables.append(generate_extension_to_string_mapping(extensions))
tables.append(generate_string_to_extension_mapping(extensions))
tables.append(generate_capability_to_string_mapping(operand_kinds))
return '\n\n'.join(tables)
def precondition_operand_kinds(operand_kinds):
"""For operand kinds that have the same number, make sure they all have the
same extension list."""
# Map operand kind and value to list of the union of extensions
# for same-valued enumerants.
exts = {}
for kind_entry in operand_kinds:
kind = kind_entry.get('kind')
for enum_entry in kind_entry.get('enumerants', []):
value = enum_entry.get('value')
key = kind + '.' + str(value)
if key in exts:
exts[key].extend(enum_entry.get('extensions', []))
else:
exts[key] = enum_entry.get('extensions', [])
exts[key] = sorted(set(exts[key]))
# Now make each entry the same list.
for kind_entry in operand_kinds:
kind = kind_entry.get('kind')
for enum_entry in kind_entry.get('enumerants', []):
value = enum_entry.get('value')
key = kind + '.' + str(value)
if len(exts[key]) > 0:
enum_entry['extensions'] = exts[key]
return operand_kinds
def prefix_operand_kind_names(prefix, json_dict):
"""Modifies json_dict, by prefixing all the operand kind names
with the given prefix. Also modifies their uses in the instructions
to match.
"""
old_to_new = {}
for operand_kind in json_dict["operand_kinds"]:
old_name = operand_kind["kind"]
new_name = prefix + old_name
operand_kind["kind"] = new_name
old_to_new[old_name] = new_name
for instruction in json_dict["instructions"]:
for operand in instruction.get("operands", []):
replacement = old_to_new.get(operand["kind"])
if replacement is not None:
operand["kind"] = replacement
def main():
import argparse
parser = argparse.ArgumentParser(description='Generate SPIR-V info tables')
parser.add_argument('--spirv-core-grammar', metavar='<path>',
type=str, required=False,
help='input JSON grammar file for core SPIR-V '
'instructions')
parser.add_argument('--extinst-debuginfo-grammar', metavar='<path>',
type=str, required=False, default=None,
help='input JSON grammar file for DebugInfo extended '
'instruction set')
parser.add_argument('--extinst-cldebuginfo100-grammar', metavar='<path>',
type=str, required=False, default=None,
help='input JSON grammar file for OpenCL.DebugInfo.100 '
'extended instruction set')
parser.add_argument('--extinst-glsl-grammar', metavar='<path>',
type=str, required=False, default=None,
help='input JSON grammar file for GLSL extended '
'instruction set')
parser.add_argument('--extinst-opencl-grammar', metavar='<path>',
type=str, required=False, default=None,
help='input JSON grammar file for OpenCL extended '
'instruction set')
parser.add_argument('--core-insts-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for core SPIR-V instructions')
parser.add_argument('--glsl-insts-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for GLSL extended instruction set')
parser.add_argument('--opencl-insts-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for OpenCL extended instruction set')
parser.add_argument('--operand-kinds-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for operand kinds')
parser.add_argument('--extension-enum-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for extension enumeration')
parser.add_argument('--enum-string-mapping-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for enum-string mappings')
parser.add_argument('--extinst-vendor-grammar', metavar='<path>',
type=str, required=False, default=None,
help='input JSON grammar file for vendor extended '
'instruction set'),
parser.add_argument('--vendor-insts-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for vendor extended instruction set')
parser.add_argument('--vendor-operand-kind-prefix', metavar='<string>',
type=str, required=False, default=None,
help='prefix for operand kinds (to disambiguate operand type enums)')
args = parser.parse_args()
# The GN build system needs this because it doesn't handle quoting
# empty string arguments well.
if args.vendor_operand_kind_prefix == "...nil...":
args.vendor_operand_kind_prefix = ""
if (args.core_insts_output is None) != \
(args.operand_kinds_output is None):
print('error: --core-insts-output and --operand-kinds-output '
'should be specified together.')
exit(1)
if args.operand_kinds_output and not (args.spirv_core_grammar and
args.extinst_debuginfo_grammar and
args.extinst_cldebuginfo100_grammar):
print('error: --operand-kinds-output requires --spirv-core-grammar '
'and --extinst-debuginfo-grammar '
'and --extinst-cldebuginfo100-grammar')
exit(1)
if (args.glsl_insts_output is None) != \
(args.extinst_glsl_grammar is None):
print('error: --glsl-insts-output and --extinst-glsl-grammar '
'should be specified together.')
exit(1)
if (args.opencl_insts_output is None) != \
(args.extinst_opencl_grammar is None):
print('error: --opencl-insts-output and --extinst-opencl-grammar '
'should be specified together.')
exit(1)
if (args.vendor_insts_output is None) != \
(args.extinst_vendor_grammar is None):
print('error: --vendor-insts-output and '
'--extinst-vendor-grammar should be specified together.')
exit(1)
if all([args.core_insts_output is None,
args.glsl_insts_output is None,
args.opencl_insts_output is None,
args.vendor_insts_output is None,
args.extension_enum_output is None,
args.enum_string_mapping_output is None]):
print('error: at least one output should be specified.')
exit(1)
if args.spirv_core_grammar is not None:
with open(args.spirv_core_grammar) as json_file:
core_grammar = json.loads(json_file.read())
with open(args.extinst_debuginfo_grammar) as debuginfo_json_file:
debuginfo_grammar = json.loads(debuginfo_json_file.read())
with open(args.extinst_cldebuginfo100_grammar) as cldebuginfo100_json_file:
cldebuginfo100_grammar = json.loads(cldebuginfo100_json_file.read())
prefix_operand_kind_names("CLDEBUG100_", cldebuginfo100_grammar)
instructions = []
instructions.extend(core_grammar['instructions'])
instructions.extend(debuginfo_grammar['instructions'])
instructions.extend(cldebuginfo100_grammar['instructions'])
operand_kinds = []
operand_kinds.extend(core_grammar['operand_kinds'])
operand_kinds.extend(debuginfo_grammar['operand_kinds'])
operand_kinds.extend(cldebuginfo100_grammar['operand_kinds'])
extensions = get_extension_list(instructions, operand_kinds)
operand_kinds = precondition_operand_kinds(operand_kinds)
if args.core_insts_output is not None:
make_path_to_file(args.core_insts_output)
make_path_to_file(args.operand_kinds_output)
with open(args.core_insts_output, 'w') as f:
f.write(generate_instruction_table(
core_grammar['instructions']))
with open(args.operand_kinds_output, 'w') as f:
f.write(generate_operand_kind_table(operand_kinds))
if args.extension_enum_output is not None:
make_path_to_file(args.extension_enum_output)
with open(args.extension_enum_output, 'w') as f:
f.write(generate_extension_enum(extensions))
if args.enum_string_mapping_output is not None:
make_path_to_file(args.enum_string_mapping_output)
with open(args.enum_string_mapping_output, 'w') as f:
f.write(generate_all_string_enum_mappings(
extensions, operand_kinds))
if args.extinst_glsl_grammar is not None:
with open(args.extinst_glsl_grammar) as json_file:
grammar = json.loads(json_file.read())
make_path_to_file(args.glsl_insts_output)
with open(args.glsl_insts_output, 'w') as f:
f.write(generate_extended_instruction_table(
grammar, 'glsl'))
if args.extinst_opencl_grammar is not None:
with open(args.extinst_opencl_grammar) as json_file:
grammar = json.loads(json_file.read())
make_path_to_file(args.opencl_insts_output)
with open(args.opencl_insts_output, 'w') as f:
f.write(generate_extended_instruction_table(
grammar, 'opencl'))
if args.extinst_vendor_grammar is not None:
with open(args.extinst_vendor_grammar) as json_file:
grammar = json.loads(json_file.read())
make_path_to_file(args.vendor_insts_output)
name = args.extinst_vendor_grammar
start = name.find('extinst.') + len('extinst.')
name = name[start:-len('.grammar.json')].replace('-', '_')
with open(args.vendor_insts_output, 'w') as f:
f.write(generate_extended_instruction_table(
grammar, name, args.vendor_operand_kind_prefix))
if __name__ == '__main__':
main()

View File

@ -1,185 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generates language headers from a JSON grammar file"""
import errno
import json
import os.path
import re
def make_path_to_file(f):
"""Makes all ancestor directories to the given file, if they
don't yet exist.
Arguments:
f: The file whose ancestor directories are to be created.
"""
dir = os.path.dirname(os.path.abspath(f))
try:
os.makedirs(dir)
except OSError as e:
if e.errno == errno.EEXIST and os.path.isdir(dir):
pass
else:
raise
class ExtInstGrammar:
"""The grammar for an extended instruction set"""
def __init__(self, name, copyright, instructions, operand_kinds, version = None, revision = None):
self.name = name
self.copyright = copyright
self.instructions = instructions
self.operand_kinds = operand_kinds
self.version = version
self.revision = revision
class LangGenerator:
"""A language-specific generator"""
def __init__(self):
self.upper_case_initial = re.compile('^[A-Z]')
pass
def comment_prefix(self):
return ""
def namespace_prefix(self):
return ""
def uses_guards(self):
return False
def cpp_guard_preamble(self):
return ""
def cpp_guard_postamble(self):
return ""
def enum_value(self, prefix, name, value):
if self.upper_case_initial.match(name):
use_name = name
else:
use_name = '_' + name
return " {}{} = {},".format(prefix, use_name, value)
def generate(self, grammar):
"""Returns a string that is the language-specific header for the given grammar"""
parts = []
if grammar.copyright:
parts.extend(["{}{}".format(self.comment_prefix(), f) for f in grammar.copyright])
parts.append('')
guard = 'SPIRV_EXTINST_{}_H_'.format(grammar.name)
if self.uses_guards:
parts.append('#ifndef {}'.format(guard))
parts.append('#define {}'.format(guard))
parts.append('')
parts.append(self.cpp_guard_preamble())
if grammar.version:
parts.append(self.const_definition(grammar.name, 'Version', grammar.version))
if grammar.revision is not None:
parts.append(self.const_definition(grammar.name, 'Revision', grammar.revision))
parts.append('')
if grammar.instructions:
parts.append(self.enum_prefix(grammar.name, 'Instructions'))
for inst in grammar.instructions:
parts.append(self.enum_value(grammar.name, inst['opname'], inst['opcode']))
parts.append(self.enum_end(grammar.name, 'Instructions'))
parts.append('')
if grammar.operand_kinds:
for kind in grammar.operand_kinds:
parts.append(self.enum_prefix(grammar.name, kind['kind']))
for e in kind['enumerants']:
parts.append(self.enum_value(grammar.name, e['enumerant'], e['value']))
parts.append(self.enum_end(grammar.name, kind['kind']))
parts.append('')
parts.append(self.cpp_guard_postamble())
if self.uses_guards:
parts.append('#endif // {}'.format(guard))
return '\n'.join(parts)
class CLikeGenerator(LangGenerator):
def uses_guards(self):
return True
def comment_prefix(self):
return "// "
def const_definition(self, prefix, var, value):
# Use an anonymous enum. Don't use a static const int variable because
# that can bloat binary size.
return 'enum {0} {1}{2} = {3}, {1}{2}_BitWidthPadding = 0x7fffffff {4};'.format(
'{', prefix, var, value, '}')
def enum_prefix(self, prefix, name):
return 'enum {}{} {}'.format(prefix, name, '{')
def enum_end(self, prefix, enum):
return ' {}{}Max = 0x7ffffff\n{};\n'.format(prefix, enum, '}')
def cpp_guard_preamble(self):
return '#ifdef __cplusplus\nextern "C" {\n#endif\n'
def cpp_guard_postamble(self):
return '#ifdef __cplusplus\n}\n#endif\n'
class CGenerator(CLikeGenerator):
pass
def main():
import argparse
parser = argparse.ArgumentParser(description='Generate language headers from a JSON grammar')
parser.add_argument('--extinst-grammar', metavar='<path>',
type=str, required=True,
help='input JSON grammar file for extended instruction set')
parser.add_argument('--extinst-output-path', metavar='<path>',
type=str, required=True,
help='Path of the language-specific output file.')
args = parser.parse_args()
with open(args.extinst_grammar) as json_file:
grammar_json = json.loads(json_file.read())
grammar_name = os.path.splitext(os.path.basename(args.extinst_output_path))[0]
grammar = ExtInstGrammar(name = grammar_name,
copyright = grammar_json['copyright'],
instructions = grammar_json['instructions'],
operand_kinds = grammar_json['operand_kinds'],
version = grammar_json['version'],
revision = grammar_json['revision'])
make_path_to_file(args.extinst_output_path)
with open(args.extinst_output_path, 'w') as f:
f.write(CGenerator().generate(grammar))
if __name__ == '__main__':
main()

View File

@ -1,90 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2016 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generates the vendor tool table from the SPIR-V XML registry."""
import errno
import os.path
import xml.etree.ElementTree
def mkdir_p(directory):
"""Make the directory, and all its ancestors as required. Any of the
directories are allowed to already exist.
This is compatible with Python down to 3.0.
"""
if directory == "":
# We're being asked to make the current directory.
return
try:
os.makedirs(directory)
except OSError as e:
if e.errno == errno.EEXIST and os.path.isdir(directory):
pass
else:
raise
def generate_vendor_table(registry):
"""Returns a list of C style initializers for the registered vendors
and their tools.
Args:
registry: The SPIR-V XMLregistry as an xml.ElementTree
"""
lines = []
for ids in registry.iter('ids'):
if 'vendor' == ids.attrib['type']:
for an_id in ids.iter('id'):
value = an_id.attrib['value']
vendor = an_id.attrib['vendor']
if 'tool' in an_id.attrib:
tool = an_id.attrib['tool']
vendor_tool = vendor + ' ' + tool
else:
tool = ''
vendor_tool = vendor
line = '{' + '{}, "{}", "{}", "{}"'.format(value,
vendor,
tool,
vendor_tool) + '},'
lines.append(line)
return '\n'.join(lines)
def main():
import argparse
parser = argparse.ArgumentParser(description=
'Generate tables from SPIR-V XML registry')
parser.add_argument('--xml', metavar='<path>',
type=str, required=True,
help='SPIR-V XML Registry file')
parser.add_argument('--generator-output', metavar='<path>',
type=str, required=True,
help='output file for SPIR-V generators table')
args = parser.parse_args()
with open(args.xml) as xml_in:
registry = xml.etree.ElementTree.fromstring(xml_in.read())
mkdir_p(os.path.dirname(args.generator_output))
with open(args.generator_output, 'w') as f:
f.write(generate_vendor_table(registry))
if __name__ == '__main__':
main()

View File

@ -1,205 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2016 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generates Vim syntax rules for SPIR-V assembly (.spvasm) files"""
import json
PREAMBLE="""" Vim syntax file
" Language: spvasm
" Generated by SPIRV-Tools
if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif
syn case match
"""
POSTAMBLE="""
syntax keyword spvasmTodo TODO FIXME contained
syn match spvasmIdNumber /%\d\+\>/
" The assembler treats the leading minus sign as part of the number token.
" This applies to integers, and to floats below.
syn match spvasmNumber /-\?\<\d\+\>/
" Floating point literals.
" In general, C++ requires at least digit in the mantissa, and the
" floating point is optional. This applies to both the regular decimal float
" case and the hex float case.
" First case: digits before the optional decimal, no trailing digits.
syn match spvasmFloat /-\?\d\+\.\?\(e[+-]\d\+\)\?/
" Second case: optional digits before decimal, trailing digits
syn match spvasmFloat /-\?\d*\.\d\+\(e[+-]\d\+\)\?/
" First case: hex digits before the optional decimal, no trailing hex digits.
syn match spvasmFloat /-\?0[xX]\\x\+\.\?p[-+]\d\+/
" Second case: optional hex digits before decimal, trailing hex digits
syn match spvasmFloat /-\?0[xX]\\x*\.\\x\+p[-+]\d\+/
syn match spvasmComment /;.*$/ contains=spvasmTodo
syn region spvasmString start=/"/ skip=/\\\\"/ end=/"/
syn match spvasmId /%[a-zA-Z_][a-zA-Z_0-9]*/
" Highlight unknown constants and statements as errors
syn match spvasmError /[a-zA-Z][a-zA-Z_0-9]*/
if version >= 508 || !exists("did_c_syn_inits")
if version < 508
let did_c_syn_inits = 1
command -nargs=+ HiLink hi link <args>
else
command -nargs=+ HiLink hi def link <args>
endif
HiLink spvasmStatement Statement
HiLink spvasmNumber Number
HiLink spvasmComment Comment
HiLink spvasmString String
HiLink spvasmFloat Float
HiLink spvasmConstant Constant
HiLink spvasmIdNumber Identifier
HiLink spvasmId Identifier
HiLink spvasmTodo Todo
delcommand HiLink
endif
let b:current_syntax = "spvasm"
"""
# This list is taken from the description of OpSpecConstantOp in SPIR-V 1.1.
# TODO(dneto): Propose that this information be embedded in the grammar file.
SPEC_CONSTANT_OP_OPCODES = """
OpSConvert, OpFConvert
OpSNegate, OpNot
OpIAdd, OpISub
OpIMul, OpUDiv, OpSDiv, OpUMod, OpSRem, OpSMod
OpShiftRightLogical, OpShiftRightArithmetic, OpShiftLeftLogical
OpBitwiseOr, OpBitwiseXor, OpBitwiseAnd
OpVectorShuffle, OpCompositeExtract, OpCompositeInsert
OpLogicalOr, OpLogicalAnd, OpLogicalNot,
OpLogicalEqual, OpLogicalNotEqual
OpSelect
OpIEqual, OpINotEqual
OpULessThan, OpSLessThan
OpUGreaterThan, OpSGreaterThan
OpULessThanEqual, OpSLessThanEqual
OpUGreaterThanEqual, OpSGreaterThanEqual
OpQuantizeToF16
OpConvertFToS, OpConvertSToF
OpConvertFToU, OpConvertUToF
OpUConvert
OpConvertPtrToU, OpConvertUToPtr
OpGenericCastToPtr, OpPtrCastToGeneric
OpBitcast
OpFNegate
OpFAdd, OpFSub
OpFMul, OpFDiv
OpFRem, OpFMod
OpAccessChain, OpInBoundsAccessChain
OpPtrAccessChain, OpInBoundsPtrAccessChain"""
def EmitAsStatement(name):
"""Emits the given name as a statement token"""
print('syn keyword spvasmStatement', name)
def EmitAsEnumerant(name):
"""Emits the given name as an named operand token"""
print('syn keyword spvasmConstant', name)
def main():
"""Parses arguments, then generates the Vim syntax rules for SPIR-V assembly
on stdout."""
import argparse
parser = argparse.ArgumentParser(description='Generate SPIR-V info tables')
parser.add_argument('--spirv-core-grammar', metavar='<path>',
type=str, required=True,
help='input JSON grammar file for core SPIR-V '
'instructions')
parser.add_argument('--extinst-glsl-grammar', metavar='<path>',
type=str, required=False, default=None,
help='input JSON grammar file for GLSL extended '
'instruction set')
parser.add_argument('--extinst-opencl-grammar', metavar='<path>',
type=str, required=False, default=None,
help='input JSON grammar file for OpenGL extended '
'instruction set')
parser.add_argument('--extinst-debuginfo-grammar', metavar='<path>',
type=str, required=False, default=None,
help='input JSON grammar file for DebugInfo extended '
'instruction set')
args = parser.parse_args()
# Generate the syntax rules.
print(PREAMBLE)
core = json.loads(open(args.spirv_core_grammar).read())
print('\n" Core instructions')
for inst in core["instructions"]:
EmitAsStatement(inst['opname'])
print('\n" Core operand enums')
for operand_kind in core["operand_kinds"]:
if 'enumerants' in operand_kind:
for e in operand_kind['enumerants']:
EmitAsEnumerant(e['enumerant'])
if args.extinst_glsl_grammar is not None:
print('\n" GLSL.std.450 extended instructions')
glsl = json.loads(open(args.extinst_glsl_grammar).read())
# These opcodes are really enumerant operands for the OpExtInst
# instruction.
for inst in glsl["instructions"]:
EmitAsEnumerant(inst['opname'])
if args.extinst_opencl_grammar is not None:
print('\n" OpenCL.std extended instructions')
opencl = json.loads(open(args.extinst_opencl_grammar).read())
for inst in opencl["instructions"]:
EmitAsEnumerant(inst['opname'])
if args.extinst_debuginfo_grammar is not None:
print('\n" DebugInfo extended instructions')
debuginfo = json.loads(open(args.extinst_debuginfo_grammar).read())
for inst in debuginfo["instructions"]:
EmitAsEnumerant(inst['opname'])
print('\n" DebugInfo operand enums')
for operand_kind in debuginfo["operand_kinds"]:
if 'enumerants' in operand_kind:
for e in operand_kind['enumerants']:
EmitAsEnumerant(e['enumerant'])
print('\n" OpSpecConstantOp opcodes')
for word in SPEC_CONSTANT_OP_OPCODES.split(' '):
stripped = word.strip('\n,')
if stripped != "":
# Treat as an enumerant, but without the leading "Op"
EmitAsEnumerant(stripped[2:])
print(POSTAMBLE)
if __name__ == '__main__':
main()

View File

@ -1,282 +0,0 @@
#!/usr/bin/env python3
# Copyright 2014 Google Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Parse a DEPS file and git checkout all of the dependencies.
Args:
An optional list of deps_os values.
Environment Variables:
GIT_EXECUTABLE: path to "git" binary; if unset, will look for one of
['git', 'git.exe', 'git.bat'] in your default path.
GIT_SYNC_DEPS_PATH: file to get the dependency list from; if unset,
will use the file ../DEPS relative to this script's directory.
GIT_SYNC_DEPS_QUIET: if set to non-empty string, suppress messages.
Git Config:
To disable syncing of a single repository:
cd path/to/repository
git config sync-deps.disable true
To re-enable sync:
cd path/to/repository
git config --unset sync-deps.disable
"""
import os
import re
import subprocess
import sys
import threading
from builtins import bytes
def git_executable():
"""Find the git executable.
Returns:
A string suitable for passing to subprocess functions, or None.
"""
envgit = os.environ.get('GIT_EXECUTABLE')
searchlist = ['git', 'git.exe', 'git.bat']
if envgit:
searchlist.insert(0, envgit)
with open(os.devnull, 'w') as devnull:
for git in searchlist:
try:
subprocess.call([git, '--version'], stdout=devnull)
except (OSError,):
continue
return git
return None
DEFAULT_DEPS_PATH = os.path.normpath(
os.path.join(os.path.dirname(__file__), os.pardir, 'DEPS'))
def usage(deps_file_path = None):
sys.stderr.write(
'Usage: run to grab dependencies, with optional platform support:\n')
sys.stderr.write(' %s %s' % (sys.executable, __file__))
if deps_file_path:
parsed_deps = parse_file_to_dict(deps_file_path)
if 'deps_os' in parsed_deps:
for deps_os in parsed_deps['deps_os']:
sys.stderr.write(' [%s]' % deps_os)
sys.stderr.write('\n\n')
sys.stderr.write(__doc__)
def git_repository_sync_is_disabled(git, directory):
try:
disable = subprocess.check_output(
[git, 'config', 'sync-deps.disable'], cwd=directory)
return disable.lower().strip() in ['true', '1', 'yes', 'on']
except subprocess.CalledProcessError:
return False
def is_git_toplevel(git, directory):
"""Return true iff the directory is the top level of a Git repository.
Args:
git (string) the git executable
directory (string) the path into which the repository
is expected to be checked out.
"""
try:
toplevel = subprocess.check_output(
[git, 'rev-parse', '--show-toplevel'], cwd=directory).strip()
return os.path.realpath(bytes(directory, 'utf8')) == os.path.realpath(toplevel)
except subprocess.CalledProcessError:
return False
def status(directory, checkoutable):
def truncate(s, length):
return s if len(s) <= length else s[:(length - 3)] + '...'
dlen = 36
directory = truncate(directory, dlen)
checkoutable = truncate(checkoutable, 40)
sys.stdout.write('%-*s @ %s\n' % (dlen, directory, checkoutable))
def git_checkout_to_directory(git, repo, checkoutable, directory, verbose):
"""Checkout (and clone if needed) a Git repository.
Args:
git (string) the git executable
repo (string) the location of the repository, suitable
for passing to `git clone`.
checkoutable (string) a tag, branch, or commit, suitable for
passing to `git checkout`
directory (string) the path into which the repository
should be checked out.
verbose (boolean)
Raises an exception if any calls to git fail.
"""
if not os.path.isdir(directory):
subprocess.check_call(
[git, 'clone', '--quiet', repo, directory])
if not is_git_toplevel(git, directory):
# if the directory exists, but isn't a git repo, you will modify
# the parent repostory, which isn't what you want.
sys.stdout.write('%s\n IS NOT TOP-LEVEL GIT DIRECTORY.\n' % directory)
return
# Check to see if this repo is disabled. Quick return.
if git_repository_sync_is_disabled(git, directory):
sys.stdout.write('%s\n SYNC IS DISABLED.\n' % directory)
return
with open(os.devnull, 'w') as devnull:
# If this fails, we will fetch before trying again. Don't spam user
# with error infomation.
if 0 == subprocess.call([git, 'checkout', '--quiet', checkoutable],
cwd=directory, stderr=devnull):
# if this succeeds, skip slow `git fetch`.
if verbose:
status(directory, checkoutable) # Success.
return
# If the repo has changed, always force use of the correct repo.
# If origin already points to repo, this is a quick no-op.
subprocess.check_call(
[git, 'remote', 'set-url', 'origin', repo], cwd=directory)
subprocess.check_call([git, 'fetch', '--quiet'], cwd=directory)
subprocess.check_call([git, 'checkout', '--quiet', checkoutable], cwd=directory)
if verbose:
status(directory, checkoutable) # Success.
def parse_file_to_dict(path):
dictionary = {}
contents = open(path).read()
# Need to convert Var() to vars[], so that the DEPS is actually Python. Var()
# comes from Autoroller using gclient which has a slightly different DEPS
# format.
contents = re.sub(r"Var\((.*?)\)", r"vars[\1]", contents)
exec(contents, dictionary)
return dictionary
def git_sync_deps(deps_file_path, command_line_os_requests, verbose):
"""Grab dependencies, with optional platform support.
Args:
deps_file_path (string) Path to the DEPS file.
command_line_os_requests (list of strings) Can be empty list.
List of strings that should each be a key in the deps_os
dictionary in the DEPS file.
Raises git Exceptions.
"""
git = git_executable()
assert git
deps_file_directory = os.path.dirname(deps_file_path)
deps_file = parse_file_to_dict(deps_file_path)
dependencies = deps_file['deps'].copy()
os_specific_dependencies = deps_file.get('deps_os', dict())
if 'all' in command_line_os_requests:
for value in list(os_specific_dependencies.values()):
dependencies.update(value)
else:
for os_name in command_line_os_requests:
# Add OS-specific dependencies
if os_name in os_specific_dependencies:
dependencies.update(os_specific_dependencies[os_name])
for directory in dependencies:
for other_dir in dependencies:
if directory.startswith(other_dir + '/'):
raise Exception('%r is parent of %r' % (other_dir, directory))
list_of_arg_lists = []
for directory in sorted(dependencies):
if '@' in dependencies[directory]:
repo, checkoutable = dependencies[directory].split('@', 1)
else:
raise Exception("please specify commit or tag")
relative_directory = os.path.join(deps_file_directory, directory)
list_of_arg_lists.append(
(git, repo, checkoutable, relative_directory, verbose))
multithread(git_checkout_to_directory, list_of_arg_lists)
for directory in deps_file.get('recursedeps', []):
recursive_path = os.path.join(deps_file_directory, directory, 'DEPS')
git_sync_deps(recursive_path, command_line_os_requests, verbose)
def multithread(function, list_of_arg_lists):
# for args in list_of_arg_lists:
# function(*args)
# return
threads = []
for args in list_of_arg_lists:
thread = threading.Thread(None, function, None, args)
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
def main(argv):
deps_file_path = os.environ.get('GIT_SYNC_DEPS_PATH', DEFAULT_DEPS_PATH)
verbose = not bool(os.environ.get('GIT_SYNC_DEPS_QUIET', False))
if '--help' in argv or '-h' in argv:
usage(deps_file_path)
return 1
git_sync_deps(deps_file_path, argv, verbose)
# subprocess.check_call(
# [sys.executable,
# os.path.join(os.path.dirname(deps_file_path), 'bin', 'fetch-gn')])
return 0
if __name__ == '__main__':
exit(main(sys.argv[1:]))

View File

@ -1,46 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2019 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Attempts to roll all entries in DEPS to tip-of-tree and create a commit.
#
# Depends on roll-dep from depot_path being in PATH.
effcee_dir="external/effcee/"
effcee_trunk="origin/main"
googletest_dir="external/googletest/"
googletest_trunk="origin/master"
re2_dir="external/re2/"
re2_trunk="origin/master"
spirv_headers_dir="external/spirv-headers/"
spirv_headers_trunk="origin/master"
# This script assumes it's parent directory is the repo root.
repo_path=$(dirname "$0")/..
cd "$repo_path"
if [[ $(git diff --stat) != '' ]]; then
echo "Working tree is dirty, commit changes before attempting to roll DEPS"
exit 1
fi
old_head=$(git rev-parse HEAD)
roll-dep --ignore-dirty-tree --roll-to="${effcee_trunk}" "${effcee_dir}"
roll-dep --ignore-dirty-tree --roll-to="${googletest_trunk}" "${googletest_dir}"
roll-dep --ignore-dirty-tree --roll-to="${re2_trunk}" "${re2_dir}"
roll-dep --ignore-dirty-tree --roll-to="${spirv_headers_trunk}" "${spirv_headers_dir}"
git rebase --interactive "${old_head}"

View File

@ -1,148 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Updates an output file with version info unless the new content is the same
# as the existing content.
#
# Args: <spirv-tools_dir> <output-file>
#
# The output file will contain a line of text consisting of two C source syntax
# string literals separated by a comma:
# - The software version deduced from the CHANGES file in the given directory.
# - A longer string with the project name, the software version number, and
# git commit information for the directory. The commit information
# is the output of "git describe" if that succeeds, or "git rev-parse HEAD"
# if that succeeds, or otherwise a message containing the phrase
# "unknown hash".
# The string contents are escaped as necessary.
import datetime
import errno
import os
import os.path
import re
import subprocess
import sys
import time
def mkdir_p(directory):
"""Make the directory, and all its ancestors as required. Any of the
directories are allowed to already exist."""
if directory == "":
# We're being asked to make the current directory.
return
try:
os.makedirs(directory)
except OSError as e:
if e.errno == errno.EEXIST and os.path.isdir(directory):
pass
else:
raise
def command_output(cmd, directory):
"""Runs a command in a directory and returns its standard output stream.
Captures the standard error stream.
Raises a RuntimeError if the command fails to launch or otherwise fails.
"""
p = subprocess.Popen(cmd,
cwd=directory,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(stdout, _) = p.communicate()
if p.returncode != 0:
raise RuntimeError('Failed to run %s in %s' % (cmd, directory))
return stdout
def deduce_software_version(directory):
"""Returns a software version number parsed from the CHANGES file
in the given directory.
The CHANGES file describes most recent versions first.
"""
# Match the first well-formed version-and-date line.
# Allow trailing whitespace in the checked-out source code has
# unexpected carriage returns on a linefeed-only system such as
# Linux.
pattern = re.compile(r'^(v\d+\.\d+(-dev)?) \d\d\d\d-\d\d-\d\d\s*$')
changes_file = os.path.join(directory, 'CHANGES')
with open(changes_file, mode='r') as f:
for line in f.readlines():
match = pattern.match(line)
if match:
return match.group(1)
raise Exception('No version number found in {}'.format(changes_file))
def describe(directory):
"""Returns a string describing the current Git HEAD version as descriptively
as possible.
Runs 'git describe', or alternately 'git rev-parse HEAD', in directory. If
successful, returns the output; otherwise returns 'unknown hash, <date>'."""
try:
# decode() is needed here for Python3 compatibility. In Python2,
# str and bytes are the same type, but not in Python3.
# Popen.communicate() returns a bytes instance, which needs to be
# decoded into text data first in Python3. And this decode() won't
# hurt Python2.
return command_output(['git', 'describe'], directory).rstrip().decode()
except:
try:
return command_output(
['git', 'rev-parse', 'HEAD'], directory).rstrip().decode()
except:
# This is the fallback case where git gives us no information,
# e.g. because the source tree might not be in a git tree.
# In this case, usually use a timestamp. However, to ensure
# reproducible builds, allow the builder to override the wall
# clock time with environment variable SOURCE_DATE_EPOCH
# containing a (presumably) fixed timestamp.
timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
formatted = datetime.datetime.utcfromtimestamp(timestamp).isoformat()
return 'unknown hash, {}'.format(formatted)
def main():
if len(sys.argv) != 3:
print('usage: {} <spirv-tools-dir> <output-file>'.format(sys.argv[0]))
sys.exit(1)
output_file = sys.argv[2]
mkdir_p(os.path.dirname(output_file))
software_version = deduce_software_version(sys.argv[1])
new_content = '"{}", "SPIRV-Tools {} {}"\n'.format(
software_version, software_version,
describe(sys.argv[1]).replace('"', '\\"'))
if os.path.isfile(output_file):
with open(output_file, 'r') as f:
if new_content == f.read():
return
with open(output_file, 'w') as f:
f.write(new_content)
if __name__ == '__main__':
main()