Add spirv-tools and spirv-tools-sys crates to wrap usage of spirv-tools (#179)

* Add spirv-headers and spirv-tools as submodules

* Add simple generator and the generated code needed for compilation

* Add first pass on spirv-tools-sys

* Add first pass on spirv-tools

* Replace invocation of spirv-opt with spirv-tools crate

* Use C++11

* Placate clippy

* Add validation, replacing spirv-val with the spirv-tools crate

* Fix MSVC warning

* Use patched spirv-tools

* Fixup metadata

* Add same compiler flags as "official" build scripts

* Update spirv-tools and generated files

* Fixup

* Add assembler and example

* Use assembler in tests

* Oops, fix macos TARGET_OS

* write -> write_all

* Start splitting spirv-tools into a compiled vs tool feature set

* Checkpointing

* Checkpoint

* Boop

* Get tests to work both with installed and compiled tools

* Cleanup CI config

* Splits steps to clearly show how long each part of a longer (eg test)
step actually takes
* Label all steps

* Explicitly disable submodule checkout

* Rustfmt

* Rename features for consistency and fix clippy warnings

* Split "core" crates from examples

* Add run_clippy bash script

* Add test script

* Remove x flag

* Newline

* Actually print out errors from running val/opt

* Revert drive-by import merging

* Change intro to take the changes this PR has into account

* Actually run tests on Windows

* Fetch only the host target to reduce fetch times

* Add more info when a spirv tool returns a non-zero exit code

* Rustfmt

* Switch tool assembler to use files to see if it fixes windows

* Use files for input and output for now until I can figure out Windows being dumb

* Fix API docs generation

* Compile and use C++ code to check Windows issue

* Return to use installed tools
This commit is contained in:
Jake Shadle 2020-10-29 23:03:07 +01:00 committed by GitHub
parent 5aa7453b19
commit 307d0da66b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 6524 additions and 187 deletions

View File

@ -11,25 +11,40 @@ jobs:
name: Test
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
os: [macOS-latest, ubuntu-latest, windows-latest]
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: windows-latest
target: x86_64-pc-windows-msvc
- os: macOS-latest
target: x86_64-apple-darwin
runs-on: ${{ matrix.os }}
env:
spirv_tools_version: "20200928"
steps:
# Note that we are explicitly NOT checking out submodules, to validate
# that we haven't accidentally enabled spirv-tools native compilation
# and regressed CI times
- uses: actions/checkout@v2
with:
submodules: "false"
# Ubuntu does have `brew install spirv-tools`, but it installs from
# source and so takes >8 minutes.
- if: ${{ runner.os == 'Linux' }}
name: Linux - Install native dependencies
run: |
sudo apt install libwayland-cursor0 libxkbcommon-dev libwayland-dev
mkdir "${HOME}/spirv-tools"
curl -fL https://storage.googleapis.com/spirv-tools/artifacts/prod/graphics_shader_compiler/spirv-tools/linux-clang-release/continuous/1305/20201026-063148/install.tgz | tar -xz -C "${HOME}/spirv-tools"
echo "${HOME}/spirv-tools/install/bin" >> $GITHUB_PATH
- if: ${{ runner.os == 'macOS' }}
name: Mac - Install spirv-tools
run: brew install spirv-tools
# Currently SPIR-V tools aren't available in any package manager
# on Windows that put the tools in the path.
- if: ${{ runner.os == 'Windows' }}
name: Windows - Install spirv-tools
shell: bash
run: |
tmparch=$(mktemp)
@ -39,25 +54,42 @@ jobs:
- if: ${{ runner.os == 'Windows' }}
# Runs separately to add spir-v tools to Powershell's Path.
run: echo "$HOME/spirv-tools/install/bin" >> $env:GITHUB_PATH
- run: rustup component add rust-src rustc-dev llvm-tools-preview
# See: https://github.com/EmbarkStudios/rust-gpu/issues/84
- if: ${{ runner.os == 'macOS' }}
run: cargo test --workspace --exclude example-runner
- if: ${{ runner.os != 'macOS' }}
run: cargo test --workspace
- name: Install rustup components
run: rustup component add rust-src rustc-dev llvm-tools-preview
# Fetch dependencies in a separate step to clearly show how long each part
# of the testing takes
- name: cargo fetch
run: cargo fetch --target ${{ matrix.target }}
- name: Run tests
shell: bash
run: .github/workflows/test.sh
lint:
name: Lint
runs-on: ubuntu-latest
steps:
# Note that we are explicitly NOT checking out submodules, to validate
# that we haven't accidentally enabled spirv-tools native compilation
# and regressed CI times
- uses: actions/checkout@v2
- run: sudo apt install libwayland-cursor0 libxkbcommon-dev libwayland-dev
- run: |
with:
submodules: "false"
- name: Install native dependencies
run: sudo apt install libwayland-cursor0 libxkbcommon-dev libwayland-dev
- name: Install spirv-tools
run: |
mkdir "${HOME}/spirv-tools"
curl -fL https://storage.googleapis.com/spirv-tools/artifacts/prod/graphics_shader_compiler/spirv-tools/linux-clang-release/continuous/1305/20201026-063148/install.tgz | tar -xz -C "${HOME}/spirv-tools"
echo "${HOME}/spirv-tools/install/bin" >> $GITHUB_PATH
- run: rustup component add rustfmt clippy rust-src rustc-dev llvm-tools-preview
- run: cargo fmt --all -- --check
- run: cargo clippy --workspace --all-targets -- -D warnings
- name: Install rustup components
run: rustup component add rustfmt clippy rust-src rustc-dev llvm-tools-preview
- name: Rustfmt
run: cargo fmt --all -- --check
- name: cargo fetch
run: cargo fetch
- name: Clippy
run: .github/workflows/clippy.sh
cargo-deny:
runs-on: ubuntu-latest
steps:

42
.github/workflows/clippy.sh vendored Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env bash
set -e
if [[ -z "${CI}" ]]; then
FEAT="use-compiled-tools"
else
FEAT="use-installed-tools"
fi
function clippy() {
echo ::group::"$1"
cargo clippy \
--manifest-path "$1/Cargo.toml" \
--no-default-features \
--features "$FEAT" \
--all-targets \
-- -D warnings
echo ::endgroup::
}
function clippy_no_features() {
echo ::group::"$1"
cargo clippy \
--manifest-path "$1/Cargo.toml" \
--all-targets \
-- -D warnings
echo ::endgroup::
}
# Core crates
clippy spirv-tools-sys
clippy spirv-tools
clippy rustc_codegen_spirv
clippy spirv-builder
# Examples
clippy examples/example-runner
clippy examples/wgpu-example-runner
clippy_no_features examples/example-runner-cpu
clippy_no_features examples/example-shader
clippy_no_features examples/wgpu-example-shader

View File

@ -13,7 +13,7 @@ jobs:
- run: brew install mdbook spirv-tools
- run: mkdir docs-build/
- run: $(cd docs && mdbook build -d ../docs-build/book)
- run: cargo doc
- run: .github/workflows/docs.sh
- run: mv target/doc docs-build/api
- uses: JamesIves/github-pages-deploy-action@3.7.1
with:

23
.github/workflows/docs.sh vendored Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -e
if [[ -z "${CI}" ]]; then
FEAT="use-compiled-tools"
else
FEAT="use-installed-tools"
fi
function doc() {
echo ::group::"$1"
cargo doc \
--manifest-path "$1/Cargo.toml" \
--no-default-features \
--features "$FEAT"
echo ::endgroup::
}
# Core crates only!
doc spirv-tools-sys
doc spirv-tools
doc rustc_codegen_spirv
doc spirv-builder

55
.github/workflows/test.sh vendored Executable file
View File

@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -e
if [[ -z "${CI}" ]]; then
FEAT="use-compiled-tools"
else
FEAT="use-installed-tools"
fi
os=$1
function cargo_test() {
echo ::group::"$1 build"
cargo test \
--manifest-path "$1/Cargo.toml" \
--no-default-features \
--features "$FEAT" \
--no-run
echo ::endgroup::
echo ::group::"$1 test"
cargo test \
--manifest-path "$1/Cargo.toml" \
--no-default-features \
--features "$FEAT"
echo ::endgroup::
}
function cargo_test_no_features() {
echo ::group::"$1 build"
cargo test --manifest-path "$1/Cargo.toml" --no-run
echo ::endgroup::
echo ::group::"$1 test"
cargo test --manifest-path "$1/Cargo.toml"
echo ::endgroup::
}
# Core crates
cargo_test spirv-tools-sys
cargo_test spirv-tools
cargo_test rustc_codegen_spirv
cargo_test spirv-builder
# Examples
# See: https://github.com/EmbarkStudios/rust-gpu/issues/84
if [[ -z "${CI}" && "$os" != "macOS" ]]; then
cargo_test examples/example-runner
fi
cargo_test examples/wgpu-example-runner
cargo_test_no_features examples/example-runner-cpu
cargo_test_no_features examples/example-shader
cargo_test_no_features examples/wgpu-example-shader

7
.gitmodules vendored Normal file
View File

@ -0,0 +1,7 @@
[submodule "spirv-tools-sys/spirv-headers"]
path = spirv-tools-sys/spirv-headers
url = https://github.com/KhronosGroup/SPIRV-Headers.git
[submodule "spirv-tools-sys/spirv-tools"]
path = spirv-tools-sys/spirv-tools
url = https://github.com/EmbarkStudios/SPIRV-Tools.git
branch = patch-to-string

18
Cargo.lock generated
View File

@ -1983,6 +1983,7 @@ dependencies = [
"bimap",
"pretty_assertions",
"rspirv",
"spirv-tools",
"tar",
"tempfile",
"thiserror",
@ -2199,6 +2200,23 @@ dependencies = [
name = "spirv-std"
version = "0.1.0"
[[package]]
name = "spirv-tools"
version = "0.1.0"
dependencies = [
"memchr",
"spirv-tools-sys",
"structopt",
"tempfile",
]
[[package]]
name = "spirv-tools-sys"
version = "0.1.0"
dependencies = [
"cc",
]
[[package]]
name = "spirv_cross"
version = "0.22.0"

View File

@ -5,7 +5,10 @@ members = [
"examples/wgpu-example-runner",
"examples/example-shader",
"examples/wgpu-example-shader",
"rustc_codegen_spirv",
"spirv-builder",
"spirv-std",
"spirv-tools",
"spirv-tools-sys",
]

View File

@ -1,4 +1,5 @@
# Introduction
Welcome to the Rust-GPU dev guide! This documentation is meant for documenting
how to use and develop on Rust-GPU.
@ -6,21 +7,27 @@ how to use and develop on Rust-GPU.
1. Clone the repository.
```shell
git clone --recurse-submodules https://github.com/EmbarkStudios.com/rust-gpu
```
1. Install the prerequisites using the provided setup script. From the root of the project, run:
MacOS, Linux:
```shell
sh setup.sh
```
Windows:
```
```shell
setup.bat
```
The setup script installs nightly Rust (required for now, see [#78](https://github.com/EmbarkStudios/rust-gpu/issues/78) for tracking issue).
1. Install [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools#downloads) and add it to your PATH (for now, eventually we will automatically build and link it instead of calling executables)
1. **optional** Install [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools#downloads) and add it to your `PATH`. You can skip this step if you just want to run examples with the defaults. See [Using installed SPIRV-Tools](#using-installed-spirv-tools) if you decide to go with this option.
1. Next, look at the [examples](examples) folder. There are two projects here: [examples/example-shader](examples/example-shader) and [examples/example-runner](examples/example-runner). The example-shader project is a "GPU crate", one that will be compiled to a SPIR-V module. The example-runner project is a normal, CPU crate that uses vulkan to consume the example-shader SPIR-V module to display a shader.
@ -36,15 +43,13 @@ how to use and develop on Rust-GPU.
Be aware that this project is in a very early phase - if the above doesn't work, please [file an issue](https://github.com/EmbarkStudios/rust-gpu/issues)!
## Getting started, for power users who don't want to use spirv-builder.
## Getting started, for power users who don't want to use spirv-builder
If you would like to build the compiler, `rustc_codegen_spirv` is the relevant folder. Install the prerequisites, as above, then, `cd rustc_codegen_spirv && cargo build`. This produces an .so file, located at `./target/debug/librustc_codegen_spirv.so` (or `.dll`/`.dylib` depending on your platform).
This file is a dynamically loaded backend for rustc - you may tell rustc to use it as a backend through the `-Z codegen-backend=...` flag. To pass this to rustc through cargo, set the environment variable `RUSTFLAGS="-Z codegen-backend=$PATH_TO_FILE"`.
Then, when building a GPU crate, we need to configure some flags when we call cargo. First, we need to build libcore
ourselves - we obviously have no SPIR-V libcore installed on our system! Use the flag `-Z build-std=core`. Then, we need
to tell rustc to generate SPIR-V instead of x86 code: `--target spirv-unknown-unknown`.
Then, when building a GPU crate, we need to configure some flags when we call cargo. First, we need to build libcore ourselves - we obviously have no SPIR-V libcore installed on our system! Use the flag `-Z build-std=core`. Then, we need to tell rustc to generate SPIR-V instead of x86 code: `--target spirv-unknown-unknown`.
Overall, building your own SPIR-V crate looks like:
@ -61,3 +66,15 @@ To create a GPU crate, look at the [examples/example-shader](examples/example-sh
This is all a little convoluted, hence the [spirv-builder](spirv-builder) crate handles a lot of this.
## Using installed SPIRV-Tools
By default, all of the crates and examples in this repo will compile the `spirv-tools-sys` crate, including a lot of C++ code from [SPIRV-Tools](https://github.com/EmbarkStudios/SPIRV-Tools). If you don't want to build the C++ code because you already have [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools#downloads) installed, or just don't want to spend more time compiling, you can build/run the crate with the `use-installed-tools` feature.
```shell
cargo run \
--manifest-path examples/example-runner/Cargo.toml \
--features use-installed-tools \
--no-default-features
```
You should see `warning: use-installed-tools feature on, skipping compilation of C++ code` during the compilation, but otherwise the build will function just the same as if you compiled the C++ code, with the exception that it will fail if you don't have SPIRV-Tools installed correctly.

View File

@ -14,4 +14,3 @@ spirv-std = { path = "../../spirv-std" }
# for parallelism, not really needed though
rayon = "1.5"

View File

@ -5,6 +5,12 @@ authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
# See rustc_codegen_spirv/Cargo.toml for details on these features
[features]
default = ["use-compiled-tools"]
use-installed-tools = ["spirv-builder/use-installed-tools"]
use-compiled-tools = ["spirv-builder/use-compiled-tools"]
[dependencies]
ash = "0.31"
ash-window = "0.5"
@ -16,4 +22,4 @@ winit = "0.23.0"
ash-molten = { git = "https://github.com/EmbarkStudios/ash-molten", branch = "moltenvk-1.1.0" }
[build-dependencies]
spirv-builder = { path = "../../spirv-builder" }
spirv-builder = { path = "../../spirv-builder", default-features = false }

View File

@ -5,13 +5,19 @@ authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
# See rustc_codegen_spirv/Cargo.toml for details on these features
[features]
default = ["use-compiled-tools"]
use-installed-tools = ["spirv-builder/use-installed-tools"]
use-compiled-tools = ["spirv-builder/use-compiled-tools"]
[dependencies]
wgpu = "0.6.0"
futures = { version = "0.3", default-features = false, features = ["std", "executor"] }
winit = { version = "0.22.1", features = ["web-sys"] }
[build-dependencies]
spirv-builder = { path = "../../spirv-builder" }
spirv-builder = { path = "../../spirv-builder", default-features = false }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
wgpu-subscriber = "0.1.0"

View File

@ -12,6 +12,20 @@ repository = "https://github.com/EmbarkStudios/rust-gpu"
[lib]
crate-type = ["dylib"]
[features]
# By default, the use-compiled-tools is enabled, as doesn't require additional
# setup steps for the user. This does however mean that you will need to disable
# default features and explicitly enable `use-installed-tools` if you are using
# this in an environment with spirv-tools in PATH, and you don't want to take
# the compile time cost
default = ["use-compiled-tools"]
# If enabled, uses spirv-tools binaries installed in PATH, instead of
# compiling and linking the spirv-tools C++ code
use-installed-tools = ["spirv-tools/use-installed-tools"]
# If enabled will compile and link the C++ code for the spirv tools, the compiled
# version is preferred if both this and `use-installed-tools` are enabled
use-compiled-tools = ["spirv-tools/use-compiled-tools"]
[dependencies]
bimap = "0.5"
rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "f11f8797bd4df2d1d22cf10767b39a5119c57551" }
@ -19,6 +33,11 @@ tar = "0.4.30"
thiserror = "1.0.20"
topological-sort = "0.1"
[dependencies.spirv-tools]
version = "0.1.0"
path = "../spirv-tools"
default-features = false
[dev-dependencies]
pretty_assertions = "0.6"
tempfile = "3.1"

View File

@ -5,7 +5,7 @@ use rustc_codegen_ssa::CodegenResults;
use rustc_data_structures::owning_ref::OwningRef;
use rustc_data_structures::rustc_erase_owner;
use rustc_data_structures::sync::MetadataRef;
use rustc_errors::{DiagnosticBuilder, FatalError};
use rustc_errors::FatalError;
use rustc_middle::bug;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::cstore::NativeLib;
@ -20,7 +20,6 @@ use std::ffi::{CString, OsStr};
use std::fs::File;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::Command;
use std::sync::Arc;
use tar::{Archive, Builder, Header};
@ -124,97 +123,88 @@ fn link_exe(
codegen_results,
);
do_link(sess, &objects, &rlibs, out_filename, legalize);
let spv_binary = do_link(sess, &objects, &rlibs, legalize);
if env::var("SPIRV_OPT").is_ok() {
let spv_binary = if env::var("SPIRV_OPT").is_ok() {
let _timer = sess.timer("link_spirv_opt");
do_spirv_opt(sess, out_filename);
}
if env::var("NO_SPIRV_VAL").is_err() {
do_spirv_val(sess, out_filename);
}
}
fn do_spirv_opt(sess: &Session, filename: &Path) {
let tmp = filename.with_extension("opt.spv");
let output = output_spirv_tool(
sess,
"spirv-opt",
|cmd| {
cmd.args(&["-Os", "--eliminate-dead-const", "--strip-debug"])
.arg(&filename)
.arg("-o")
.arg(&tmp)
},
|_| {
let mut err = sess.struct_warn("spirv-opt failed, leaving as unoptimized");
err.note(&format!("module {:?}", filename));
err
},
);
if output.is_some() {
std::fs::rename(tmp, filename).unwrap();
}
}
fn do_spirv_val(sess: &Session, filename: &Path) {
output_spirv_tool(
sess,
"spirv-val",
|cmd| cmd.arg(&filename),
|status| {
let mut err = sess.struct_err(&format!("spirv-val failed with {}", status));
err.note(&format!("module {:?}", filename));
err
},
);
}
/// Runs a given SPIR-V `tool`, configured with `builder`, erroring if not found
/// or returns a non-zero exit code. All errors will be emitted using the
/// diagnostics builder provided by `diagnostics.`
fn output_spirv_tool<'a, F, D>(
sess: &Session,
tool: &str,
builder: F,
diagnostics: D,
) -> Option<std::process::Output>
where
F: FnOnce(&mut Command) -> &mut Command,
D: FnOnce(std::process::ExitStatus) -> DiagnosticBuilder<'a>,
{
let mut cmd = Command::new(tool);
(builder)(&mut cmd);
let output = match cmd.output() {
Ok(output) => output,
Err(_) => {
let mut err =
sess.struct_err(&format!("Couldn't find `{}` SPIR-V tool in PATH.", tool));
err.note(
"Please ensure that you have `spirv-tools` installed on \
your system and available in your PATH.",
);
err.emit();
return None;
}
do_spirv_opt(sess, spv_binary, out_filename)
} else {
spv_binary
};
if output.status.success() {
Some(output)
} else {
let mut diagnostics = (diagnostics)(output.status);
if !output.stdout.is_empty() {
diagnostics.note(&String::from_utf8(output.stdout).unwrap());
}
if !output.stderr.is_empty() {
diagnostics.note(&String::from_utf8(output.stderr).unwrap());
if env::var("NO_SPIRV_VAL").is_err() {
do_spirv_val(sess, &spv_binary, out_filename);
}
diagnostics.emit();
None
{
let save_modules_timer = sess.timer("link_save_modules");
if let Err(e) = std::fs::write(out_filename, crate::slice_u32_to_u8(&spv_binary)) {
let mut err = sess.struct_err("failed to serialize spirv-binary to disk");
err.note(&format!("module {:?}", out_filename));
err.note(&format!("I/O error: {:#}", e));
err.emit();
}
drop(save_modules_timer);
}
}
fn do_spirv_opt(sess: &Session, spv_binary: Vec<u32>, filename: &Path) -> Vec<u32> {
use spirv_tools::{
error,
opt::{self, Optimizer},
};
let mut optimizer = opt::create(None);
optimizer
.register_size_passes()
.register_pass(opt::Passes::EliminateDeadConstant)
.register_pass(opt::Passes::StripDebugInfo);
let result = optimizer.optimize(
&spv_binary,
&mut |msg: error::Message| {
use error::MessageLevel as Level;
// TODO: Adds spans here? Not sure how useful with binary, but maybe?
let mut err = match msg.level {
Level::Fatal | Level::InternalError => sess.struct_fatal(&msg.message),
Level::Error => sess.struct_err(&msg.message),
Level::Warning => sess.struct_warn(&msg.message),
Level::Info | Level::Debug => sess.struct_note_without_error(&msg.message),
};
err.note(&format!("module {:?}", filename));
err.emit();
},
// We currently run the validator separately after optimization or even
// if we don't run optimization, the default options don't run the validator
None,
);
match result {
Ok(binary) => Vec::from(binary.as_ref()),
Err(e) => {
let mut err = sess.struct_warn(&e.to_string());
err.note("spirv-opt failed, leaving as unoptimized");
err.note(&format!("module {:?}", filename));
spv_binary
}
}
}
fn do_spirv_val(sess: &Session, spv_binary: &[u32], filename: &Path) {
use spirv_tools::val::{self, Validator};
let validator = val::create(None);
if let Err(e) = validator.validate(spv_binary, None) {
let mut err = sess.struct_err(&e.to_string());
err.note("spirv-val failed");
err.note(&format!("module {:?}", filename));
err.emit();
}
}
@ -368,13 +358,13 @@ pub fn read_metadata(rlib: &Path) -> Result<MetadataRef, String> {
/// This is the actual guts of linking: the rest of the link-related functions are just digging through rustc's
/// shenanigans to collect all the object files we need to link.
fn do_link(
sess: &Session,
objects: &[PathBuf],
rlibs: &[PathBuf],
out_filename: &Path,
legalize: bool,
) {
fn do_link(sess: &Session, objects: &[PathBuf], rlibs: &[PathBuf], legalize: bool) -> Vec<u32> {
fn load(bytes: &[u8]) -> rspirv::dr::Module {
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_bytes(&bytes, &mut loader).unwrap();
loader.module()
}
let load_modules_timer = sess.timer("link_load_modules");
let mut modules = Vec::new();
// `objects` are the plain obj files we need to link - usually produced by the final crate.
@ -421,9 +411,9 @@ fn do_link(
mem2reg: legalize,
structurize: env::var("NO_STRUCTURIZE").is_err(),
};
let link_result = linker::link(Some(sess), &mut module_refs, &options);
let save_modules_timer = sess.timer("link_save_modules");
let assembled = match link_result {
Ok(v) => v,
Err(err) => {
@ -446,17 +436,7 @@ fn do_link(
// And finally write out the linked binary.
use rspirv::binary::Assemble;
File::create(out_filename)
.unwrap()
.write_all(crate::slice_u32_to_u8(&assembled.assemble()))
.unwrap();
drop(save_modules_timer);
fn load(bytes: &[u8]) -> rspirv::dr::Module {
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_bytes(&bytes, &mut loader).unwrap();
loader.module()
}
assembled.assemble()
}
/// As of right now, this is essentially a no-op, just plumbing through all the files.

View File

@ -26,6 +26,16 @@ pub enum LinkerError {
MultipleExports(String),
#[error("Types mismatch for {:?}", .name)]
TypeMismatch { name: String },
#[error("spirv-tools error {:#}", .0)]
#[cfg(test)]
SpirvTool(spirv_tools::Error),
}
#[cfg(test)]
impl From<spirv_tools::Error> for LinkerError {
fn from(err: spirv_tools::Error) -> Self {
Self::SpirvTool(err)
}
}
pub type Result<T> = std::result::Result<T, LinkerError>;

View File

@ -12,54 +12,26 @@ impl<'a> std::fmt::Debug for PrettyString<'a> {
}
}
fn assemble_spirv(spirv: &str) -> Vec<u8> {
use std::process::Command;
use tempfile::tempdir;
fn assemble_spirv(spirv: &str) -> Result<Vec<u8>> {
use spirv_tools::assembler::{self, Assembler};
let temp = tempdir().expect("Unable to create temp dir");
let input = temp.path().join("code.txt");
let output = temp.path().join("code.spv");
let assembler = assembler::create(None);
std::fs::write(&input, spirv).unwrap();
let spv_binary = assembler.assemble(spirv, assembler::AssemblerOptions::default())?;
let process = Command::new("spirv-as")
.arg(input.to_str().unwrap())
.arg("-o")
.arg(output.to_str().unwrap())
.output()
.expect("failed to execute process");
println!("status: {}", process.status);
println!("stdout: {}", String::from_utf8_lossy(&process.stdout));
println!("stderr: {}", String::from_utf8_lossy(&process.stderr));
assert!(process.status.success());
std::fs::read(&output).unwrap()
let contents: &[u8] = spv_binary.as_ref();
Ok(contents.to_vec())
}
#[allow(unused)]
fn validate(spirv: &[u32]) {
use std::process::Command;
use tempfile::tempdir;
use spirv_tools::val::{self, Validator};
let temp = tempdir().expect("Unable to create temp dir");
let input = temp.path().join("code.spv");
let validator = val::create(None);
let spirv = unsafe { std::slice::from_raw_parts(spirv.as_ptr() as *const u8, spirv.len() * 4) };
std::fs::write(&input, spirv).unwrap();
let process = Command::new("spirv-val.exe")
.arg(input.to_str().unwrap())
.output()
.expect("failed to execute process");
println!("status: {}", process.status);
println!("stdout: {}", String::from_utf8_lossy(&process.stdout));
println!("stderr: {}", String::from_utf8_lossy(&process.stderr));
assert!(process.status.success());
validator
.validate(spirv, None)
.expect("validation error occurred");
}
fn load(bytes: &[u8]) -> Module {
@ -126,7 +98,7 @@ fn standard() -> Result<()> {
%2 = OpTypeFloat 32
%1 = OpVariable %2 Uniform
%3 = OpVariable %2 Input"#,
);
)?;
let b = assemble_spirv(
r#"OpCapability Linkage
@ -135,7 +107,7 @@ fn standard() -> Result<()> {
%3 = OpConstant %2 42
%1 = OpVariable %2 Uniform %3
"#,
);
)?;
let result = assemble_and_link(&[&a, &b])?;
let expect = r#"%1 = OpTypeFloat 32
@ -154,7 +126,7 @@ fn not_a_lib_extra_exports() -> Result<()> {
OpDecorate %1 LinkageAttributes "foo" Export
%2 = OpTypeFloat 32
%1 = OpVariable %2 Uniform"#,
);
)?;
let result = assemble_and_link(&[&a])?;
let expect = r#"%1 = OpTypeFloat 32
@ -191,9 +163,9 @@ fn unresolved_symbol() -> Result<()> {
OpDecorate %1 LinkageAttributes "foo" Import
%2 = OpTypeFloat 32
%1 = OpVariable %2 Uniform"#,
);
)?;
let b = assemble_spirv("OpCapability Linkage");
let b = assemble_spirv("OpCapability Linkage")?;
let result = assemble_and_link(&[&a, &b]);
@ -213,7 +185,7 @@ fn type_mismatch() -> Result<()> {
%2 = OpTypeFloat 32
%1 = OpVariable %2 Uniform
%3 = OpVariable %2 Input"#,
);
)?;
let b = assemble_spirv(
r#"OpCapability Linkage
@ -222,7 +194,7 @@ fn type_mismatch() -> Result<()> {
%3 = OpConstant %2 42
%1 = OpVariable %2 Uniform %3
"#,
);
)?;
let result = assemble_and_link(&[&a, &b]);
assert_eq!(
@ -242,7 +214,7 @@ fn multiple_definitions() -> Result<()> {
%2 = OpTypeFloat 32
%1 = OpVariable %2 Uniform
%3 = OpVariable %2 Input"#,
);
)?;
let b = assemble_spirv(
r#"OpCapability Linkage
@ -251,7 +223,7 @@ fn multiple_definitions() -> Result<()> {
%2 = OpTypeFloat 32
%3 = OpConstant %2 42
%1 = OpVariable %2 Uniform %3"#,
);
)?;
let c = assemble_spirv(
r#"OpCapability Linkage
@ -259,7 +231,7 @@ fn multiple_definitions() -> Result<()> {
%2 = OpTypeFloat 32
%3 = OpConstant %2 -1
%1 = OpVariable %2 Uniform %3"#,
);
)?;
let result = assemble_and_link(&[&a, &b, &c]);
assert_eq!(
@ -277,7 +249,7 @@ fn multiple_definitions_different_types() -> Result<()> {
%2 = OpTypeFloat 32
%1 = OpVariable %2 Uniform
%3 = OpVariable %2 Input"#,
);
)?;
let b = assemble_spirv(
r#"OpCapability Linkage
@ -286,7 +258,7 @@ fn multiple_definitions_different_types() -> Result<()> {
%2 = OpTypeInt 32 0
%3 = OpConstant %2 42
%1 = OpVariable %2 Uniform %3"#,
);
)?;
let c = assemble_spirv(
r#"OpCapability Linkage
@ -294,7 +266,7 @@ fn multiple_definitions_different_types() -> Result<()> {
%2 = OpTypeFloat 32
%3 = OpConstant %2 12
%1 = OpVariable %2 Uniform %3"#,
);
)?;
let result = assemble_and_link(&[&a, &b, &c]);
assert_eq!(
@ -343,7 +315,7 @@ fn func_ctrl() -> Result<()> {
%5 = OpVariable %4 Uniform
%1 = OpFunction %2 None %3
OpFunctionEnd"#,
);
)?;
let b = assemble_spirv(
r#"OpCapability Linkage
@ -354,7 +326,7 @@ fn func_ctrl() -> Result<()> {
%4 = OpLabel
OpReturn
OpFunctionEnd"#,
);
)?;
let result = assemble_and_link(&[&a, &b])?;
@ -390,7 +362,7 @@ fn use_exported_func_param_attr() -> Result<()> {
%4 = OpFunctionParameter %6
OpFunctionEnd
"#,
);
)?;
let b = assemble_spirv(
r#"OpCapability Kernel
@ -406,7 +378,7 @@ fn use_exported_func_param_attr() -> Result<()> {
OpReturn
OpFunctionEnd
"#,
);
)?;
let result = assemble_and_link(&[&a, &b])?;
@ -454,7 +426,7 @@ fn names_and_decorations() -> Result<()> {
%4 = OpFunctionParameter %9
OpFunctionEnd
"#,
);
)?;
let b = assemble_spirv(
r#"OpCapability Kernel
@ -473,7 +445,7 @@ fn names_and_decorations() -> Result<()> {
OpReturn
OpFunctionEnd
"#,
);
)?;
let result = assemble_and_link(&[&a, &b])?;

View File

@ -5,7 +5,11 @@ authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
# See rustc_codegen_spirv/Cargo.toml for details on these features
[features]
default = ["use-compiled-tools"]
use-installed-tools = ["rustc_codegen_spirv/use-installed-tools"]
use-compiled-tools = ["rustc_codegen_spirv/use-compiled-tools"]
[dependencies]
memchr = "2.3"
@ -13,7 +17,7 @@ raw-string = "0.3.5"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# See comment in lib.rs invoke_rustc for why this is here
rustc_codegen_spirv = { path = "../rustc_codegen_spirv" }
rustc_codegen_spirv = { path = "../rustc_codegen_spirv", default-features = false }
[dev-dependencies]
lazy_static = "1.4"

View File

@ -0,0 +1,18 @@
[package]
name = "spirv-tools-sys"
version = "0.1.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
build = "build.rs"
license = "MIT OR Apache-2.0"
[features]
# Using this feature disables the compilation in the build script, but
# preserves the types so that spirv-tools can still work without needing
# to keep copies of some of the basic enums etc
use-installed-tools = []
# Forces compilation of the C++ code, even if `use-installed-tools` is enabled
use-compiled-tools = []
[build-dependencies]
cc = { version = "1.0", features = ["parallel"] }

300
spirv-tools-sys/build.rs Normal file
View File

@ -0,0 +1,300 @@
use cc::Build;
use std::path::Path;
fn add_includes(builder: &mut Build, root: &str, includes: &[&str]) {
let root = Path::new(root);
for inc in includes {
builder.include(root.join(inc));
}
}
fn add_sources(builder: &mut Build, root: &str, files: &[&str]) {
let root = Path::new(root);
builder.files(files.iter().map(|src| {
let mut p = root.join(src);
p.set_extension("cpp");
p
}));
}
fn shared(build: &mut Build) {
add_sources(
build,
"spirv-tools/source",
&[
"util/bit_vector",
"util/parse_number",
"util/string_utils",
"assembly_grammar",
"binary",
"diagnostic",
"disassemble",
"enum_string_mapping",
"ext_inst",
"extensions",
"libspirv",
"name_mapper",
"opcode",
"operand",
"parsed_operand",
"print",
"software_version",
"spirv_endian",
"spirv_fuzzer_options",
"spirv_optimizer_options",
"spirv_reducer_options",
"spirv_target_env",
"spirv_validator_options",
"table",
"text",
"text_handler",
],
);
}
fn opt(build: &mut Build) {
build.file("src/c/opt.cpp");
add_sources(
build,
"spirv-tools/source/opt",
&[
"aggressive_dead_code_elim_pass",
"amd_ext_to_khr",
"basic_block",
"block_merge_pass",
"block_merge_util",
"build_module",
"ccp_pass",
"cfg",
"cfg_cleanup_pass",
"code_sink",
"combine_access_chains",
"compact_ids_pass",
"composite",
"const_folding_rules",
"constants",
"convert_to_half_pass",
"copy_prop_arrays",
"dead_branch_elim_pass",
"dead_insert_elim_pass",
"dead_variable_elimination",
"debug_info_manager",
"decompose_initialized_variables_pass",
"decoration_manager",
"def_use_manager",
"desc_sroa",
"dominator_analysis",
"dominator_tree",
"eliminate_dead_constant_pass",
"eliminate_dead_functions_pass",
"eliminate_dead_functions_util",
"eliminate_dead_members_pass",
"feature_manager",
"fix_storage_class",
"flatten_decoration_pass",
"fold",
"fold_spec_constant_op_and_composite_pass",
"folding_rules",
"freeze_spec_constant_value_pass",
"function",
"generate_webgpu_initializers_pass",
"graphics_robust_access_pass",
"if_conversion",
"inline_exhaustive_pass",
"inline_opaque_pass",
"inline_pass",
"inst_bindless_check_pass",
"inst_buff_addr_check_pass",
"inst_debug_printf_pass",
"instruction",
"instruction_list",
"instrument_pass",
"ir_context",
"ir_loader",
"legalize_vector_shuffle_pass",
"licm_pass",
"local_access_chain_convert_pass",
"local_redundancy_elimination",
"local_single_block_elim_pass",
"local_single_store_elim_pass",
"loop_dependence",
"loop_dependence_helpers",
"loop_descriptor",
"loop_fission",
"loop_fusion",
"loop_fusion_pass",
"loop_peeling",
"loop_unroller",
"loop_unswitch_pass",
"loop_utils",
"mem_pass",
"merge_return_pass",
"module",
"optimizer",
"pass",
"pass_manager",
"pch_source_opt",
"private_to_local_pass",
"process_lines_pass",
"propagator",
"reduce_load_size",
"redundancy_elimination",
"register_pressure",
"relax_float_ops_pass",
"remove_duplicates_pass",
"replace_invalid_opc",
"scalar_analysis",
"scalar_analysis_simplification",
"scalar_replacement_pass",
"set_spec_constant_default_value_pass",
"simplification_pass",
"split_invalid_unreachable_pass",
"ssa_rewrite_pass",
"strength_reduction_pass",
"strip_atomic_counter_memory_pass",
"strip_debug_info_pass",
"strip_reflect_info_pass",
"struct_cfg_analysis",
"type_manager",
"types",
"unify_const_pass",
"upgrade_memory_model",
"value_number_table",
"vector_dce",
"workaround1209",
"wrap_opkill",
],
);
}
fn val(build: &mut Build) {
add_sources(
build,
"spirv-tools/source/val",
&[
"validate",
"validate_adjacency",
"validate_annotation",
"validate_arithmetics",
"validate_atomics",
"validate_barriers",
"validate_bitwise",
"validate_builtins",
"validate_capability",
"validate_cfg",
"validate_composites",
"validate_constants",
"validate_conversion",
"validate_debug",
"validate_decorations",
"validate_derivatives",
"validate_extensions",
"validate_execution_limitations",
"validate_function",
"validate_id",
"validate_image",
"validate_interfaces",
"validate_instruction",
"validate_layout",
"validate_literals",
"validate_logicals",
"validate_memory",
"validate_memory_semantics",
"validate_misc",
"validate_mode_setting",
"validate_non_uniform",
"validate_primitives",
"validate_scopes",
"validate_small_type_uses",
"validate_type",
"basic_block",
"construct",
"function",
"instruction",
"validation_state",
],
);
}
fn main() {
if std::env::var("CARGO_FEATURE_USE_INSTALLED_TOOLS").is_ok()
&& std::env::var("CARGO_FEATURE_USE_COMPILED_TOOLS").is_err()
{
println!("cargo:warning=use-installed-tools feature on, skipping compilation of C++ code");
return;
}
let mut build = Build::new();
add_includes(&mut build, "spirv-tools", &["", "include"]);
add_includes(&mut build, "generated", &[""]);
add_includes(
&mut build,
"spirv-headers",
&["include", "include/spirv/unified1"],
);
shared(&mut build);
val(&mut build);
opt(&mut build);
build.define("SPIRV_CHECK_CONTEXT", None);
let target_def = match std::env::var("CARGO_CFG_TARGET_OS")
.expect("CARGO_CFG_TARGET_OS not set")
.as_str()
{
"linux" => "SPIRV_LINUX",
"windows" => "SPIRV_WINDOWS",
"macos" => "SPIRV_MAC",
android if android.starts_with("android") => "SPIRV_ANDROID",
"freebsd" => "SPIRV_FREEBSD",
other => panic!("unsupported target os '{}'", other),
};
build.define(target_def, None);
let compiler = build.get_compiler();
if compiler.is_like_gnu() {
build
.flag("-Wall")
.flag("-Wextra")
.flag("-Wnon-virtual-dtor")
.flag("-Wno-missing-field-initializers")
.flag("-Werror")
.flag("-std=c++11")
.flag("-fno-exceptions")
.flag("-fno-rtti")
.flag("-Wno-long-long")
.flag("-Wshadow")
.flag("-Wundef")
.flag("-Wconversion")
.flag("-Wno-sign-conversion")
.flag("-std=gnu++11");
} else if compiler.is_like_clang() {
build
.flag("-Wextra-semi")
.flag("-Wall")
.flag("-Wextra")
.flag("-Wnon-virtual-dtor")
.flag("-Wno-missing-field-initializers")
.flag("-Wno-self-assign")
.flag("-Werror")
.flag("-std=c++11")
.flag("-fno-exceptions")
.flag("-fno-rtti")
.flag("-Wno-long-long")
.flag("-Wshadow")
.flag("-Wundef")
.flag("-Wconversion")
.flag("-Wno-sign-conversion")
.flag("-ftemplate-depth=1024")
.flag("-std=gnu++11");
}
build.cpp(true);
build.compile("spirv-tools");
}

115
spirv-tools-sys/generate.rs Normal file
View File

@ -0,0 +1,115 @@
// The spirv tools use generated code, for now we just replicate the minimum
// generation we need here by calling the *shudders* python script(s) we need
// to in a simple script and commit them to source control, as they only need
// to be regenerated when spirv-headers is updated
use std::{fs, process::Command};
fn python<S: AsRef<std::ffi::OsStr>>(args: impl IntoIterator<Item = S>) -> Result<(), i32> {
Command::new("python")
.args(args.into_iter())
.status()
.map_err(|_| -1)
.and_then(|es| {
if es.success() {
Ok(())
} else {
Err(es.code().unwrap_or(-1))
}
})
}
fn main() {
fs::create_dir_all("generated").expect("unable to create 'generated'");
python(&[
"spirv-tools/utils/update_build_version.py",
"spirv-tools",
"generated/build-version.inc",
])
.expect("failed to generate build version from spirv-headers");
enum_string_mapping("unified1");
core_table("unified1");
glsl_table("unified1");
opencl_table("unified1");
vendor_table("spv-amd-shader-explicit-vertex-parameter", None);
vendor_table("spv-amd-shader-trinary-minmax", None);
vendor_table("spv-amd-gcn-shader", None);
vendor_table("spv-amd-shader-ballot", None);
vendor_table("debuginfo", None);
vendor_table("nonsemantic.clspvreflection", None);
vendor_table("opencl.debuginfo.100", Some("CLDEBUG100_"));
registry_table();
}
fn enum_string_mapping(version: &str) {
python(&[
"spirv-tools/utils/generate_grammar_tables.py".to_owned(),
format!("--spirv-core-grammar=spirv-headers/include/spirv/{}/spirv.core.grammar.json", version),
"--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json".to_owned(),
"--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json".to_owned(),
"--extension-enum-output=generated/extension_enum.inc".to_owned(),
"--enum-string-mapping-output=generated/enum_string_mapping.inc".to_owned(),
]).expect("failed to generate enum includes from spirv-headers");
}
fn vendor_table(which: &str, prefix: Option<&str>) {
python(&[
"spirv-tools/utils/generate_grammar_tables.py".to_owned(),
format!(
"--extinst-vendor-grammar=spirv-headers/include/spirv/unified1/extinst.{}.grammar.json",
which
),
format!("--vendor-insts-output=generated/{}.insts.inc", which),
format!(
"--vendor-operand-kind-prefix={}",
prefix.unwrap_or_default()
),
])
.expect("failed to generate vendor table");
}
fn core_table(which: &str) {
python(&[
"spirv-tools/utils/generate_grammar_tables.py".to_owned(),
"--spirv-core-grammar=spirv-headers/include/spirv/unified1/spirv.core.grammar.json".to_owned(),
format!("--core-insts-output=generated/core.insts-{}.inc", which),
"--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json".to_owned(),
"--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json".to_owned(),
format!("--operand-kinds-output=generated/operand.kinds-{}.inc", which),
]).expect("failed to generate core table from spirv-headers");
}
fn registry_table() {
python(&[
"spirv-tools/utils/generate_registry_tables.py",
"--xml=spirv-headers/include/spirv/spir-v.xml",
"--generator=generated/generators.inc",
])
.expect("failed to generate core table from spirv-headers");
}
fn glsl_table(version: &str) {
python(&[
"spirv-tools/utils/generate_grammar_tables.py".to_owned(),
format!("--spirv-core-grammar=spirv-headers/include/spirv/{}/spirv.core.grammar.json", version),
"--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json".to_owned(),
"--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json".to_owned(),
format!("--extinst-glsl-grammar=spirv-headers/include/spirv/{}/extinst.glsl.std.450.grammar.json", version),
"--glsl-insts-output=generated/glsl.std.450.insts.inc".to_owned(),
]).expect("failed to generate glsl table from spirv-headers");
}
fn opencl_table(version: &str) {
python(&[
"spirv-tools/utils/generate_grammar_tables.py".to_owned(),
format!("--spirv-core-grammar=spirv-headers/include/spirv/{}/spirv.core.grammar.json", version),
"--extinst-debuginfo-grammar=spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json".to_owned(),
"--extinst-cldebuginfo100-grammar=spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json".to_owned(),
format!("--extinst-opencl-grammar=spirv-headers/include/spirv/{}/extinst.opencl.std.100.grammar.json", version),
"--opencl-insts-output=generated/opencl.std.insts.inc".to_owned(),
]).expect("failed to generate glsl table from spirv-headers");
}

23
spirv-tools-sys/generate.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
set -eu
dir=$(dirname "$(dirname "$0")")
if ! [ -d "${dir}/target" ]; then
mkdir "${dir}/target"
fi
# Compile our "script" if the binary doesn't already exist
if [ "${1-}" == "-f" ] || ! [ -f "${dir}/target/generate" ]; then
echo "Compiling generate..."
rustc -g -o "${dir}/target/generate" "${dir}/spirv-tools-sys/generate.rs"
if [ "${1-}" == "-f" ]; then
# remove the force flag when sending the arguments to generate
shift
fi
fi
gen=$(realpath "${dir}/target/generate")
(cd spirv-tools-sys && $gen "${@}")

View File

@ -0,0 +1 @@
"v2020.6", "SPIRV-Tools v2020.6 v2020.5-81-g6c992630"

View File

@ -0,0 +1,642 @@
static const SpvCapability pygen_variable_caps_Addresses[] = {SpvCapabilityAddresses};
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_AtomicFloat32AddEXTAtomicFloat64AddEXT[] = {SpvCapabilityAtomicFloat32AddEXT, SpvCapabilityAtomicFloat64AddEXT};
static const SpvCapability pygen_variable_caps_BlockingPipesINTEL[] = {SpvCapabilityBlockingPipesINTEL};
static const SpvCapability pygen_variable_caps_CooperativeMatrixNV[] = {SpvCapabilityCooperativeMatrixNV};
static const SpvCapability pygen_variable_caps_DemoteToHelperInvocationEXT[] = {SpvCapabilityDemoteToHelperInvocationEXT};
static const SpvCapability pygen_variable_caps_DerivativeControl[] = {SpvCapabilityDerivativeControl};
static const SpvCapability pygen_variable_caps_DeviceEnqueue[] = {SpvCapabilityDeviceEnqueue};
static const SpvCapability pygen_variable_caps_FPGARegINTEL[] = {SpvCapabilityFPGARegINTEL};
static const SpvCapability pygen_variable_caps_FragmentMaskAMD[] = {SpvCapabilityFragmentMaskAMD};
static const SpvCapability pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT[] = {SpvCapabilityFragmentShaderSampleInterlockEXT, SpvCapabilityFragmentShaderPixelInterlockEXT, SpvCapabilityFragmentShaderShadingRateInterlockEXT};
static const SpvCapability pygen_variable_caps_FunctionPointersINTEL[] = {SpvCapabilityFunctionPointersINTEL};
static const SpvCapability pygen_variable_caps_Geometry[] = {SpvCapabilityGeometry};
static const SpvCapability pygen_variable_caps_GeometryStreams[] = {SpvCapabilityGeometryStreams};
static const SpvCapability pygen_variable_caps_GroupNonUniform[] = {SpvCapabilityGroupNonUniform};
static const SpvCapability pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV[] = {SpvCapabilityGroupNonUniformArithmetic, SpvCapabilityGroupNonUniformClustered, SpvCapabilityGroupNonUniformPartitionedNV};
static const SpvCapability pygen_variable_caps_GroupNonUniformBallot[] = {SpvCapabilityGroupNonUniformBallot};
static const SpvCapability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {SpvCapabilityGroupNonUniformPartitionedNV};
static const SpvCapability pygen_variable_caps_GroupNonUniformQuad[] = {SpvCapabilityGroupNonUniformQuad};
static const SpvCapability pygen_variable_caps_GroupNonUniformShuffle[] = {SpvCapabilityGroupNonUniformShuffle};
static const SpvCapability pygen_variable_caps_GroupNonUniformShuffleRelative[] = {SpvCapabilityGroupNonUniformShuffleRelative};
static const SpvCapability pygen_variable_caps_GroupNonUniformVote[] = {SpvCapabilityGroupNonUniformVote};
static const SpvCapability pygen_variable_caps_Groups[] = {SpvCapabilityGroups};
static const SpvCapability pygen_variable_caps_ImageFootprintNV[] = {SpvCapabilityImageFootprintNV};
static const SpvCapability pygen_variable_caps_ImageQuery[] = {SpvCapabilityImageQuery};
static const SpvCapability pygen_variable_caps_IntegerFunctions2INTEL[] = {SpvCapabilityIntegerFunctions2INTEL};
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_Matrix[] = {SpvCapabilityMatrix};
static const SpvCapability pygen_variable_caps_MeshShadingNV[] = {SpvCapabilityMeshShadingNV};
static const SpvCapability pygen_variable_caps_NamedBarrier[] = {SpvCapabilityNamedBarrier};
static const SpvCapability pygen_variable_caps_PipeStorage[] = {SpvCapabilityPipeStorage};
static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes};
static const SpvCapability pygen_variable_caps_RayQueryProvisionalKHR[] = {SpvCapabilityRayQueryProvisionalKHR};
static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingProvisionalKHR};
static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingProvisionalKHRRayQueryProvisionalKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingProvisionalKHR, SpvCapabilityRayQueryProvisionalKHR};
static const SpvCapability pygen_variable_caps_Shader[] = {SpvCapabilityShader};
static const SpvCapability pygen_variable_caps_ShaderClockKHR[] = {SpvCapabilityShaderClockKHR};
static const SpvCapability pygen_variable_caps_SparseResidency[] = {SpvCapabilitySparseResidency};
static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL};
static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL, SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL};
static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL, SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL};
static const SpvCapability pygen_variable_caps_SubgroupBallotKHR[] = {SpvCapabilitySubgroupBallotKHR};
static const SpvCapability pygen_variable_caps_SubgroupBufferBlockIOINTEL[] = {SpvCapabilitySubgroupBufferBlockIOINTEL};
static const SpvCapability pygen_variable_caps_SubgroupDispatch[] = {SpvCapabilitySubgroupDispatch};
static const SpvCapability pygen_variable_caps_SubgroupImageBlockIOINTEL[] = {SpvCapabilitySubgroupImageBlockIOINTEL};
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_UnstructuredLoopControlsINTEL[] = {SpvCapabilityUnstructuredLoopControlsINTEL};
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};
static const spvtools::Extension pygen_variable_exts_SPV_EXT_demote_to_helper_invocation[] = {spvtools::Extension::kSPV_EXT_demote_to_helper_invocation};
static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_interlock[] = {spvtools::Extension::kSPV_EXT_fragment_shader_interlock};
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_add};
static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_decorate_string, spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1};
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_INTEL_blocking_pipes[] = {spvtools::Extension::kSPV_INTEL_blocking_pipes};
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_unstructured_loop_controls[] = {spvtools::Extension::kSPV_INTEL_unstructured_loop_controls};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_query};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {spvtools::Extension::kSPV_KHR_shader_clock};
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_terminate_invocation[] = {spvtools::Extension::kSPV_KHR_terminate_invocation};
static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix[] = {spvtools::Extension::kSPV_NV_cooperative_matrix};
static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader};
static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing, spvtools::Extension::kSPV_KHR_ray_tracing};
static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query[] = {spvtools::Extension::kSPV_NV_ray_tracing, spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_KHR_ray_query};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footprint[] = {spvtools::Extension::kSPV_NV_shader_image_footprint};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_subgroup_partitioned[] = {spvtools::Extension::kSPV_NV_shader_subgroup_partitioned};
static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"Nop", SpvOpNop, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Undef", SpvOpUndef, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SourceContinued", SpvOpSourceContinued, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Source", SpvOpSource, 0, nullptr, 4, {SPV_OPERAND_TYPE_SOURCE_LANGUAGE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SourceExtension", SpvOpSourceExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Name", SpvOpName, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MemberName", SpvOpMemberName, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"String", SpvOpString, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Line", SpvOpLine, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Extension", SpvOpExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ExtInstImport", SpvOpExtInstImport, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ExtInst", SpvOpExtInst, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MemoryModel", SpvOpMemoryModel, 0, nullptr, 2, {SPV_OPERAND_TYPE_ADDRESSING_MODEL, SPV_OPERAND_TYPE_MEMORY_MODEL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"EntryPoint", SpvOpEntryPoint, 0, nullptr, 4, {SPV_OPERAND_TYPE_EXECUTION_MODEL, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ExecutionMode", SpvOpExecutionMode, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Capability", SpvOpCapability, 0, nullptr, 1, {SPV_OPERAND_TYPE_CAPABILITY}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeVoid", SpvOpTypeVoid, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeBool", SpvOpTypeBool, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeInt", SpvOpTypeInt, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeFloat", SpvOpTypeFloat, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeVector", SpvOpTypeVector, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeMatrix", SpvOpTypeMatrix, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeImage", SpvOpTypeImage, 0, nullptr, 9, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DIMENSIONALITY, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeSampler", SpvOpTypeSampler, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeSampledImage", SpvOpTypeSampledImage, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeArray", SpvOpTypeArray, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeRuntimeArray", SpvOpTypeRuntimeArray, 1, pygen_variable_caps_Shader, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeStruct", SpvOpTypeStruct, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeOpaque", SpvOpTypeOpaque, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypePointer", SpvOpTypePointer, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeFunction", SpvOpTypeFunction, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeEvent", SpvOpTypeEvent, 1, pygen_variable_caps_Kernel, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeDeviceEvent", SpvOpTypeDeviceEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeReserveId", SpvOpTypeReserveId, 1, pygen_variable_caps_Pipes, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeQueue", SpvOpTypeQueue, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypePipe", SpvOpTypePipe, 1, pygen_variable_caps_Pipes, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeForwardPointer", SpvOpTypeForwardPointer, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConstantTrue", SpvOpConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConstantFalse", SpvOpConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Constant", SpvOpConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConstantComposite", SpvOpConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConstantSampler", SpvOpConstantSampler, 1, pygen_variable_caps_LiteralSampler, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConstantNull", SpvOpConstantNull, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SpecConstantTrue", SpvOpSpecConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SpecConstantFalse", SpvOpSpecConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SpecConstant", SpvOpSpecConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SpecConstantComposite", SpvOpSpecConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SpecConstantOp", SpvOpSpecConstantOp, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Function", SpvOpFunction, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_FUNCTION_CONTROL, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FunctionParameter", SpvOpFunctionParameter, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FunctionEnd", SpvOpFunctionEnd, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FunctionCall", SpvOpFunctionCall, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Variable", SpvOpVariable, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageTexelPointer", SpvOpImageTexelPointer, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Load", SpvOpLoad, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Store", SpvOpStore, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CopyMemory", SpvOpCopyMemory, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CopyMemorySized", SpvOpCopyMemorySized, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AccessChain", SpvOpAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"InBoundsAccessChain", SpvOpInBoundsAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"PtrAccessChain", SpvOpPtrAccessChain, 4, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ArrayLength", SpvOpArrayLength, 1, pygen_variable_caps_Shader, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GenericPtrMemSemantics", SpvOpGenericPtrMemSemantics, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"InBoundsPtrAccessChain", SpvOpInBoundsPtrAccessChain, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Decorate", SpvOpDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MemberDecorate", SpvOpMemberDecorate, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"DecorationGroup", SpvOpDecorationGroup, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupDecorate", SpvOpGroupDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupMemberDecorate", SpvOpGroupMemberDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"VectorExtractDynamic", SpvOpVectorExtractDynamic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"VectorInsertDynamic", SpvOpVectorInsertDynamic, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"VectorShuffle", SpvOpVectorShuffle, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CompositeConstruct", SpvOpCompositeConstruct, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CompositeExtract", SpvOpCompositeExtract, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CompositeInsert", SpvOpCompositeInsert, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CopyObject", SpvOpCopyObject, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Transpose", SpvOpTranspose, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SampledImage", SpvOpSampledImage, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSampleImplicitLod", SpvOpImageSampleImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSampleExplicitLod", SpvOpImageSampleExplicitLod, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSampleDrefImplicitLod", SpvOpImageSampleDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSampleDrefExplicitLod", SpvOpImageSampleDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSampleProjImplicitLod", SpvOpImageSampleProjImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSampleProjExplicitLod", SpvOpImageSampleProjExplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSampleProjDrefImplicitLod", SpvOpImageSampleProjDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSampleProjDrefExplicitLod", SpvOpImageSampleProjDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageFetch", SpvOpImageFetch, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageGather", SpvOpImageGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageDrefGather", SpvOpImageDrefGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageRead", SpvOpImageRead, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageWrite", SpvOpImageWrite, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Image", SpvOpImage, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageQueryFormat", SpvOpImageQueryFormat, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageQueryOrder", SpvOpImageQueryOrder, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageQuerySizeLod", SpvOpImageQuerySizeLod, 2, pygen_variable_caps_KernelImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageQuerySize", SpvOpImageQuerySize, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageQueryLod", SpvOpImageQueryLod, 1, pygen_variable_caps_ImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageQueryLevels", SpvOpImageQueryLevels, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageQuerySamples", SpvOpImageQuerySamples, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertFToU", SpvOpConvertFToU, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertFToS", SpvOpConvertFToS, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertSToF", SpvOpConvertSToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertUToF", SpvOpConvertUToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"UConvert", SpvOpUConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SConvert", SpvOpSConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FConvert", SpvOpFConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"QuantizeToF16", SpvOpQuantizeToF16, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertPtrToU", SpvOpConvertPtrToU, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SatConvertSToU", SpvOpSatConvertSToU, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SatConvertUToS", SpvOpSatConvertUToS, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertUToPtr", SpvOpConvertUToPtr, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"PtrCastToGeneric", SpvOpPtrCastToGeneric, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GenericCastToPtr", SpvOpGenericCastToPtr, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GenericCastToPtrExplicit", SpvOpGenericCastToPtrExplicit, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Bitcast", SpvOpBitcast, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SNegate", SpvOpSNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FNegate", SpvOpFNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IAdd", SpvOpIAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FAdd", SpvOpFAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ISub", SpvOpISub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FSub", SpvOpFSub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IMul", SpvOpIMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FMul", SpvOpFMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"UDiv", SpvOpUDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SDiv", SpvOpSDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FDiv", SpvOpFDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"UMod", SpvOpUMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SRem", SpvOpSRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SMod", SpvOpSMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FRem", SpvOpFRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FMod", SpvOpFMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"VectorTimesScalar", SpvOpVectorTimesScalar, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MatrixTimesScalar", SpvOpMatrixTimesScalar, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"VectorTimesMatrix", SpvOpVectorTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MatrixTimesVector", SpvOpMatrixTimesVector, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MatrixTimesMatrix", SpvOpMatrixTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"OuterProduct", SpvOpOuterProduct, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Dot", SpvOpDot, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IAddCarry", SpvOpIAddCarry, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ISubBorrow", SpvOpISubBorrow, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"UMulExtended", SpvOpUMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SMulExtended", SpvOpSMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Any", SpvOpAny, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"All", SpvOpAll, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IsNan", SpvOpIsNan, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IsInf", SpvOpIsInf, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IsFinite", SpvOpIsFinite, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IsNormal", SpvOpIsNormal, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SignBitSet", SpvOpSignBitSet, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"LessOrGreater", SpvOpLessOrGreater, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Ordered", SpvOpOrdered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Unordered", SpvOpUnordered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"LogicalEqual", SpvOpLogicalEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"LogicalNotEqual", SpvOpLogicalNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"LogicalOr", SpvOpLogicalOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"LogicalAnd", SpvOpLogicalAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"LogicalNot", SpvOpLogicalNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Select", SpvOpSelect, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IEqual", SpvOpIEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"INotEqual", SpvOpINotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"UGreaterThan", SpvOpUGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SGreaterThan", SpvOpSGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"UGreaterThanEqual", SpvOpUGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SGreaterThanEqual", SpvOpSGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ULessThan", SpvOpULessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SLessThan", SpvOpSLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ULessThanEqual", SpvOpULessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SLessThanEqual", SpvOpSLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FOrdEqual", SpvOpFOrdEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FUnordEqual", SpvOpFUnordEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FOrdNotEqual", SpvOpFOrdNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FUnordNotEqual", SpvOpFUnordNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FOrdLessThan", SpvOpFOrdLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FUnordLessThan", SpvOpFUnordLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FOrdGreaterThan", SpvOpFOrdGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FUnordGreaterThan", SpvOpFUnordGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FOrdLessThanEqual", SpvOpFOrdLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FUnordLessThanEqual", SpvOpFUnordLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FOrdGreaterThanEqual", SpvOpFOrdGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FUnordGreaterThanEqual", SpvOpFUnordGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ShiftRightLogical", SpvOpShiftRightLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ShiftRightArithmetic", SpvOpShiftRightArithmetic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ShiftLeftLogical", SpvOpShiftLeftLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BitwiseOr", SpvOpBitwiseOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BitwiseXor", SpvOpBitwiseXor, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BitwiseAnd", SpvOpBitwiseAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Not", SpvOpNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BitFieldInsert", SpvOpBitFieldInsert, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BitFieldSExtract", SpvOpBitFieldSExtract, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BitFieldUExtract", SpvOpBitFieldUExtract, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BitReverse", SpvOpBitReverse, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BitCount", SpvOpBitCount, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"DPdx", SpvOpDPdx, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"DPdy", SpvOpDPdy, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Fwidth", SpvOpFwidth, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"DPdxFine", SpvOpDPdxFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"DPdyFine", SpvOpDPdyFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FwidthFine", SpvOpFwidthFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"DPdxCoarse", SpvOpDPdxCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"DPdyCoarse", SpvOpDPdyCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FwidthCoarse", SpvOpFwidthCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"EmitVertex", SpvOpEmitVertex, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"EndPrimitive", SpvOpEndPrimitive, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"EmitStreamVertex", SpvOpEmitStreamVertex, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"EndStreamPrimitive", SpvOpEndStreamPrimitive, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ControlBarrier", SpvOpControlBarrier, 0, nullptr, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MemoryBarrier", SpvOpMemoryBarrier, 0, nullptr, 2, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicLoad", SpvOpAtomicLoad, 0, nullptr, 5, {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}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicStore", SpvOpAtomicStore, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicExchange", SpvOpAtomicExchange, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicCompareExchange", SpvOpAtomicCompareExchange, 0, nullptr, 8, {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_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicCompareExchangeWeak", SpvOpAtomicCompareExchangeWeak, 1, pygen_variable_caps_Kernel, 8, {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_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), SPV_SPIRV_VERSION_WORD(1,3)},
{"AtomicIIncrement", SpvOpAtomicIIncrement, 0, nullptr, 5, {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}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicIDecrement", SpvOpAtomicIDecrement, 0, nullptr, 5, {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}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicIAdd", SpvOpAtomicIAdd, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicISub", SpvOpAtomicISub, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicSMin", SpvOpAtomicSMin, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicUMin", SpvOpAtomicUMin, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicSMax", SpvOpAtomicSMax, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicUMax", SpvOpAtomicUMax, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicAnd", SpvOpAtomicAnd, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicOr", SpvOpAtomicOr, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicXor", SpvOpAtomicXor, 0, nullptr, 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, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Phi", SpvOpPhi, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"LoopMerge", SpvOpLoopMerge, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LOOP_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SelectionMerge", SpvOpSelectionMerge, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SELECTION_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Label", SpvOpLabel, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Branch", SpvOpBranch, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BranchConditional", SpvOpBranchConditional, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Switch", SpvOpSwitch, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Kill", SpvOpKill, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Return", SpvOpReturn, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ReturnValue", SpvOpReturnValue, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Unreachable", SpvOpUnreachable, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"LifetimeStart", SpvOpLifetimeStart, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"LifetimeStop", SpvOpLifetimeStop, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupAsyncCopy", SpvOpGroupAsyncCopy, 1, pygen_variable_caps_Kernel, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupWaitEvents", SpvOpGroupWaitEvents, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupAll", SpvOpGroupAll, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupAny", SpvOpGroupAny, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupBroadcast", SpvOpGroupBroadcast, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupIAdd", SpvOpGroupIAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupFAdd", SpvOpGroupFAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupFMin", SpvOpGroupFMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupUMin", SpvOpGroupUMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupSMin", SpvOpGroupSMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupFMax", SpvOpGroupFMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupUMax", SpvOpGroupUMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupSMax", SpvOpGroupSMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ReadPipe", SpvOpReadPipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"WritePipe", SpvOpWritePipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ReservedReadPipe", SpvOpReservedReadPipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ReservedWritePipe", SpvOpReservedWritePipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ReserveReadPipePackets", SpvOpReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ReserveWritePipePackets", SpvOpReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CommitReadPipe", SpvOpCommitReadPipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CommitWritePipe", SpvOpCommitWritePipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IsValidReserveId", SpvOpIsValidReserveId, 1, pygen_variable_caps_Pipes, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GetNumPipePackets", SpvOpGetNumPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GetMaxPipePackets", SpvOpGetMaxPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupReserveReadPipePackets", SpvOpGroupReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupReserveWritePipePackets", SpvOpGroupReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupCommitReadPipe", SpvOpGroupCommitReadPipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GroupCommitWritePipe", SpvOpGroupCommitWritePipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"EnqueueMarker", SpvOpEnqueueMarker, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"EnqueueKernel", SpvOpEnqueueKernel, 1, pygen_variable_caps_DeviceEnqueue, 13, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GetKernelNDrangeSubGroupCount", SpvOpGetKernelNDrangeSubGroupCount, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GetKernelNDrangeMaxSubGroupSize", SpvOpGetKernelNDrangeMaxSubGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GetKernelWorkGroupSize", SpvOpGetKernelWorkGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GetKernelPreferredWorkGroupSizeMultiple", SpvOpGetKernelPreferredWorkGroupSizeMultiple, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"RetainEvent", SpvOpRetainEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ReleaseEvent", SpvOpReleaseEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CreateUserEvent", SpvOpCreateUserEvent, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"IsValidEvent", SpvOpIsValidEvent, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SetUserEventStatus", SpvOpSetUserEventStatus, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"CaptureEventProfilingInfo", SpvOpCaptureEventProfilingInfo, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GetDefaultQueue", SpvOpGetDefaultQueue, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"BuildNDRange", SpvOpBuildNDRange, 1, pygen_variable_caps_DeviceEnqueue, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSparseSampleImplicitLod", SpvOpImageSparseSampleImplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSparseSampleExplicitLod", SpvOpImageSparseSampleExplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSparseSampleDrefImplicitLod", SpvOpImageSparseSampleDrefImplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSparseSampleDrefExplicitLod", SpvOpImageSparseSampleDrefExplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSparseSampleProjImplicitLod", SpvOpImageSparseSampleProjImplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ImageSparseSampleProjExplicitLod", SpvOpImageSparseSampleProjExplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ImageSparseSampleProjDrefImplicitLod", SpvOpImageSparseSampleProjDrefImplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ImageSparseSampleProjDrefExplicitLod", SpvOpImageSparseSampleProjDrefExplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ImageSparseFetch", SpvOpImageSparseFetch, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSparseGather", SpvOpImageSparseGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSparseDrefGather", SpvOpImageSparseDrefGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSparseTexelsResident", SpvOpImageSparseTexelsResident, 1, pygen_variable_caps_SparseResidency, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"NoLine", SpvOpNoLine, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicFlagTestAndSet", SpvOpAtomicFlagTestAndSet, 1, pygen_variable_caps_Kernel, 5, {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}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicFlagClear", SpvOpAtomicFlagClear, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageSparseRead", SpvOpImageSparseRead, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SizeOf", SpvOpSizeOf, 1, pygen_variable_caps_Addresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"TypePipeStorage", SpvOpTypePipeStorage, 1, pygen_variable_caps_PipeStorage, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"ConstantPipeStorage", SpvOpConstantPipeStorage, 1, pygen_variable_caps_PipeStorage, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"CreatePipeFromPipeStorage", SpvOpCreatePipeFromPipeStorage, 1, pygen_variable_caps_PipeStorage, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"GetKernelLocalSizeForSubgroupCount", SpvOpGetKernelLocalSizeForSubgroupCount, 1, pygen_variable_caps_SubgroupDispatch, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"GetKernelMaxNumSubgroups", SpvOpGetKernelMaxNumSubgroups, 1, pygen_variable_caps_SubgroupDispatch, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"TypeNamedBarrier", SpvOpTypeNamedBarrier, 1, pygen_variable_caps_NamedBarrier, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"NamedBarrierInitialize", SpvOpNamedBarrierInitialize, 1, pygen_variable_caps_NamedBarrier, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"MemoryNamedBarrier", SpvOpMemoryNamedBarrier, 1, pygen_variable_caps_NamedBarrier, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"ModuleProcessed", SpvOpModuleProcessed, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu},
{"ExecutionModeId", SpvOpExecutionModeId, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu},
{"DecorateId", SpvOpDecorateId, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu},
{"GroupNonUniformElect", SpvOpGroupNonUniformElect, 1, pygen_variable_caps_GroupNonUniform, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformAll", SpvOpGroupNonUniformAll, 1, pygen_variable_caps_GroupNonUniformVote, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformAny", SpvOpGroupNonUniformAny, 1, pygen_variable_caps_GroupNonUniformVote, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformAllEqual", SpvOpGroupNonUniformAllEqual, 1, pygen_variable_caps_GroupNonUniformVote, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBroadcast", SpvOpGroupNonUniformBroadcast, 1, pygen_variable_caps_GroupNonUniformBallot, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBroadcastFirst", SpvOpGroupNonUniformBroadcastFirst, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBallot", SpvOpGroupNonUniformBallot, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformInverseBallot", SpvOpGroupNonUniformInverseBallot, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBallotBitExtract", SpvOpGroupNonUniformBallotBitExtract, 1, pygen_variable_caps_GroupNonUniformBallot, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBallotBitCount", SpvOpGroupNonUniformBallotBitCount, 1, pygen_variable_caps_GroupNonUniformBallot, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBallotFindLSB", SpvOpGroupNonUniformBallotFindLSB, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBallotFindMSB", SpvOpGroupNonUniformBallotFindMSB, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformShuffle", SpvOpGroupNonUniformShuffle, 1, pygen_variable_caps_GroupNonUniformShuffle, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformShuffleXor", SpvOpGroupNonUniformShuffleXor, 1, pygen_variable_caps_GroupNonUniformShuffle, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformShuffleUp", SpvOpGroupNonUniformShuffleUp, 1, pygen_variable_caps_GroupNonUniformShuffleRelative, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformShuffleDown", SpvOpGroupNonUniformShuffleDown, 1, pygen_variable_caps_GroupNonUniformShuffleRelative, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformIAdd", SpvOpGroupNonUniformIAdd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformFAdd", SpvOpGroupNonUniformFAdd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformIMul", SpvOpGroupNonUniformIMul, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformFMul", SpvOpGroupNonUniformFMul, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformSMin", SpvOpGroupNonUniformSMin, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformUMin", SpvOpGroupNonUniformUMin, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformFMin", SpvOpGroupNonUniformFMin, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformSMax", SpvOpGroupNonUniformSMax, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformUMax", SpvOpGroupNonUniformUMax, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformFMax", SpvOpGroupNonUniformFMax, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBitwiseAnd", SpvOpGroupNonUniformBitwiseAnd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBitwiseOr", SpvOpGroupNonUniformBitwiseOr, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformBitwiseXor", SpvOpGroupNonUniformBitwiseXor, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformLogicalAnd", SpvOpGroupNonUniformLogicalAnd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformLogicalOr", SpvOpGroupNonUniformLogicalOr, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformLogicalXor", SpvOpGroupNonUniformLogicalXor, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformQuadBroadcast", SpvOpGroupNonUniformQuadBroadcast, 1, pygen_variable_caps_GroupNonUniformQuad, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformQuadSwap", SpvOpGroupNonUniformQuadSwap, 1, pygen_variable_caps_GroupNonUniformQuad, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"CopyLogical", SpvOpCopyLogical, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"PtrEqual", SpvOpPtrEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"PtrNotEqual", SpvOpPtrNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"PtrDiff", SpvOpPtrDiff, 3, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBuffer, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"TerminateInvocation", SpvOpTerminateInvocation, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_terminate_invocation, 0xffffffffu, 0xffffffffu},
{"SubgroupBallotKHR", SpvOpSubgroupBallotKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu},
{"SubgroupFirstInvocationKHR", SpvOpSubgroupFirstInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu},
{"SubgroupAllKHR", SpvOpSubgroupAllKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu},
{"SubgroupAnyKHR", SpvOpSubgroupAnyKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu},
{"SubgroupAllEqualKHR", SpvOpSubgroupAllEqualKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu},
{"SubgroupReadInvocationKHR", SpvOpSubgroupReadInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 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_shader_ballot, 0xffffffffu, 0xffffffffu},
{"TypeRayQueryProvisionalKHR", SpvOpTypeRayQueryProvisionalKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"RayQueryInitializeKHR", SpvOpRayQueryInitializeKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 8, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"RayQueryTerminateKHR", SpvOpRayQueryTerminateKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"RayQueryGenerateIntersectionKHR", SpvOpRayQueryGenerateIntersectionKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"RayQueryConfirmIntersectionKHR", SpvOpRayQueryConfirmIntersectionKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"RayQueryProceedKHR", SpvOpRayQueryProceedKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionTypeKHR", SpvOpRayQueryGetIntersectionTypeKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"GroupIAddNonUniformAMD", SpvOpGroupIAddNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
{"GroupFAddNonUniformAMD", SpvOpGroupFAddNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
{"GroupFMinNonUniformAMD", SpvOpGroupFMinNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
{"GroupUMinNonUniformAMD", SpvOpGroupUMinNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
{"GroupSMinNonUniformAMD", SpvOpGroupSMinNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
{"GroupFMaxNonUniformAMD", SpvOpGroupFMaxNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
{"GroupUMaxNonUniformAMD", SpvOpGroupUMaxNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
{"GroupSMaxNonUniformAMD", SpvOpGroupSMaxNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
{"FragmentMaskFetchAMD", SpvOpFragmentMaskFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 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_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu},
{"FragmentFetchAMD", SpvOpFragmentFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu},
{"ReadClockKHR", SpvOpReadClockKHR, 1, pygen_variable_caps_ShaderClockKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_clock, 0xffffffffu, 0xffffffffu},
{"ImageSampleFootprintNV", SpvOpImageSampleFootprintNV, 1, pygen_variable_caps_ImageFootprintNV, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_image_footprint, 0xffffffffu, 0xffffffffu},
{"GroupNonUniformPartitionNV", SpvOpGroupNonUniformPartitionNV, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, 0xffffffffu, 0xffffffffu},
{"WritePackedPrimitiveIndices4x8NV", SpvOpWritePackedPrimitiveIndices4x8NV, 1, pygen_variable_caps_MeshShadingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_mesh_shader, 0xffffffffu, 0xffffffffu},
{"ReportIntersectionKHR", SpvOpReportIntersectionKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"ReportIntersectionNV", SpvOpReportIntersectionNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"IgnoreIntersectionKHR", SpvOpIgnoreIntersectionKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, {}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"IgnoreIntersectionNV", SpvOpIgnoreIntersectionNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, {}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TerminateRayKHR", SpvOpTerminateRayKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, {}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TerminateRayNV", SpvOpTerminateRayNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 0, {}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TraceNV", SpvOpTraceNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 11, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TraceRayKHR", SpvOpTraceRayKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 11, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TypeAccelerationStructureKHR", SpvOpTypeAccelerationStructureKHR, 3, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHRRayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"TypeAccelerationStructureNV", SpvOpTypeAccelerationStructureNV, 3, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHRRayQueryProvisionalKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"ExecuteCallableKHR", SpvOpExecuteCallableKHR, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"ExecuteCallableNV", SpvOpExecuteCallableNV, 2, pygen_variable_caps_RayTracingNVRayTracingProvisionalKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TypeCooperativeMatrixNV", SpvOpTypeCooperativeMatrixNV, 1, pygen_variable_caps_CooperativeMatrixNV, 5, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixLoadNV", SpvOpCooperativeMatrixLoadNV, 1, pygen_variable_caps_CooperativeMatrixNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 1, 1, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixStoreNV", SpvOpCooperativeMatrixStoreNV, 1, pygen_variable_caps_CooperativeMatrixNV, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixMulAddNV", SpvOpCooperativeMatrixMulAddNV, 1, pygen_variable_caps_CooperativeMatrixNV, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixLengthNV", SpvOpCooperativeMatrixLengthNV, 1, pygen_variable_caps_CooperativeMatrixNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu},
{"BeginInvocationInterlockEXT", SpvOpBeginInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu},
{"EndInvocationInterlockEXT", SpvOpEndInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu},
{"DemoteToHelperInvocationEXT", SpvOpDemoteToHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, 0xffffffffu, 0xffffffffu},
{"IsHelperInvocationEXT", SpvOpIsHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, 0xffffffffu, 0xffffffffu},
{"SubgroupShuffleINTEL", SpvOpSubgroupShuffleINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 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},
{"SubgroupShuffleDownINTEL", SpvOpSubgroupShuffleDownINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupShuffleUpINTEL", SpvOpSubgroupShuffleUpINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupShuffleXorINTEL", SpvOpSubgroupShuffleXorINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 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},
{"SubgroupBlockReadINTEL", SpvOpSubgroupBlockReadINTEL, 1, pygen_variable_caps_SubgroupBufferBlockIOINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupBlockWriteINTEL", SpvOpSubgroupBlockWriteINTEL, 1, pygen_variable_caps_SubgroupBufferBlockIOINTEL, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupImageBlockReadINTEL", SpvOpSubgroupImageBlockReadINTEL, 1, pygen_variable_caps_SubgroupImageBlockIOINTEL, 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},
{"SubgroupImageBlockWriteINTEL", SpvOpSubgroupImageBlockWriteINTEL, 1, pygen_variable_caps_SubgroupImageBlockIOINTEL, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupImageMediaBlockReadINTEL", SpvOpSubgroupImageMediaBlockReadINTEL, 1, pygen_variable_caps_SubgroupImageMediaBlockIOINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupImageMediaBlockWriteINTEL", SpvOpSubgroupImageMediaBlockWriteINTEL, 1, pygen_variable_caps_SubgroupImageMediaBlockIOINTEL, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"UCountLeadingZerosINTEL", SpvOpUCountLeadingZerosINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"UCountTrailingZerosINTEL", SpvOpUCountTrailingZerosINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"AbsISubINTEL", SpvOpAbsISubINTEL, 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},
{"AbsUSubINTEL", SpvOpAbsUSubINTEL, 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},
{"IAddSatINTEL", SpvOpIAddSatINTEL, 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},
{"UAddSatINTEL", SpvOpUAddSatINTEL, 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},
{"IAverageINTEL", SpvOpIAverageINTEL, 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},
{"UAverageINTEL", SpvOpUAverageINTEL, 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},
{"IAverageRoundedINTEL", SpvOpIAverageRoundedINTEL, 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},
{"UAverageRoundedINTEL", SpvOpUAverageRoundedINTEL, 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},
{"ISubSatINTEL", SpvOpISubSatINTEL, 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},
{"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},
{"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},
{"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},
{"MemberDecorateStringGOOGLE", SpvOpMemberDecorateStringGOOGLE, 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},
{"VmeImageINTEL", SpvOpVmeImageINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"TypeVmeImageINTEL", SpvOpTypeVmeImageINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcImePayloadINTEL", SpvOpTypeAvcImePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcRefPayloadINTEL", SpvOpTypeAvcRefPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcSicPayloadINTEL", SpvOpTypeAvcSicPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcMcePayloadINTEL", SpvOpTypeAvcMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcMceResultINTEL", SpvOpTypeAvcMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcImeResultINTEL", SpvOpTypeAvcImeResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcImeResultSingleReferenceStreamoutINTEL", SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcImeResultDualReferenceStreamoutINTEL", SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcImeSingleReferenceStreaminINTEL", SpvOpTypeAvcImeSingleReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcImeDualReferenceStreaminINTEL", SpvOpTypeAvcImeDualReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcRefResultINTEL", SpvOpTypeAvcRefResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAvcSicResultINTEL", SpvOpTypeAvcSicResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL", SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcMceGetDefaultInterShapePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcMceSetInterShapePenaltyINTEL", SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcMceSetInterDirectionPenaltyINTEL", SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 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},
{"SubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL", SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL", SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL", SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL", SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMceSetMotionVectorCostFunctionINTEL", SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 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},
{"SubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL", SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMceSetAcOnlyHaarINTEL", SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL, 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},
{"SubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL", SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL", SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL", SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcMceConvertToImePayloadINTEL", SpvOpSubgroupAvcMceConvertToImePayloadINTEL, 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},
{"SubgroupAvcMceConvertToImeResultINTEL", SpvOpSubgroupAvcMceConvertToImeResultINTEL, 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},
{"SubgroupAvcMceConvertToRefPayloadINTEL", SpvOpSubgroupAvcMceConvertToRefPayloadINTEL, 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},
{"SubgroupAvcMceConvertToRefResultINTEL", SpvOpSubgroupAvcMceConvertToRefResultINTEL, 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},
{"SubgroupAvcMceConvertToSicPayloadINTEL", SpvOpSubgroupAvcMceConvertToSicPayloadINTEL, 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},
{"SubgroupAvcMceConvertToSicResultINTEL", SpvOpSubgroupAvcMceConvertToSicResultINTEL, 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},
{"SubgroupAvcMceGetMotionVectorsINTEL", SpvOpSubgroupAvcMceGetMotionVectorsINTEL, 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},
{"SubgroupAvcMceGetInterDistortionsINTEL", SpvOpSubgroupAvcMceGetInterDistortionsINTEL, 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},
{"SubgroupAvcMceGetBestInterDistortionsINTEL", SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL, 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},
{"SubgroupAvcMceGetInterMajorShapeINTEL", SpvOpSubgroupAvcMceGetInterMajorShapeINTEL, 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},
{"SubgroupAvcMceGetInterMinorShapeINTEL", SpvOpSubgroupAvcMceGetInterMinorShapeINTEL, 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},
{"SubgroupAvcMceGetInterDirectionsINTEL", SpvOpSubgroupAvcMceGetInterDirectionsINTEL, 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},
{"SubgroupAvcMceGetInterMotionVectorCountINTEL", SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL, 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},
{"SubgroupAvcMceGetInterReferenceIdsINTEL", SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL, 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},
{"SubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL", SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeInitializeINTEL", SpvOpSubgroupAvcImeInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeSetSingleReferenceINTEL", SpvOpSubgroupAvcImeSetSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeSetDualReferenceINTEL", SpvOpSubgroupAvcImeSetDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeRefWindowSizeINTEL", SpvOpSubgroupAvcImeRefWindowSizeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcImeAdjustRefOffsetINTEL", SpvOpSubgroupAvcImeAdjustRefOffsetINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeConvertToMcePayloadINTEL", SpvOpSubgroupAvcImeConvertToMcePayloadINTEL, 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},
{"SubgroupAvcImeSetMaxMotionVectorCountINTEL", SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcImeSetUnidirectionalMixDisableINTEL", SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL, 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},
{"SubgroupAvcImeSetEarlySearchTerminationThresholdINTEL", SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcImeSetWeightedSadINTEL", SpvOpSubgroupAvcImeSetWeightedSadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcImeEvaluateWithSingleReferenceINTEL", SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeEvaluateWithDualReferenceINTEL", SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL", SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL", SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL", SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL", SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL", SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL", SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeConvertToMceResultINTEL", SpvOpSubgroupAvcImeConvertToMceResultINTEL, 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},
{"SubgroupAvcImeGetSingleReferenceStreaminINTEL", SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL, 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},
{"SubgroupAvcImeGetDualReferenceStreaminINTEL", SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL, 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},
{"SubgroupAvcImeStripSingleReferenceStreamoutINTEL", SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL, 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},
{"SubgroupAvcImeStripDualReferenceStreamoutINTEL", SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL, 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},
{"SubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL", SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL", SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL", SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL", SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL", SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL", SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcImeGetBorderReachedINTEL", SpvOpSubgroupAvcImeGetBorderReachedINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcImeGetTruncatedSearchIndicationINTEL", SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL, 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},
{"SubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL", SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL, 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},
{"SubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL", SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL, 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},
{"SubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL", SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL, 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},
{"SubgroupAvcFmeInitializeINTEL", SpvOpSubgroupAvcFmeInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcBmeInitializeINTEL", SpvOpSubgroupAvcBmeInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcRefConvertToMcePayloadINTEL", SpvOpSubgroupAvcRefConvertToMcePayloadINTEL, 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},
{"SubgroupAvcRefSetBidirectionalMixDisableINTEL", SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL, 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},
{"SubgroupAvcRefSetBilinearFilterEnableINTEL", SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL, 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},
{"SubgroupAvcRefEvaluateWithSingleReferenceINTEL", SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcRefEvaluateWithDualReferenceINTEL", SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcRefEvaluateWithMultiReferenceINTEL", SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL", SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcRefConvertToMceResultINTEL", SpvOpSubgroupAvcRefConvertToMceResultINTEL, 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},
{"SubgroupAvcSicInitializeINTEL", SpvOpSubgroupAvcSicInitializeINTEL, 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},
{"SubgroupAvcSicConfigureSkcINTEL", SpvOpSubgroupAvcSicConfigureSkcINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicConfigureIpeLumaINTEL", SpvOpSubgroupAvcSicConfigureIpeLumaINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicConfigureIpeLumaChromaINTEL", SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 13, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicGetMotionVectorMaskINTEL", SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcSicConvertToMcePayloadINTEL", SpvOpSubgroupAvcSicConvertToMcePayloadINTEL, 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},
{"SubgroupAvcSicSetIntraLumaShapePenaltyINTEL", SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcSicSetIntraLumaModeCostFunctionINTEL", SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicSetIntraChromaModeCostFunctionINTEL", SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 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},
{"SubgroupAvcSicSetBilinearFilterEnableINTEL", SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL, 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},
{"SubgroupAvcSicSetSkcForwardTransformEnableINTEL", SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcSicSetBlockBasedRawSkipSadINTEL", SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 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},
{"SubgroupAvcSicEvaluateIpeINTEL", SpvOpSubgroupAvcSicEvaluateIpeINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 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},
{"SubgroupAvcSicEvaluateWithSingleReferenceINTEL", SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicEvaluateWithDualReferenceINTEL", SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicEvaluateWithMultiReferenceINTEL", SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL", SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"SubgroupAvcSicConvertToMceResultINTEL", SpvOpSubgroupAvcSicConvertToMceResultINTEL, 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},
{"SubgroupAvcSicGetIpeLumaShapeINTEL", SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL, 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},
{"SubgroupAvcSicGetBestIpeLumaDistortionINTEL", SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL, 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},
{"SubgroupAvcSicGetBestIpeChromaDistortionINTEL", SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL, 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},
{"SubgroupAvcSicGetPackedIpeLumaModesINTEL", SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL, 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},
{"SubgroupAvcSicGetIpeChromaModeINTEL", SpvOpSubgroupAvcSicGetIpeChromaModeINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"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},
{"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},
{"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},
{"RayQueryGetRayTMinKHR", SpvOpRayQueryGetRayTMinKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetRayFlagsKHR", SpvOpRayQueryGetRayFlagsKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionTKHR", SpvOpRayQueryGetIntersectionTKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionInstanceCustomIndexKHR", SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionInstanceIdKHR", SpvOpRayQueryGetIntersectionInstanceIdKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR", SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionGeometryIndexKHR", SpvOpRayQueryGetIntersectionGeometryIndexKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionPrimitiveIndexKHR", SpvOpRayQueryGetIntersectionPrimitiveIndexKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionBarycentricsKHR", SpvOpRayQueryGetIntersectionBarycentricsKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionFrontFaceKHR", SpvOpRayQueryGetIntersectionFrontFaceKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionCandidateAABBOpaqueKHR", SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionObjectRayDirectionKHR", SpvOpRayQueryGetIntersectionObjectRayDirectionKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetIntersectionObjectRayOriginKHR", SpvOpRayQueryGetIntersectionObjectRayOriginKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetWorldRayDirectionKHR", SpvOpRayQueryGetWorldRayDirectionKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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},
{"RayQueryGetWorldRayOriginKHR", SpvOpRayQueryGetWorldRayOriginKHR, 1, pygen_variable_caps_RayQueryProvisionalKHR, 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_RayQueryProvisionalKHR, 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_RayQueryProvisionalKHR, 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}
};

View File

@ -0,0 +1,38 @@
static const spv_ext_inst_desc_t debuginfo_entries[] = {
{"DebugInfoNone", 0, 0, nullptr, {SPV_OPERAND_TYPE_NONE}},
{"DebugCompilationUnit", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeBasic", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, SPV_OPERAND_TYPE_NONE}},
{"DebugTypePointer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeQualifier", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeArray", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeVector", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugTypedef", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeFunction", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeEnum", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeComposite", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeMember", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeInheritance", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}},
{"DebugTypePtrToMember", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeTemplate", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeTemplateParameter", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeTemplateTemplateParameter", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeTemplateParameterPack", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugGlobalVariable", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugFunctionDeclaration", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}},
{"DebugFunction", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugLexicalBlock", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugLexicalBlockDiscriminator", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugScope", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugNoScope", 24, 0, nullptr, {SPV_OPERAND_TYPE_NONE}},
{"DebugInlinedAt", 25, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugLocalVariable", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugInlinedVariable", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugDeclare", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugValue", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugOperation", 30, 0, nullptr, {SPV_OPERAND_TYPE_DEBUG_OPERATION, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
};

View File

@ -0,0 +1,485 @@
const char* ExtensionToString(Extension extension) {
switch (extension) {
case Extension::kSPV_AMD_gcn_shader:
return "SPV_AMD_gcn_shader";
case Extension::kSPV_AMD_gpu_shader_half_float:
return "SPV_AMD_gpu_shader_half_float";
case Extension::kSPV_AMD_gpu_shader_half_float_fetch:
return "SPV_AMD_gpu_shader_half_float_fetch";
case Extension::kSPV_AMD_gpu_shader_int16:
return "SPV_AMD_gpu_shader_int16";
case Extension::kSPV_AMD_shader_ballot:
return "SPV_AMD_shader_ballot";
case Extension::kSPV_AMD_shader_explicit_vertex_parameter:
return "SPV_AMD_shader_explicit_vertex_parameter";
case Extension::kSPV_AMD_shader_fragment_mask:
return "SPV_AMD_shader_fragment_mask";
case Extension::kSPV_AMD_shader_image_load_store_lod:
return "SPV_AMD_shader_image_load_store_lod";
case Extension::kSPV_AMD_shader_trinary_minmax:
return "SPV_AMD_shader_trinary_minmax";
case Extension::kSPV_AMD_texture_gather_bias_lod:
return "SPV_AMD_texture_gather_bias_lod";
case Extension::kSPV_EXT_demote_to_helper_invocation:
return "SPV_EXT_demote_to_helper_invocation";
case Extension::kSPV_EXT_descriptor_indexing:
return "SPV_EXT_descriptor_indexing";
case Extension::kSPV_EXT_fragment_fully_covered:
return "SPV_EXT_fragment_fully_covered";
case Extension::kSPV_EXT_fragment_invocation_density:
return "SPV_EXT_fragment_invocation_density";
case Extension::kSPV_EXT_fragment_shader_interlock:
return "SPV_EXT_fragment_shader_interlock";
case Extension::kSPV_EXT_physical_storage_buffer:
return "SPV_EXT_physical_storage_buffer";
case Extension::kSPV_EXT_shader_atomic_float_add:
return "SPV_EXT_shader_atomic_float_add";
case Extension::kSPV_EXT_shader_image_int64:
return "SPV_EXT_shader_image_int64";
case Extension::kSPV_EXT_shader_stencil_export:
return "SPV_EXT_shader_stencil_export";
case Extension::kSPV_EXT_shader_viewport_index_layer:
return "SPV_EXT_shader_viewport_index_layer";
case Extension::kSPV_GOOGLE_decorate_string:
return "SPV_GOOGLE_decorate_string";
case Extension::kSPV_GOOGLE_hlsl_functionality1:
return "SPV_GOOGLE_hlsl_functionality1";
case Extension::kSPV_GOOGLE_user_type:
return "SPV_GOOGLE_user_type";
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_fpga_loop_controls:
return "SPV_INTEL_fpga_loop_controls";
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_kernel_attributes:
return "SPV_INTEL_kernel_attributes";
case Extension::kSPV_INTEL_media_block_io:
return "SPV_INTEL_media_block_io";
case Extension::kSPV_INTEL_shader_integer_functions2:
return "SPV_INTEL_shader_integer_functions2";
case Extension::kSPV_INTEL_subgroups:
return "SPV_INTEL_subgroups";
case Extension::kSPV_INTEL_unstructured_loop_controls:
return "SPV_INTEL_unstructured_loop_controls";
case Extension::kSPV_KHR_16bit_storage:
return "SPV_KHR_16bit_storage";
case Extension::kSPV_KHR_8bit_storage:
return "SPV_KHR_8bit_storage";
case Extension::kSPV_KHR_device_group:
return "SPV_KHR_device_group";
case Extension::kSPV_KHR_float_controls:
return "SPV_KHR_float_controls";
case Extension::kSPV_KHR_fragment_shading_rate:
return "SPV_KHR_fragment_shading_rate";
case Extension::kSPV_KHR_multiview:
return "SPV_KHR_multiview";
case Extension::kSPV_KHR_no_integer_wrap_decoration:
return "SPV_KHR_no_integer_wrap_decoration";
case Extension::kSPV_KHR_non_semantic_info:
return "SPV_KHR_non_semantic_info";
case Extension::kSPV_KHR_physical_storage_buffer:
return "SPV_KHR_physical_storage_buffer";
case Extension::kSPV_KHR_post_depth_coverage:
return "SPV_KHR_post_depth_coverage";
case Extension::kSPV_KHR_ray_query:
return "SPV_KHR_ray_query";
case Extension::kSPV_KHR_ray_tracing:
return "SPV_KHR_ray_tracing";
case Extension::kSPV_KHR_shader_atomic_counter_ops:
return "SPV_KHR_shader_atomic_counter_ops";
case Extension::kSPV_KHR_shader_ballot:
return "SPV_KHR_shader_ballot";
case Extension::kSPV_KHR_shader_clock:
return "SPV_KHR_shader_clock";
case Extension::kSPV_KHR_shader_draw_parameters:
return "SPV_KHR_shader_draw_parameters";
case Extension::kSPV_KHR_storage_buffer_storage_class:
return "SPV_KHR_storage_buffer_storage_class";
case Extension::kSPV_KHR_subgroup_vote:
return "SPV_KHR_subgroup_vote";
case Extension::kSPV_KHR_terminate_invocation:
return "SPV_KHR_terminate_invocation";
case Extension::kSPV_KHR_variable_pointers:
return "SPV_KHR_variable_pointers";
case Extension::kSPV_KHR_vulkan_memory_model:
return "SPV_KHR_vulkan_memory_model";
case Extension::kSPV_NVX_multiview_per_view_attributes:
return "SPV_NVX_multiview_per_view_attributes";
case Extension::kSPV_NV_compute_shader_derivatives:
return "SPV_NV_compute_shader_derivatives";
case Extension::kSPV_NV_cooperative_matrix:
return "SPV_NV_cooperative_matrix";
case Extension::kSPV_NV_fragment_shader_barycentric:
return "SPV_NV_fragment_shader_barycentric";
case Extension::kSPV_NV_geometry_shader_passthrough:
return "SPV_NV_geometry_shader_passthrough";
case Extension::kSPV_NV_mesh_shader:
return "SPV_NV_mesh_shader";
case Extension::kSPV_NV_ray_tracing:
return "SPV_NV_ray_tracing";
case Extension::kSPV_NV_sample_mask_override_coverage:
return "SPV_NV_sample_mask_override_coverage";
case Extension::kSPV_NV_shader_image_footprint:
return "SPV_NV_shader_image_footprint";
case Extension::kSPV_NV_shader_sm_builtins:
return "SPV_NV_shader_sm_builtins";
case Extension::kSPV_NV_shader_subgroup_partitioned:
return "SPV_NV_shader_subgroup_partitioned";
case Extension::kSPV_NV_shading_rate:
return "SPV_NV_shading_rate";
case Extension::kSPV_NV_stereo_view_rendering:
return "SPV_NV_stereo_view_rendering";
case Extension::kSPV_NV_viewport_array2:
return "SPV_NV_viewport_array2";
case Extension::kSPV_VALIDATOR_ignore_type_decl_unique:
return "SPV_VALIDATOR_ignore_type_decl_unique";
};
return "";
}
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 };
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;
}
const char* CapabilityToString(SpvCapability capability) {
switch (capability) {
case SpvCapabilityMatrix:
return "Matrix";
case SpvCapabilityShader:
return "Shader";
case SpvCapabilityGeometry:
return "Geometry";
case SpvCapabilityTessellation:
return "Tessellation";
case SpvCapabilityAddresses:
return "Addresses";
case SpvCapabilityLinkage:
return "Linkage";
case SpvCapabilityKernel:
return "Kernel";
case SpvCapabilityVector16:
return "Vector16";
case SpvCapabilityFloat16Buffer:
return "Float16Buffer";
case SpvCapabilityFloat16:
return "Float16";
case SpvCapabilityFloat64:
return "Float64";
case SpvCapabilityInt64:
return "Int64";
case SpvCapabilityInt64Atomics:
return "Int64Atomics";
case SpvCapabilityImageBasic:
return "ImageBasic";
case SpvCapabilityImageReadWrite:
return "ImageReadWrite";
case SpvCapabilityImageMipmap:
return "ImageMipmap";
case SpvCapabilityPipes:
return "Pipes";
case SpvCapabilityGroups:
return "Groups";
case SpvCapabilityDeviceEnqueue:
return "DeviceEnqueue";
case SpvCapabilityLiteralSampler:
return "LiteralSampler";
case SpvCapabilityAtomicStorage:
return "AtomicStorage";
case SpvCapabilityInt16:
return "Int16";
case SpvCapabilityTessellationPointSize:
return "TessellationPointSize";
case SpvCapabilityGeometryPointSize:
return "GeometryPointSize";
case SpvCapabilityImageGatherExtended:
return "ImageGatherExtended";
case SpvCapabilityStorageImageMultisample:
return "StorageImageMultisample";
case SpvCapabilityUniformBufferArrayDynamicIndexing:
return "UniformBufferArrayDynamicIndexing";
case SpvCapabilitySampledImageArrayDynamicIndexing:
return "SampledImageArrayDynamicIndexing";
case SpvCapabilityStorageBufferArrayDynamicIndexing:
return "StorageBufferArrayDynamicIndexing";
case SpvCapabilityStorageImageArrayDynamicIndexing:
return "StorageImageArrayDynamicIndexing";
case SpvCapabilityClipDistance:
return "ClipDistance";
case SpvCapabilityCullDistance:
return "CullDistance";
case SpvCapabilityImageCubeArray:
return "ImageCubeArray";
case SpvCapabilitySampleRateShading:
return "SampleRateShading";
case SpvCapabilityImageRect:
return "ImageRect";
case SpvCapabilitySampledRect:
return "SampledRect";
case SpvCapabilityGenericPointer:
return "GenericPointer";
case SpvCapabilityInt8:
return "Int8";
case SpvCapabilityInputAttachment:
return "InputAttachment";
case SpvCapabilitySparseResidency:
return "SparseResidency";
case SpvCapabilityMinLod:
return "MinLod";
case SpvCapabilitySampled1D:
return "Sampled1D";
case SpvCapabilityImage1D:
return "Image1D";
case SpvCapabilitySampledCubeArray:
return "SampledCubeArray";
case SpvCapabilitySampledBuffer:
return "SampledBuffer";
case SpvCapabilityImageBuffer:
return "ImageBuffer";
case SpvCapabilityImageMSArray:
return "ImageMSArray";
case SpvCapabilityStorageImageExtendedFormats:
return "StorageImageExtendedFormats";
case SpvCapabilityImageQuery:
return "ImageQuery";
case SpvCapabilityDerivativeControl:
return "DerivativeControl";
case SpvCapabilityInterpolationFunction:
return "InterpolationFunction";
case SpvCapabilityTransformFeedback:
return "TransformFeedback";
case SpvCapabilityGeometryStreams:
return "GeometryStreams";
case SpvCapabilityStorageImageReadWithoutFormat:
return "StorageImageReadWithoutFormat";
case SpvCapabilityStorageImageWriteWithoutFormat:
return "StorageImageWriteWithoutFormat";
case SpvCapabilityMultiViewport:
return "MultiViewport";
case SpvCapabilitySubgroupDispatch:
return "SubgroupDispatch";
case SpvCapabilityNamedBarrier:
return "NamedBarrier";
case SpvCapabilityPipeStorage:
return "PipeStorage";
case SpvCapabilityGroupNonUniform:
return "GroupNonUniform";
case SpvCapabilityGroupNonUniformVote:
return "GroupNonUniformVote";
case SpvCapabilityGroupNonUniformArithmetic:
return "GroupNonUniformArithmetic";
case SpvCapabilityGroupNonUniformBallot:
return "GroupNonUniformBallot";
case SpvCapabilityGroupNonUniformShuffle:
return "GroupNonUniformShuffle";
case SpvCapabilityGroupNonUniformShuffleRelative:
return "GroupNonUniformShuffleRelative";
case SpvCapabilityGroupNonUniformClustered:
return "GroupNonUniformClustered";
case SpvCapabilityGroupNonUniformQuad:
return "GroupNonUniformQuad";
case SpvCapabilityShaderLayer:
return "ShaderLayer";
case SpvCapabilityShaderViewportIndex:
return "ShaderViewportIndex";
case SpvCapabilityFragmentShadingRateKHR:
return "FragmentShadingRateKHR";
case SpvCapabilitySubgroupBallotKHR:
return "SubgroupBallotKHR";
case SpvCapabilityDrawParameters:
return "DrawParameters";
case SpvCapabilitySubgroupVoteKHR:
return "SubgroupVoteKHR";
case SpvCapabilityStorageBuffer16BitAccess:
return "StorageBuffer16BitAccess";
case SpvCapabilityUniformAndStorageBuffer16BitAccess:
return "UniformAndStorageBuffer16BitAccess";
case SpvCapabilityStoragePushConstant16:
return "StoragePushConstant16";
case SpvCapabilityStorageInputOutput16:
return "StorageInputOutput16";
case SpvCapabilityDeviceGroup:
return "DeviceGroup";
case SpvCapabilityMultiView:
return "MultiView";
case SpvCapabilityVariablePointersStorageBuffer:
return "VariablePointersStorageBuffer";
case SpvCapabilityVariablePointers:
return "VariablePointers";
case SpvCapabilityAtomicStorageOps:
return "AtomicStorageOps";
case SpvCapabilitySampleMaskPostDepthCoverage:
return "SampleMaskPostDepthCoverage";
case SpvCapabilityStorageBuffer8BitAccess:
return "StorageBuffer8BitAccess";
case SpvCapabilityUniformAndStorageBuffer8BitAccess:
return "UniformAndStorageBuffer8BitAccess";
case SpvCapabilityStoragePushConstant8:
return "StoragePushConstant8";
case SpvCapabilityDenormPreserve:
return "DenormPreserve";
case SpvCapabilityDenormFlushToZero:
return "DenormFlushToZero";
case SpvCapabilitySignedZeroInfNanPreserve:
return "SignedZeroInfNanPreserve";
case SpvCapabilityRoundingModeRTE:
return "RoundingModeRTE";
case SpvCapabilityRoundingModeRTZ:
return "RoundingModeRTZ";
case SpvCapabilityRayQueryProvisionalKHR:
return "RayQueryProvisionalKHR";
case SpvCapabilityRayTraversalPrimitiveCullingProvisionalKHR:
return "RayTraversalPrimitiveCullingProvisionalKHR";
case SpvCapabilityFloat16ImageAMD:
return "Float16ImageAMD";
case SpvCapabilityImageGatherBiasLodAMD:
return "ImageGatherBiasLodAMD";
case SpvCapabilityFragmentMaskAMD:
return "FragmentMaskAMD";
case SpvCapabilityStencilExportEXT:
return "StencilExportEXT";
case SpvCapabilityImageReadWriteLodAMD:
return "ImageReadWriteLodAMD";
case SpvCapabilityInt64ImageEXT:
return "Int64ImageEXT";
case SpvCapabilityShaderClockKHR:
return "ShaderClockKHR";
case SpvCapabilitySampleMaskOverrideCoverageNV:
return "SampleMaskOverrideCoverageNV";
case SpvCapabilityGeometryShaderPassthroughNV:
return "GeometryShaderPassthroughNV";
case SpvCapabilityShaderViewportIndexLayerEXT:
return "ShaderViewportIndexLayerEXT";
case SpvCapabilityShaderViewportMaskNV:
return "ShaderViewportMaskNV";
case SpvCapabilityShaderStereoViewNV:
return "ShaderStereoViewNV";
case SpvCapabilityPerViewAttributesNV:
return "PerViewAttributesNV";
case SpvCapabilityFragmentFullyCoveredEXT:
return "FragmentFullyCoveredEXT";
case SpvCapabilityMeshShadingNV:
return "MeshShadingNV";
case SpvCapabilityImageFootprintNV:
return "ImageFootprintNV";
case SpvCapabilityFragmentBarycentricNV:
return "FragmentBarycentricNV";
case SpvCapabilityComputeDerivativeGroupQuadsNV:
return "ComputeDerivativeGroupQuadsNV";
case SpvCapabilityFragmentDensityEXT:
return "FragmentDensityEXT";
case SpvCapabilityGroupNonUniformPartitionedNV:
return "GroupNonUniformPartitionedNV";
case SpvCapabilityShaderNonUniform:
return "ShaderNonUniform";
case SpvCapabilityRuntimeDescriptorArray:
return "RuntimeDescriptorArray";
case SpvCapabilityInputAttachmentArrayDynamicIndexing:
return "InputAttachmentArrayDynamicIndexing";
case SpvCapabilityUniformTexelBufferArrayDynamicIndexing:
return "UniformTexelBufferArrayDynamicIndexing";
case SpvCapabilityStorageTexelBufferArrayDynamicIndexing:
return "StorageTexelBufferArrayDynamicIndexing";
case SpvCapabilityUniformBufferArrayNonUniformIndexing:
return "UniformBufferArrayNonUniformIndexing";
case SpvCapabilitySampledImageArrayNonUniformIndexing:
return "SampledImageArrayNonUniformIndexing";
case SpvCapabilityStorageBufferArrayNonUniformIndexing:
return "StorageBufferArrayNonUniformIndexing";
case SpvCapabilityStorageImageArrayNonUniformIndexing:
return "StorageImageArrayNonUniformIndexing";
case SpvCapabilityInputAttachmentArrayNonUniformIndexing:
return "InputAttachmentArrayNonUniformIndexing";
case SpvCapabilityUniformTexelBufferArrayNonUniformIndexing:
return "UniformTexelBufferArrayNonUniformIndexing";
case SpvCapabilityStorageTexelBufferArrayNonUniformIndexing:
return "StorageTexelBufferArrayNonUniformIndexing";
case SpvCapabilityRayTracingNV:
return "RayTracingNV";
case SpvCapabilityVulkanMemoryModel:
return "VulkanMemoryModel";
case SpvCapabilityVulkanMemoryModelDeviceScope:
return "VulkanMemoryModelDeviceScope";
case SpvCapabilityPhysicalStorageBufferAddresses:
return "PhysicalStorageBufferAddresses";
case SpvCapabilityComputeDerivativeGroupLinearNV:
return "ComputeDerivativeGroupLinearNV";
case SpvCapabilityRayTracingProvisionalKHR:
return "RayTracingProvisionalKHR";
case SpvCapabilityCooperativeMatrixNV:
return "CooperativeMatrixNV";
case SpvCapabilityFragmentShaderSampleInterlockEXT:
return "FragmentShaderSampleInterlockEXT";
case SpvCapabilityFragmentShaderShadingRateInterlockEXT:
return "FragmentShaderShadingRateInterlockEXT";
case SpvCapabilityShaderSMBuiltinsNV:
return "ShaderSMBuiltinsNV";
case SpvCapabilityFragmentShaderPixelInterlockEXT:
return "FragmentShaderPixelInterlockEXT";
case SpvCapabilityDemoteToHelperInvocationEXT:
return "DemoteToHelperInvocationEXT";
case SpvCapabilitySubgroupShuffleINTEL:
return "SubgroupShuffleINTEL";
case SpvCapabilitySubgroupBufferBlockIOINTEL:
return "SubgroupBufferBlockIOINTEL";
case SpvCapabilitySubgroupImageBlockIOINTEL:
return "SubgroupImageBlockIOINTEL";
case SpvCapabilitySubgroupImageMediaBlockIOINTEL:
return "SubgroupImageMediaBlockIOINTEL";
case SpvCapabilityIntegerFunctions2INTEL:
return "IntegerFunctions2INTEL";
case SpvCapabilityFunctionPointersINTEL:
return "FunctionPointersINTEL";
case SpvCapabilityIndirectReferencesINTEL:
return "IndirectReferencesINTEL";
case SpvCapabilitySubgroupAvcMotionEstimationINTEL:
return "SubgroupAvcMotionEstimationINTEL";
case SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL:
return "SubgroupAvcMotionEstimationIntraINTEL";
case SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL:
return "SubgroupAvcMotionEstimationChromaINTEL";
case SpvCapabilityFPGAMemoryAttributesINTEL:
return "FPGAMemoryAttributesINTEL";
case SpvCapabilityUnstructuredLoopControlsINTEL:
return "UnstructuredLoopControlsINTEL";
case SpvCapabilityFPGALoopControlsINTEL:
return "FPGALoopControlsINTEL";
case SpvCapabilityKernelAttributesINTEL:
return "KernelAttributesINTEL";
case SpvCapabilityFPGAKernelAttributesINTEL:
return "FPGAKernelAttributesINTEL";
case SpvCapabilityBlockingPipesINTEL:
return "BlockingPipesINTEL";
case SpvCapabilityFPGARegINTEL:
return "FPGARegINTEL";
case SpvCapabilityAtomicFloat32AddEXT:
return "AtomicFloat32AddEXT";
case SpvCapabilityAtomicFloat64AddEXT:
return "AtomicFloat64AddEXT";
case SpvCapabilityMax:
assert(0 && "Attempting to convert SpvCapabilityMax to string");
return "";
};
return "";
}

View File

@ -0,0 +1,70 @@
kSPV_AMD_gcn_shader,
kSPV_AMD_gpu_shader_half_float,
kSPV_AMD_gpu_shader_half_float_fetch,
kSPV_AMD_gpu_shader_int16,
kSPV_AMD_shader_ballot,
kSPV_AMD_shader_explicit_vertex_parameter,
kSPV_AMD_shader_fragment_mask,
kSPV_AMD_shader_image_load_store_lod,
kSPV_AMD_shader_trinary_minmax,
kSPV_AMD_texture_gather_bias_lod,
kSPV_EXT_demote_to_helper_invocation,
kSPV_EXT_descriptor_indexing,
kSPV_EXT_fragment_fully_covered,
kSPV_EXT_fragment_invocation_density,
kSPV_EXT_fragment_shader_interlock,
kSPV_EXT_physical_storage_buffer,
kSPV_EXT_shader_atomic_float_add,
kSPV_EXT_shader_image_int64,
kSPV_EXT_shader_stencil_export,
kSPV_EXT_shader_viewport_index_layer,
kSPV_GOOGLE_decorate_string,
kSPV_GOOGLE_hlsl_functionality1,
kSPV_GOOGLE_user_type,
kSPV_INTEL_blocking_pipes,
kSPV_INTEL_device_side_avc_motion_estimation,
kSPV_INTEL_fpga_loop_controls,
kSPV_INTEL_fpga_memory_attributes,
kSPV_INTEL_fpga_reg,
kSPV_INTEL_function_pointers,
kSPV_INTEL_kernel_attributes,
kSPV_INTEL_media_block_io,
kSPV_INTEL_shader_integer_functions2,
kSPV_INTEL_subgroups,
kSPV_INTEL_unstructured_loop_controls,
kSPV_KHR_16bit_storage,
kSPV_KHR_8bit_storage,
kSPV_KHR_device_group,
kSPV_KHR_float_controls,
kSPV_KHR_fragment_shading_rate,
kSPV_KHR_multiview,
kSPV_KHR_no_integer_wrap_decoration,
kSPV_KHR_non_semantic_info,
kSPV_KHR_physical_storage_buffer,
kSPV_KHR_post_depth_coverage,
kSPV_KHR_ray_query,
kSPV_KHR_ray_tracing,
kSPV_KHR_shader_atomic_counter_ops,
kSPV_KHR_shader_ballot,
kSPV_KHR_shader_clock,
kSPV_KHR_shader_draw_parameters,
kSPV_KHR_storage_buffer_storage_class,
kSPV_KHR_subgroup_vote,
kSPV_KHR_terminate_invocation,
kSPV_KHR_variable_pointers,
kSPV_KHR_vulkan_memory_model,
kSPV_NVX_multiview_per_view_attributes,
kSPV_NV_compute_shader_derivatives,
kSPV_NV_cooperative_matrix,
kSPV_NV_fragment_shader_barycentric,
kSPV_NV_geometry_shader_passthrough,
kSPV_NV_mesh_shader,
kSPV_NV_ray_tracing,
kSPV_NV_sample_mask_override_coverage,
kSPV_NV_shader_image_footprint,
kSPV_NV_shader_sm_builtins,
kSPV_NV_shader_subgroup_partitioned,
kSPV_NV_shading_rate,
kSPV_NV_stereo_view_rendering,
kSPV_NV_viewport_array2,
kSPV_VALIDATOR_ignore_type_decl_unique

View File

@ -0,0 +1,27 @@
{0, "Khronos", "", "Khronos"},
{1, "LunarG", "", "LunarG"},
{2, "Valve", "", "Valve"},
{3, "Codeplay", "", "Codeplay"},
{4, "NVIDIA", "", "NVIDIA"},
{5, "ARM", "", "ARM"},
{6, "Khronos", "LLVM/SPIR-V Translator", "Khronos LLVM/SPIR-V Translator"},
{7, "Khronos", "SPIR-V Tools Assembler", "Khronos SPIR-V Tools Assembler"},
{8, "Khronos", "Glslang Reference Front End", "Khronos Glslang Reference Front End"},
{9, "Qualcomm", "", "Qualcomm"},
{10, "AMD", "", "AMD"},
{11, "Intel", "", "Intel"},
{12, "Imagination", "", "Imagination"},
{13, "Google", "Shaderc over Glslang", "Google Shaderc over Glslang"},
{14, "Google", "spiregg", "Google spiregg"},
{15, "Google", "rspirv", "Google rspirv"},
{16, "X-LEGEND", "Mesa-IR/SPIR-V Translator", "X-LEGEND Mesa-IR/SPIR-V Translator"},
{17, "Khronos", "SPIR-V Tools Linker", "Khronos SPIR-V Tools Linker"},
{18, "Wine", "VKD3D Shader Compiler", "Wine VKD3D Shader Compiler"},
{19, "Clay", "Clay Shader Compiler", "Clay Clay Shader Compiler"},
{20, "W3C WebGPU Group", "WHLSL Shader Translator", "W3C WebGPU Group WHLSL Shader Translator"},
{21, "Google", "Clspv", "Google Clspv"},
{22, "Google", "MLIR SPIR-V Serializer", "Google MLIR SPIR-V Serializer"},
{23, "Google", "Tint Compiler", "Google Tint Compiler"},
{24, "Google", "ANGLE Shader Compiler", "Google ANGLE Shader Compiler"},
{25, "Netease Games", "Messiah Shader Compiler", "Netease Games Messiah Shader Compiler"},
{26, "Xenia", "Xenia Emulator Microcode Translator", "Xenia Xenia Emulator Microcode Translator"},

View File

@ -0,0 +1,86 @@
static const SpvCapability pygen_variable_caps_Float64[] = {SpvCapabilityFloat64};
static const SpvCapability pygen_variable_caps_InterpolationFunction[] = {SpvCapabilityInterpolationFunction};
static const spv_ext_inst_desc_t glsl_entries[] = {
{"Round", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"RoundEven", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Trunc", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FAbs", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SAbs", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FSign", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SSign", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Floor", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Ceil", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Fract", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Radians", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Degrees", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Sin", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Cos", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Tan", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Asin", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Acos", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Atan", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Sinh", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Cosh", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Tanh", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Asinh", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Acosh", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Atanh", 24, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Atan2", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Pow", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Exp", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Log", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Exp2", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Log2", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Sqrt", 31, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"InverseSqrt", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Determinant", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"MatrixInverse", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Modf", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"ModfStruct", 36, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FMin", 37, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UMin", 38, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SMin", 39, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FMax", 40, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UMax", 41, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SMax", 42, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FClamp", 43, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UClamp", 44, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SClamp", 45, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FMix", 46, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"IMix", 47, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Step", 48, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SmoothStep", 49, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Fma", 50, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Frexp", 51, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FrexpStruct", 52, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Ldexp", 53, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PackSnorm4x8", 54, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PackUnorm4x8", 55, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PackSnorm2x16", 56, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PackUnorm2x16", 57, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PackHalf2x16", 58, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PackDouble2x32", 59, 1, pygen_variable_caps_Float64, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UnpackSnorm2x16", 60, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UnpackUnorm2x16", 61, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UnpackHalf2x16", 62, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UnpackSnorm4x8", 63, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UnpackUnorm4x8", 64, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UnpackDouble2x32", 65, 1, pygen_variable_caps_Float64, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Length", 66, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Distance", 67, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Cross", 68, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Normalize", 69, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FaceForward", 70, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Reflect", 71, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"Refract", 72, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FindILsb", 73, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FindSMsb", 74, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FindUMsb", 75, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"InterpolateAtCentroid", 76, 1, pygen_variable_caps_InterpolationFunction, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"InterpolateAtSample", 77, 1, pygen_variable_caps_InterpolationFunction, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"InterpolateAtOffset", 78, 1, pygen_variable_caps_InterpolationFunction, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"NMin", 79, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"NMax", 80, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"NClamp", 81, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
};

View File

@ -0,0 +1,28 @@
static const spv_ext_inst_desc_t nonsemantic_clspvreflection_entries[] = {
{"Kernel", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentInfo", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentStorageBuffer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentUniform", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentPodStorageBuffer", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentPodUniform", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentPodPushConstant", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentSampledImage", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentStorageImage", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentSampler", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"ArgumentWorkgroup", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"SpecConstantWorkgroupSize", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SpecConstantGlobalOffset", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SpecConstantWorkDim", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PushConstantGlobalOffset", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PushConstantEnqueuedLocalSize", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PushConstantGlobalSize", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PushConstantRegionOffset", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PushConstantNumWorkgroups", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PushConstantRegionGroupOffset", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"ConstantDataStorageBuffer", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"ConstantDataUniform", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"LiteralSampler", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"PropertyRequiredWorkgroupSize", 24, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
};

View File

@ -0,0 +1,40 @@
static const spv_ext_inst_desc_t opencl_debuginfo_100_entries[] = {
{"DebugInfoNone", 0, 0, nullptr, {SPV_OPERAND_TYPE_NONE}},
{"DebugCompilationUnit", 1, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SOURCE_LANGUAGE, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeBasic", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, SPV_OPERAND_TYPE_NONE}},
{"DebugTypePointer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeQualifier", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeArray", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeVector", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugTypedef", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeFunction", 8, 0, nullptr, {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeEnum", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeComposite", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeMember", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeInheritance", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}},
{"DebugTypePtrToMember", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeTemplate", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeTemplateParameter", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeTemplateTemplateParameter", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeTemplateParameterPack", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugGlobalVariable", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugFunctionDeclaration", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}},
{"DebugFunction", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugLexicalBlock", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugLexicalBlockDiscriminator", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugScope", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugNoScope", 24, 0, nullptr, {SPV_OPERAND_TYPE_NONE}},
{"DebugInlinedAt", 25, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugLocalVariable", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugInlinedVariable", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugDeclare", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugValue", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugOperation", 30, 0, nullptr, {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugImportedEntity", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugSource", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}
};

View File

@ -0,0 +1,166 @@
static const spv_ext_inst_desc_t opencl_entries[] = {
{"acos", 0, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"acosh", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"acospi", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"asin", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"asinh", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"asinpi", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"atan", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"atan2", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"atanh", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"atanpi", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"atan2pi", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"cbrt", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"ceil", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"copysign", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"cos", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"cosh", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"cospi", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"erfc", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"erf", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"exp", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"exp2", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"exp10", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"expm1", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fabs", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fdim", 24, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"floor", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fma", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fmax", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fmin", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fmod", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fract", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"frexp", 31, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"hypot", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"ilogb", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"ldexp", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"lgamma", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"lgamma_r", 36, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"log", 37, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"log2", 38, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"log10", 39, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"log1p", 40, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"logb", 41, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"mad", 42, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"maxmag", 43, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"minmag", 44, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"modf", 45, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"nan", 46, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"nextafter", 47, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"pow", 48, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"pown", 49, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"powr", 50, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"remainder", 51, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"remquo", 52, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"rint", 53, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"rootn", 54, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"round", 55, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"rsqrt", 56, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"sin", 57, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"sincos", 58, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"sinh", 59, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"sinpi", 60, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"sqrt", 61, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"tan", 62, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"tanh", 63, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"tanpi", 64, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"tgamma", 65, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"trunc", 66, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_cos", 67, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_divide", 68, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_exp", 69, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_exp2", 70, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_exp10", 71, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_log", 72, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_log2", 73, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_log10", 74, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_powr", 75, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_recip", 76, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_rsqrt", 77, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_sin", 78, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_sqrt", 79, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"half_tan", 80, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_cos", 81, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_divide", 82, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_exp", 83, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_exp2", 84, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_exp10", 85, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_log", 86, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_log2", 87, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_log10", 88, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_powr", 89, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_recip", 90, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_rsqrt", 91, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_sin", 92, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_sqrt", 93, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"native_tan", 94, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fclamp", 95, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"degrees", 96, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fmax_common", 97, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fmin_common", 98, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"mix", 99, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"radians", 100, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"step", 101, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"smoothstep", 102, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"sign", 103, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"cross", 104, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"distance", 105, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"length", 106, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"normalize", 107, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fast_distance", 108, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fast_length", 109, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"fast_normalize", 110, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_abs", 141, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_abs_diff", 142, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_add_sat", 143, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_add_sat", 144, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_hadd", 145, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_hadd", 146, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_rhadd", 147, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_rhadd", 148, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_clamp", 149, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_clamp", 150, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"clz", 151, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"ctz", 152, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_mad_hi", 153, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_mad_sat", 154, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_mad_sat", 155, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_max", 156, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_max", 157, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_min", 158, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_min", 159, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_mul_hi", 160, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"rotate", 161, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_sub_sat", 162, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_sub_sat", 163, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_upsample", 164, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_upsample", 165, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"popcount", 166, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_mad24", 167, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_mad24", 168, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"s_mul24", 169, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_mul24", 170, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"vloadn", 171, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"vstoren", 172, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"vload_half", 173, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"vload_halfn", 174, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"vstore_half", 175, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"vstore_half_r", 176, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_NONE}},
{"vstore_halfn", 177, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"vstore_halfn_r", 178, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_NONE}},
{"vloada_halfn", 179, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}},
{"vstorea_halfn", 180, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"vstorea_halfn_r", 181, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_NONE}},
{"shuffle", 182, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"shuffle2", 183, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"printf", 184, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
{"prefetch", 185, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"bitselect", 186, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"select", 187, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_abs", 201, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_abs_diff", 202, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_mul_hi", 203, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"u_mad_hi", 204, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
static const spv_ext_inst_desc_t spv_amd_gcn_shader_entries[] = {
{"CubeFaceIndexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"CubeFaceCoordAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"TimeAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}
};

View File

@ -0,0 +1,8 @@
static const spv_ext_inst_desc_t spv_amd_shader_ballot_entries[] = {
{"SwizzleInvocationsAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SwizzleInvocationsMaskedAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"WriteInvocationAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"MbcntAMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
};

View File

@ -0,0 +1,5 @@
static const spv_ext_inst_desc_t spv_amd_shader_explicit_vertex_parameter_entries[] = {
{"InterpolateAtVertexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
};

View File

@ -0,0 +1,13 @@
static const spv_ext_inst_desc_t spv_amd_shader_trinary_minmax_entries[] = {
{"FMin3AMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UMin3AMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SMin3AMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FMax3AMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UMax3AMD", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SMax3AMD", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"FMid3AMD", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"UMid3AMD", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"SMid3AMD", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
};

@ -0,0 +1 @@
Subproject commit 7845730cab6ebbdeb621e7349b7dc1a59c3377be

@ -0,0 +1 @@
Subproject commit 36494dd966ecaa4a399f3f7755bbdcf561229503

View File

@ -0,0 +1,29 @@
use crate::shared;
#[repr(u32)] // SPV_FORCE_32_BIT_ENUM
pub enum BinaryOptions {
None = 0x1,
PreserveNumberIds = 1 << 1,
}
extern "C" {
/// Encodes the given SPIR-V assembly text to its binary representation. The
/// length parameter specifies the number of bytes for text. Encoded binary will
/// be stored into *binary. Any error will be written into *diagnostic if
/// diagnostic is non-null, otherwise the context's message consumer will be
/// used. The generated binary is independent of the context and may outlive it.
/// The SPIR-V binary version is set to the highest version of SPIR-V supported
/// by the context's target environment.
///
/// The options parameter is a bit field of
/// spv_text_to_binary_options_t.
#[link_name = "spvTextToBinaryWithOptions"]
pub fn assemble(
tool: *const shared::ToolContext,
text: *const std::os::raw::c_char,
size: usize,
options: u32,
binary: *mut *mut shared::Binary,
diagnostic: *mut *mut crate::diagnostics::Diagnostic,
) -> shared::SpirvResult;
}

View File

@ -0,0 +1,248 @@
#include "spirv-tools/optimizer.hpp"
#include <cstring>
struct Optimus;
enum Passes {
Null,
StripAtomicCounterMemory,
StripDebugInfo,
StripReflectInfo,
EliminateDeadFunctions,
EliminateDeadMembers,
FlattenDecoration,
FreezeSpecConstantValue,
FoldSpecConstantOpAndComposite,
UnifyConstant,
EliminateDeadConstant,
StrengthReduction,
BlockMerge,
InlineExhaustive,
InlineOpaque,
LocalSingleBlockLoadStoreElim,
DeadBranchElim,
LocalMultiStoreElim,
LocalAccessChainConvert,
LocalSingleStoreElim,
InsertExtractElim,
DeadInsertElim,
AggressiveDCE,
PropagateLineInfo,
RedundantLineInfoElim,
CompactIds,
RemoveDuplicates,
CFGCleanup,
DeadVariableElimination,
MergeReturn,
LocalRedundancyElimination,
LoopInvariantCodeMotion,
LoopPeeling,
LoopUnswitch,
RedundancyElimination,
PrivateToLocal,
CCP,
Workaround1209,
IfConversion,
ReplaceInvalidOpcode,
Simplification,
SSARewrite,
ConvertRelaxedToHalf,
RelaxFloatOps,
CopyPropagateArrays,
VectorDCE,
ReduceLoadSize,
CombineAccessChains,
UpgradeMemoryModel,
CodeSinking,
GenerateWebGPUInitializers,
FixStorageClass,
LegalizeVectorShuffle,
DecomposeInitializedVariables,
SplitInvalidUnreachable,
GraphicsRobustAccess,
DescriptorScalarReplacement,
WrapOpKill,
AmdExtToKhr,
};
typedef void (*message_callback)(
spv_message_level_t level,
const char* source,
const spv_position_t* position,
const char* message,
void* ctx
);
extern "C" {
SPIRV_TOOLS_EXPORT Optimus* optimizer_create(spv_target_env target_env) {
auto* optimizer = new spvtools::Optimizer(target_env);
return (Optimus*)optimizer;
}
SPIRV_TOOLS_EXPORT void optimizer_destroy(Optimus* optimizer) {
delete (spvtools::Optimizer*)optimizer;
}
SPIRV_TOOLS_EXPORT spv_result_t optimizer_run(
const Optimus* optimizer,
const uint32_t* input_ptr,
size_t input_size,
spv_binary* out_binary,
message_callback msg_callback,
void* ctx,
const spv_optimizer_options options
) {
if (input_ptr == nullptr) {
return SPV_ERROR_INVALID_POINTER;
}
if (out_binary == nullptr) {
return SPV_ERROR_INVALID_POINTER;
}
auto op = (spvtools::Optimizer*)optimizer;
if (msg_callback) {
op->SetMessageConsumer([msg_callback, ctx](
spv_message_level_t level,
const char* source,
const spv_position_t& position,
const char* message) {
msg_callback(level, source, &position, message, ctx);
});
} else {
// The optimizer keeps the message consumer as state, so if no
// callback is passed to us, we insert a noop callback to ensure
// we don't use the state from a previous optimizer run
op->SetMessageConsumer([](
spv_message_level_t,
const char*,
const spv_position_t&,
const char*)
{}
);
}
auto output_buff = std::vector<uint32_t>();
bool success = false;
if (options == nullptr) {
success = op->Run(input_ptr, input_size, &output_buff);
} else {
success = op->Run(input_ptr, input_size, &output_buff, options);
}
if (!success) {
return SPV_ERROR_INTERNAL;
}
uint32_t* data = new uint32_t[output_buff.size()];
if (data == nullptr) {
return SPV_ERROR_OUT_OF_MEMORY;
}
spv_binary binary = new spv_binary_t();
if (binary == nullptr) {
delete[] data;
return SPV_ERROR_OUT_OF_MEMORY;
}
memcpy(data, output_buff.data(), output_buff.size());
*out_binary = binary;
return SPV_SUCCESS;
}
SPIRV_TOOLS_EXPORT void optimizer_register_pass(Optimus* optimizer, Passes pass) {
#define PASTEB(a, b) a ## b
#define PASTEA(a, b) PASTEB(a, b)
#define PASS(name) \
case name: \
op->RegisterPass(spvtools::PASTEA(PASTEA(Create, name), Pass)()); \
break;
spvtools::Optimizer* op = (spvtools::Optimizer*)optimizer;
switch (pass) {
PASS(Null)
PASS(StripAtomicCounterMemory)
PASS(StripDebugInfo)
PASS(StripReflectInfo)
PASS(EliminateDeadFunctions)
PASS(EliminateDeadMembers)
PASS(FlattenDecoration)
PASS(FreezeSpecConstantValue)
PASS(FoldSpecConstantOpAndComposite)
PASS(UnifyConstant)
PASS(EliminateDeadConstant)
PASS(StrengthReduction)
PASS(BlockMerge)
PASS(InlineExhaustive)
PASS(InlineOpaque)
PASS(LocalSingleBlockLoadStoreElim)
PASS(DeadBranchElim)
PASS(LocalMultiStoreElim)
PASS(LocalAccessChainConvert)
PASS(LocalSingleStoreElim)
PASS(InsertExtractElim)
PASS(DeadInsertElim)
PASS(AggressiveDCE)
PASS(PropagateLineInfo)
PASS(RedundantLineInfoElim)
PASS(CompactIds)
PASS(RemoveDuplicates)
PASS(CFGCleanup)
PASS(DeadVariableElimination)
PASS(MergeReturn)
PASS(LocalRedundancyElimination)
PASS(LoopInvariantCodeMotion)
PASS(LoopPeeling)
PASS(LoopUnswitch)
PASS(RedundancyElimination)
PASS(PrivateToLocal)
PASS(CCP)
PASS(Workaround1209)
PASS(IfConversion)
PASS(ReplaceInvalidOpcode)
PASS(Simplification)
PASS(SSARewrite)
PASS(ConvertRelaxedToHalf)
PASS(RelaxFloatOps)
PASS(CopyPropagateArrays)
PASS(VectorDCE)
PASS(ReduceLoadSize)
PASS(CombineAccessChains)
PASS(UpgradeMemoryModel)
PASS(CodeSinking)
PASS(GenerateWebGPUInitializers)
PASS(FixStorageClass)
PASS(LegalizeVectorShuffle)
PASS(DecomposeInitializedVariables)
PASS(SplitInvalidUnreachable)
PASS(GraphicsRobustAccess)
PASS(DescriptorScalarReplacement)
PASS(WrapOpKill)
PASS(AmdExtToKhr)
}
}
SPIRV_TOOLS_EXPORT void optimizer_register_performance_passes(Optimus* optimizer) {
((spvtools::Optimizer*)optimizer)->RegisterPerformancePasses();
}
SPIRV_TOOLS_EXPORT void optimizer_register_size_passes(Optimus* optimizer) {
((spvtools::Optimizer*)optimizer)->RegisterSizePasses();
}
SPIRV_TOOLS_EXPORT void optimizer_register_vulkan_to_webgpu_passes(Optimus* optimizer) {
((spvtools::Optimizer*)optimizer)->RegisterVulkanToWebGPUPasses();
}
SPIRV_TOOLS_EXPORT void optimizer_register_webgpu_to_vulkan_passes(Optimus* optimizer) {
((spvtools::Optimizer*)optimizer)->RegisterWebGPUToVulkanPasses();
}
SPIRV_TOOLS_EXPORT void optimizer_register_hlsl_legalization_passes(Optimus* optimizer) {
((spvtools::Optimizer*)optimizer)->RegisterLegalizationPasses();
}
}

View File

@ -0,0 +1,50 @@
#[repr(C)]
pub struct Position {
pub line: usize,
pub column: usize,
pub index: usize,
}
#[repr(C)]
pub struct Diagnostic {
pub position: Position,
pub error: *const std::os::raw::c_char,
pub is_text_source: bool,
}
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)]
pub enum MessageLevel {
/// Unrecoverable error due to environment.
/// Will exit the program immediately. E.g.,
/// out of memory.
Fatal,
/// Unrecoverable error due to SPIRV-Tools
/// internals.
/// Will exit the program immediately. E.g.,
/// unimplemented feature.
InternalError,
/// Normal error due to user input.
Error,
/// Warning information.
Warning,
/// General information.
Info,
/// Debug information.
Debug,
}
pub type MessageCallback = extern "C" fn(
MessageLevel, // level
*const std::os::raw::c_char, // source
*const Position, // source position
*const std::os::raw::c_char, // the actual message
*mut std::ffi::c_void, // context we use for mapping
);
extern "C" {
/// Destroys a diagnostic object. This is a no-op if diagnostic is a null
/// pointer.
#[link_name = "spvDiagnosticDestroy"]
pub fn diagnostic_destroy(diag: *mut Diagnostic);
}

View File

@ -0,0 +1,5 @@
pub mod assembler;
pub mod diagnostics;
pub mod opt;
pub mod shared;
pub mod val;

696
spirv-tools-sys/src/opt.rs Normal file
View File

@ -0,0 +1,696 @@
#[repr(C)]
pub struct Optimizer {
_unused: [u8; 0],
}
#[repr(C)]
pub struct OptimizerOptions {
_unused: [u8; 0],
}
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum Passes {
// Creates a null pass.
// A null pass does nothing to the SPIR-V module to be optimized.
Null,
// Creates a strip-atomic-counter-memory pass.
// A strip-atomic-counter-memory pass removes all usages of the
// AtomicCounterMemory bit in Memory Semantics bitmasks. This bit is a no-op in
// Vulkan, so isn't needed in that env. And the related capability is not
// allowed in WebGPU, so it is not allowed in that env.
StripAtomicCounterMemory,
// Creates a strip-debug-info pass.
// A strip-debug-info pass removes all debug instructions (as documented in
// Section 3.32.2 of the SPIR-V spec) of the SPIR-V module to be optimized.
StripDebugInfo,
// Creates a strip-reflect-info pass.
// A strip-reflect-info pass removes all reflections instructions.
// For now, this is limited to removing decorations defined in
// SPV_GOOGLE_hlsl_functionality1. The coverage may expand in
// the future.
StripReflectInfo,
// Creates an eliminate-dead-functions pass.
// An eliminate-dead-functions pass will remove all functions that are not in
// the call trees rooted at entry points and exported functions. These
// functions are not needed because they will never be called.
EliminateDeadFunctions,
// Creates an eliminate-dead-members pass.
// An eliminate-dead-members pass will remove all unused members of structures.
// This will not affect the data layout of the remaining members.
EliminateDeadMembers,
// Creates a flatten-decoration pass.
// A flatten-decoration pass replaces grouped decorations with equivalent
// ungrouped decorations. That is, it replaces each OpDecorationGroup
// instruction and associated OpGroupDecorate and OpGroupMemberDecorate
// instructions with equivalent OpDecorate and OpMemberDecorate instructions.
// The pass does not attempt to preserve debug information for instructions
// it removes.
FlattenDecoration,
// Creates a freeze-spec-constant-value pass.
// A freeze-spec-constant pass specializes the value of spec constants to
// their default values. This pass only processes the spec constants that have
// SpecId decorations (defined by OpSpecConstant, OpSpecConstantTrue, or
// OpSpecConstantFalse instructions) and replaces them with their normal
// counterparts (OpConstant, OpConstantTrue, or OpConstantFalse). The
// corresponding SpecId annotation instructions will also be removed. This
// pass does not fold the newly added normal constants and does not process
// other spec constants defined by OpSpecConstantComposite or
// OpSpecConstantOp.
FreezeSpecConstantValue,
// Creates a fold-spec-constant-op-and-composite pass.
// A fold-spec-constant-op-and-composite pass folds spec constants defined by
// OpSpecConstantOp or OpSpecConstantComposite instruction, to normal Constants
// defined by OpConstantTrue, OpConstantFalse, OpConstant, OpConstantNull, or
// OpConstantComposite instructions. Note that spec constants defined with
// OpSpecConstant, OpSpecConstantTrue, or OpSpecConstantFalse instructions are
// not handled, as these instructions indicate their value are not determined
// and can be changed in future. A spec constant is foldable if all of its
// value(s) can be determined from the module. E.g., an integer spec constant
// defined with OpSpecConstantOp instruction can be folded if its value won't
// change later. This pass will replace the original OpSpecContantOp instruction
// with an OpConstant instruction. When folding composite spec constants,
// new instructions may be inserted to define the components of the composite
// constant first, then the original spec constants will be replaced by
// OpConstantComposite instructions.
//
// There are some operations not supported yet:
// OpSConvert, OpFConvert, OpQuantizeToF16 and
// all the operations under Kernel capability.
// TODO(qining): Add support for the operations listed above.
FoldSpecConstantOpAndComposite,
// Creates a unify-constant pass.
// A unify-constant pass de-duplicates the constants. Constants with the exact
// same value and identical form will be unified and only one constant will
// be kept for each unique pair of type and value.
// There are several cases not handled by this pass:
// 1) Constants defined by OpConstantNull instructions (null constants) and
// constants defined by OpConstantFalse, OpConstant or OpConstantComposite
// with value 0 (zero-valued normal constants) are not considered equivalent.
// So null constants won't be used to replace zero-valued normal constants,
// vice versa.
// 2) Whenever there are decorations to the constant's result id id, the
// constant won't be handled, which means, it won't be used to replace any
// other constants, neither can other constants replace it.
// 3) NaN in float point format with different bit patterns are not unified.
UnifyConstant,
// Creates a eliminate-dead-constant pass.
// A eliminate-dead-constant pass removes dead constants, including normal
// contants defined by OpConstant, OpConstantComposite, OpConstantTrue, or
// OpConstantFalse and spec constants defined by OpSpecConstant,
// OpSpecConstantComposite, OpSpecConstantTrue, OpSpecConstantFalse or
// OpSpecConstantOp.
EliminateDeadConstant,
// Creates a strength-reduction pass.
// A strength-reduction pass will look for opportunities to replace an
// instruction with an equivalent and less expensive one. For example,
// multiplying by a power of 2 can be replaced by a bit shift.
StrengthReduction,
// Creates a block merge pass.
// This pass searches for blocks with a single Branch to a block with no
// other predecessors and merges the blocks into a single block. Continue
// blocks and Merge blocks are not candidates for the second block.
//
// The pass is most useful after Dead Branch Elimination, which can leave
// such sequences of blocks. Merging them makes subsequent passes more
// effective, such as single block local store-load elimination.
//
// While this pass reduces the number of occurrences of this sequence, at
// this time it does not guarantee all such sequences are eliminated.
//
// Presence of phi instructions can inhibit this optimization. Handling
// these is left for future improvements.
BlockMerge,
// Creates an exhaustive inline pass.
// An exhaustive inline pass attempts to exhaustively inline all function
// calls in all functions in an entry point call tree. The intent is to enable,
// albeit through brute force, analysis and optimization across function
// calls by subsequent optimization passes. As the inlining is exhaustive,
// there is no attempt to optimize for size or runtime performance. Functions
// that are not in the call tree of an entry point are not changed.
InlineExhaustive,
// Creates an opaque inline pass.
// An opaque inline pass inlines all function calls in all functions in all
// entry point call trees where the called function contains an opaque type
// in either its parameter types or return type. An opaque type is currently
// defined as Image, Sampler or SampledImage. The intent is to enable, albeit
// through brute force, analysis and optimization across these function calls
// by subsequent passes in order to remove the storing of opaque types which is
// not legal in Vulkan. Functions that are not in the call tree of an entry
// point are not changed.
InlineOpaque,
// Creates a single-block local variable load/store elimination pass.
// For every entry point function, do single block memory optimization of
// function variables referenced only with non-access-chain loads and stores.
// For each targeted variable load, if previous store to that variable in the
// block, replace the load's result id with the value id of the store.
// If previous load within the block, replace the current load's result id
// with the previous load's result id. In either case, delete the current
// load. Finally, check if any remaining stores are useless, and delete store
// and variable if possible.
//
// The presence of access chain references and function calls can inhibit
// the above optimization.
//
// Only modules with relaxed logical addressing (see opt/instruction.h) are
// currently processed.
//
// This pass is most effective if preceeded by Inlining and
// LocalAccessChainConvert. This pass will reduce the work needed to be done
// by LocalSingleStoreElim and LocalMultiStoreElim.
//
// Only functions in the call tree of an entry point are processed.
LocalSingleBlockLoadStoreElim,
// Create dead branch elimination pass.
// For each entry point function, this pass will look for SelectionMerge
// BranchConditionals with constant condition and convert to a Branch to
// the indicated label. It will delete resulting dead blocks.
//
// For all phi functions in merge block, replace all uses with the id
// corresponding to the living predecessor.
//
// Note that some branches and blocks may be left to avoid creating invalid
// control flow. Improving this is left to future work.
//
// This pass is most effective when preceeded by passes which eliminate
// local loads and stores, effectively propagating constant values where
// possible.
DeadBranchElim,
// Creates an SSA local variable load/store elimination pass.
// For every entry point function, eliminate all loads and stores of function
// scope variables only referenced with non-access-chain loads and stores.
// Eliminate the variables as well.
//
// The presence of access chain references and function calls can inhibit
// the above optimization.
//
// Only shader modules with relaxed logical addressing (see opt/instruction.h)
// are currently processed. Currently modules with any extensions enabled are
// not processed. This is left for future work.
//
// This pass is most effective if preceeded by Inlining and
// LocalAccessChainConvert. LocalSingleStoreElim and LocalSingleBlockElim
// will reduce the work that this pass has to do.
LocalMultiStoreElim,
// Creates a local access chain conversion pass.
// A local access chain conversion pass identifies all function scope
// variables which are accessed only with loads, stores and access chains
// with constant indices. It then converts all loads and stores of such
// variables into equivalent sequences of loads, stores, extracts and inserts.
//
// This pass only processes entry point functions. It currently only converts
// non-nested, non-ptr access chains. It does not process modules with
// non-32-bit integer types present. Optional memory access options on loads
// and stores are ignored as we are only processing function scope variables.
//
// This pass unifies access to these variables to a single mode and simplifies
// subsequent analysis and elimination of these variables along with their
// loads and stores allowing values to propagate to their points of use where
// possible.
LocalAccessChainConvert,
// Creates a local single store elimination pass.
// For each entry point function, this pass eliminates loads and stores for
// function scope variable that are stored to only once, where possible. Only
// whole variable loads and stores are eliminated; access-chain references are
// not optimized. Replace all loads of such variables with the value that is
// stored and eliminate any resulting dead code.
//
// Currently, the presence of access chains and function calls can inhibit this
// pass, however the Inlining and LocalAccessChainConvert passes can make it
// more effective. In additional, many non-load/store memory operations are
// not supported and will prohibit optimization of a function. Support of
// these operations are future work.
//
// Only shader modules with relaxed logical addressing (see opt/instruction.h)
// are currently processed.
//
// This pass will reduce the work needed to be done by LocalSingleBlockElim
// and LocalMultiStoreElim and can improve the effectiveness of other passes
// such as DeadBranchElimination which depend on values for their analysis.
LocalSingleStoreElim,
// Creates an insert/extract elimination pass.
// This pass processes each entry point function in the module, searching for
// extracts on a sequence of inserts. It further searches the sequence for an
// insert with indices identical to the extract. If such an insert can be
// found before hitting a conflicting insert, the extract's result id is
// replaced with the id of the values from the insert.
//
// Besides removing extracts this pass enables subsequent dead code elimination
// passes to delete the inserts. This pass performs best after access chains are
// converted to inserts and extracts and local loads and stores are eliminated.
InsertExtractElim,
// Creates a dead insert elimination pass.
// This pass processes each entry point function in the module, searching for
// unreferenced inserts into composite types. These are most often unused
// stores to vector components. They are unused because they are never
// referenced, or because there is another insert to the same component between
// the insert and the reference. After removing the inserts, dead code
// elimination is attempted on the inserted values.
//
// This pass performs best after access chains are converted to inserts and
// extracts and local loads and stores are eliminated. While executing this
// pass can be advantageous on its own, it is also advantageous to execute
// this pass after CreateInsertExtractPass() as it will remove any unused
// inserts created by that pass.
DeadInsertElim,
// Create aggressive dead code elimination pass
// This pass eliminates unused code from the module. In addition,
// it detects and eliminates code which may have spurious uses but which do
// not contribute to the output of the function. The most common cause of
// such code sequences is summations in loops whose result is no longer used
// due to dead code elimination. This optimization has additional compile
// time cost over standard dead code elimination.
//
// This pass only processes entry point functions. It also only processes
// shaders with relaxed logical addressing (see opt/instruction.h). It
// currently will not process functions with function calls. Unreachable
// functions are deleted.
//
// This pass will be made more effective by first running passes that remove
// dead control flow and inlines function calls.
//
// This pass can be especially useful after running Local Access Chain
// Conversion, which tends to cause cycles of dead code to be left after
// Store/Load elimination passes are completed. These cycles cannot be
// eliminated with standard dead code elimination.
AggressiveDCE,
// Create line propagation pass
// This pass propagates line information based on the rules for OpLine and
// OpNoline and clones an appropriate line instruction into every instruction
// which does not already have debug line instructions.
//
// This pass is intended to maximize preservation of source line information
// through passes which delete, move and clone instructions. Ideally it should
// be run before any such pass. It is a bookend pass with EliminateDeadLines
// which can be used to remove redundant line instructions at the end of a
// run of such passes and reduce final output file size.
PropagateLineInfo,
// Create dead line elimination pass
// This pass eliminates redundant line instructions based on the rules for
// OpLine and OpNoline. Its main purpose is to reduce the size of the file
// need to store the SPIR-V without losing line information.
//
// This is a bookend pass with PropagateLines which attaches line instructions
// to every instruction to preserve line information during passes which
// delete, move and clone instructions. DeadLineElim should be run after
// PropagateLines and all such subsequent passes. Normally it would be one
// of the last passes to be run.
RedundantLineInfoElim,
// Creates a compact ids pass.
// The pass remaps result ids to a compact and gapless range starting from %1.
CompactIds,
// Creates a remove duplicate pass.
// This pass removes various duplicates:
// * duplicate capabilities;
// * duplicate extended instruction imports;
// * duplicate types;
// * duplicate decorations.
RemoveDuplicates,
// Creates a CFG cleanup pass.
// This pass removes cruft from the control flow graph of functions that are
// reachable from entry points and exported functions. It currently includes the
// following functionality:
//
// - Removal of unreachable basic blocks.
CFGCleanup,
// Create dead variable elimination pass.
// This pass will delete module scope variables, along with their decorations,
// that are not referenced.
DeadVariableElimination,
// create merge return pass.
// changes functions that have multiple return statements so they have a single
// return statement.
//
// for structured control flow it is assumed that the only unreachable blocks in
// the function are trivial merge and continue blocks.
//
// a trivial merge block contains the label and an opunreachable instructions,
// nothing else. a trivial continue block contain a label and an opbranch to
// the header, nothing else.
//
// these conditions are guaranteed to be met after running dead-branch
// elimination.
MergeReturn,
// Create value numbering pass.
// This pass will look for instructions in the same basic block that compute the
// same value, and remove the redundant ones.
LocalRedundancyElimination,
// Create LICM pass.
// This pass will look for invariant instructions inside loops and hoist them to
// the loops preheader.
LoopInvariantCodeMotion,
// Creates a loop peeling pass.
// This pass will look for conditions inside a loop that are true or false only
// for the N first or last iteration. For loop with such condition, those N
// iterations of the loop will be executed outside of the main loop.
// To limit code size explosion, the loop peeling can only happen if the code
// size growth for each loop is under |code_growth_threshold|.
LoopPeeling,
// Creates a loop unswitch pass.
// This pass will look for loop independent branch conditions and move the
// condition out of the loop and version the loop based on the taken branch.
// Works best after LICM and local multi store elimination pass.
LoopUnswitch,
// Create global value numbering pass.
// This pass will look for instructions where the same value is computed on all
// paths leading to the instruction. Those instructions are deleted.
RedundancyElimination,
// Create a private to local pass.
// This pass looks for variables delcared in the private storage class that are
// used in only one function. Those variables are moved to the function storage
// class in the function that they are used.
PrivateToLocal,
// Creates a conditional constant propagation (CCP) pass.
// This pass implements the SSA-CCP algorithm in
//
// Constant propagation with conditional branches,
// Wegman and Zadeck, ACM TOPLAS 13(2):181-210.
//
// Constant values in expressions and conditional jumps are folded and
// simplified. This may reduce code size by removing never executed jump targets
// and computations with constant operands.
ConditionalConstantPropagation,
// Creates a workaround driver bugs pass. This pass attempts to work around
// a known driver bug (issue #1209) by identifying the bad code sequences and
// rewriting them.
//
// Current workaround: Avoid OpUnreachable instructions in loops.
Workaround1209,
// Creates a pass that converts if-then-else like assignments into OpSelect.
IfConversion,
// Creates a pass that will replace instructions that are not valid for the
// current shader stage by constants. Has no effect on non-shader modules.
ReplaceInvalidOpcode,
// Creates a pass that simplifies instructions using the instruction folder.
Simplification,
// Create the SSA rewrite pass.
// This pass converts load/store operations on function local variables into
// operations on SSA IDs. This allows SSA optimizers to act on these variables.
// Only variables that are local to the function and of supported types are
// processed (see IsSSATargetVar for details).
SSARewrite,
// Create pass to convert relaxed precision instructions to half precision.
// This pass converts as many relaxed float32 arithmetic operations to half as
// possible. It converts any float32 operands to half if needed. It converts
// any resulting half precision values back to float32 as needed. No variables
// are changed. No image operations are changed.
//
// Best if run after function scope store/load and composite operation
// eliminations are run. Also best if followed by instruction simplification,
// redundancy elimination and DCE.
ConvertRelaxedToHalf,
// Create relax float ops pass.
// This pass decorates all float32 result instructions with RelaxedPrecision
// if not already so decorated.
RelaxFloatOps,
// Create copy propagate arrays pass.
// This pass looks to copy propagate memory references for arrays. It looks
// for specific code patterns to recognize array copies.
CopyPropagateArrays,
// Create a vector dce pass.
// This pass looks for components of vectors that are unused, and removes them
// from the vector. Note this would still leave around lots of dead code that
// a pass of ADCE will be able to remove.
VectorDCE,
// Create a pass to reduce the size of loads.
// This pass looks for loads of structures where only a few of its members are
// used. It replaces the loads feeding an OpExtract with an OpAccessChain and
// a load of the specific elements.
ReduceLoadSize,
// Create a pass to combine chained access chains.
// This pass looks for access chains fed by other access chains and combines
// them into a single instruction where possible.
CombineAccessChains,
// Create a pass to upgrade to the VulkanKHR memory model.
// This pass upgrades the Logical GLSL450 memory model to Logical VulkanKHR.
// Additionally, it modifies memory, image, atomic and barrier operations to
// conform to that model's requirements.
UpgradeMemoryModel,
// Create a pass to do code sinking. Code sinking is a transformation
// where an instruction is moved into a more deeply nested construct.
CodeSinking,
// Create a pass to adds initializers for OpVariable calls that require them
// in WebGPU. Currently this pass naively initializes variables that are
// missing an initializer with a null value. In the future it may initialize
// variables to the first value stored in them, if that is a constant.
GenerateWebGPUInitializers,
// Create a pass to fix incorrect storage classes. In order to make code
// generation simpler, DXC may generate code where the storage classes do not
// match up correctly. This pass will fix the errors that it can.
FixStorageClass,
// Create a pass to legalize OpVectorShuffle operands going into WebGPU. WebGPU
// forbids using 0xFFFFFFFF, which indicates an undefined result, so this pass
// converts those literals to 0.
LegalizeVectorShuffle,
// Create a pass to decompose initialized variables into a seperate variable
// declaration and an initial store.
DecomposeInitializedVariables,
// Create a pass to attempt to split up invalid unreachable merge-blocks and
// continue-targets to legalize for WebGPU.
SplitInvalidUnreachable,
// Creates a graphics robust access pass.
//
// This pass injects code to clamp indexed accesses to buffers and internal
// arrays, providing guarantees satisfying Vulkan's robustBufferAccess rules.
//
// TODO(dneto): Clamps coordinates and sample index for pointer calculations
// into storage images (OpImageTexelPointer). For an cube array image, it
// assumes the maximum layer count times 6 is at most 0xffffffff.
//
// NOTE: This pass will fail with a message if:
// - The module is not a Shader module.
// - The module declares VariablePointers, VariablePointersStorageBuffer, or
// RuntimeDescriptorArrayEXT capabilities.
// - The module uses an addressing model other than Logical
// - Access chain indices are wider than 64 bits.
// - Access chain index for a struct is not an OpConstant integer or is out
// of range. (The module is already invalid if that is the case.)
// - TODO(dneto): The OpImageTexelPointer coordinate component is not 32-bits
// wide.
//
// NOTE: Access chain indices are always treated as signed integers. So
// if an array has a fixed size of more than 2^31 elements, then elements
// from 2^31 and above are never accessible with a 32-bit index,
// signed or unsigned. For this case, this pass will clamp the index
// between 0 and at 2^31-1, inclusive.
// Similarly, if an array has more then 2^15 element and is accessed with
// a 16-bit index, then elements from 2^15 and above are not accessible.
// In this case, the pass will clamp the index between 0 and 2^15-1
// inclusive.
GraphicsRobustAccess,
// Create descriptor scalar replacement pass.
// This pass replaces every array variable |desc| that has a DescriptorSet and
// Binding decorations with a new variable for each element of the array.
// Suppose |desc| was bound at binding |b|. Then the variable corresponding to
// |desc[i]| will have binding |b+i|. The descriptor set will be the same. It
// is assumed that no other variable already has a binding that will used by one
// of the new variables. If not, the pass will generate invalid Spir-V. All
// accesses to |desc| must be OpAccessChain instructions with a literal index
// for the first index.
DescriptorScalarReplacement,
// Create a pass to replace each OpKill instruction with a function call to a
// function that has a single OpKill. Also replace each OpTerminateInvocation
// instruction with a function call to a function that has a single
// OpTerminateInvocation. This allows more code to be inlined.
WrapOpKill,
// Replaces the extensions VK_AMD_shader_ballot,VK_AMD_gcn_shader, and
// VK_AMD_shader_trinary_minmax with equivalent code using core instructions and
// capabilities.
AmdExtToKhr,
}
extern "C" {
pub fn optimizer_create(env: crate::shared::TargetEnv) -> *mut Optimizer;
pub fn optimizer_destroy(opt: *mut Optimizer);
pub fn optimizer_run(
opt: *const Optimizer,
input_ptr: *const u32,
input_size: usize,
binary: *mut *mut crate::shared::Binary,
message_callback: crate::diagnostics::MessageCallback,
message_ctx: *mut std::ffi::c_void,
options: *const OptimizerOptions,
) -> crate::shared::SpirvResult;
/// Creates an optimizer options object with default options. Returns a valid
/// options object. The object remains valid until it is passed into
/// |spvOptimizerOptionsDestroy|.
#[link_name = "spvOptimizerOptionsCreate"]
pub fn optimizer_options_create() -> *mut OptimizerOptions;
/// Destroys the given optimizer options object.
#[link_name = "spvOptimizerOptionsDestroy"]
pub fn optimizer_options_destroy(options: *mut OptimizerOptions);
/// Records whether or not the optimizer should run the validator before
/// optimizing. If |val| is true, the validator will be run.
#[link_name = "spvOptimizerOptionsSetRunValidator"]
pub fn optimizer_options_run_validator(options: *mut OptimizerOptions, run: bool);
/// Records the validator options that should be passed to the validator if it is
/// run.
#[link_name = "spvOptimizerOptionsSetValidatorOptions"]
pub fn optimizer_options_set_validator_options(
options: *mut OptimizerOptions,
validator_opts: *mut crate::val::ValidatorOptions,
);
/// Records the maximum possible value for the id bound.
#[link_name = "spvOptimizerOptionsSetMaxIdBound"]
pub fn optimizer_options_set_max_id_bound(options: *mut OptimizerOptions, max: u32);
/// Records whether all bindings within the module should be preserved.
#[link_name = "spvOptimizerOptionsSetPreserveBindings"]
pub fn optimizer_options_preserve_bindings(options: *mut OptimizerOptions, preserve: bool);
/// Records whether all specialization constants within the module
/// should be preserved.
#[link_name = "spvOptimizerOptionsSetPreserveSpecConstants"]
pub fn optimizer_options_preserve_spec_constants(
options: *mut OptimizerOptions,
preserve: bool,
);
pub fn optimizer_register_pass(opt: *mut Optimizer, which: Passes);
/// Registers passes that attempt to improve performance of generated code.
/// This sequence of passes is subject to constant review and will change
/// from time to time.
pub fn optimizer_register_performance_passes(opt: *mut Optimizer);
/// Registers passes that attempt to improve the size of generated code.
/// This sequence of passes is subject to constant review and will change
/// from time to time.
pub fn optimizer_register_size_passes(opt: *mut Optimizer);
/// Registers passes that have been prescribed for converting from Vulkan to
/// WebGPU. This sequence of passes is subject to constant review and will
/// change from time to time.
pub fn optimizer_register_vulkan_to_webgpu_passes(opt: *mut Optimizer);
/// Registers passes that have been prescribed for converting from WebGPU to
/// Vulkan. This sequence of passes is subject to constant review and will
/// change from time to time.
pub fn optimizer_register_webgpu_to_vulkan_passes(opt: *mut Optimizer);
/// Registers passes that attempt to legalize the generated code.
///
/// Note: this recipe is specially designed for legalizing SPIR-V. It should be
/// used by compilers after translating HLSL source code literally. It should
/// *not* be used by general workloads for performance or size improvement.
///
/// This sequence of passes is subject to constant review and will change
/// from time to time.
pub fn optimizer_register_hlsl_legalization_passes(opt: *mut Optimizer);
// Some passes take arguments, so we create those separately on a
// case-by-case basis
// #[repr(C)]
// pub struct SpecConstantDefault {
// pub id: u32,
// pub value_ptr: *const c_char,
// pub value_len: usize,
// }
// Creates a set-spec-constant-default-value pass from a mapping from spec-ids
// to the default values in the form of string.
// A set-spec-constant-default-value pass sets the default values for the
// spec constants that have SpecId decorations (i.e., those defined by
// OpSpecConstant{|True|False} instructions).
// SetSpecConstantDefaultValuePass(
// const std::unordered_map<uint32_t, std::string>& id_value_map);
// Create a pass to instrument OpDebugPrintf instructions.
// This pass replaces all OpDebugPrintf instructions with instructions to write
// a record containing the string id and the all specified values into a special
// printf output buffer (if space allows). This pass is designed to support
// the printf validation in the Vulkan validation layers.
//
// The instrumentation will write buffers in debug descriptor set |desc_set|.
// It will write |shader_id| in each output record to identify the shader
// module which generated the record.
// InstDebugPrintfPass(uint32_t desc_set,
// uint32_t shader_id);
// Create a pass to instrument bindless descriptor checking
// This pass instruments all bindless references to check that descriptor
// array indices are inbounds, and if the descriptor indexing extension is
// enabled, that the descriptor has been initialized. If the reference is
// invalid, a record is written to the debug output buffer (if space allows)
// and a null value is returned. This pass is designed to support bindless
// validation in the Vulkan validation layers.
//
// TODO(greg-lunarg): Add support for buffer references. Currently only does
// checking for image references.
//
// Dead code elimination should be run after this pass as the original,
// potentially invalid code is not removed and could cause undefined behavior,
// including crashes. It may also be beneficial to run Simplification
// (ie Constant Propagation), DeadBranchElim and BlockMerge after this pass to
// optimize instrument code involving the testing of compile-time constants.
// It is also generally recommended that this pass (and all
// instrumentation passes) be run after any legalization and optimization
// passes. This will give better analysis for the instrumentation and avoid
// potentially de-optimizing the instrument code, for example, inlining
// the debug record output function throughout the module.
//
// The instrumentation will read and write buffers in debug
// descriptor set |desc_set|. It will write |shader_id| in each output record
// to identify the shader module which generated the record.
// |input_length_enable| controls instrumentation of runtime descriptor array
// references, and |input_init_enable| controls instrumentation of descriptor
// initialization checking, both of which require input buffer support.
// InstBindlessCheckPass(
// uint32_t desc_set, uint32_t shader_id, bool input_length_enable = false,
// bool input_init_enable = false, bool input_buff_oob_enable = false);
// // Create a pass to instrument physical buffer address checking
// // This pass instruments all physical buffer address references to check that
// // all referenced bytes fall in a valid buffer. If the reference is
// // invalid, a record is written to the debug output buffer (if space allows)
// // and a null value is returned. This pass is designed to support buffer
// // address validation in the Vulkan validation layers.
// //
// // Dead code elimination should be run after this pass as the original,
// // potentially invalid code is not removed and could cause undefined behavior,
// // including crashes. Instruction simplification would likely also be
// // beneficial. It is also generally recommended that this pass (and all
// // instrumentation passes) be run after any legalization and optimization
// // passes. This will give better analysis for the instrumentation and avoid
// // potentially de-optimizing the instrument code, for example, inlining
// // the debug record output function throughout the module.
// //
// // The instrumentation will read and write buffers in debug
// // descriptor set |desc_set|. It will write |shader_id| in each output record
// // to identify the shader module which generated the record.
// InstBuffAddrCheckPass(uint32_t desc_set,
// uint32_t shader_id);
// Create loop unroller pass.
// Creates a pass to unroll loops which have the "Unroll" loop control
// mask set. The loops must meet a specific criteria in order to be unrolled
// safely this criteria is checked before doing the unroll by the
// LoopUtils::CanPerformUnroll method. Any loop that does not meet the criteria
// won't be unrolled. See CanPerformUnroll LoopUtils.h for more information.
//LoopUnrollPass(bool fully_unroll, int factor = 0);
// Create scalar replacement pass.
// This pass replaces composite function scope variables with variables for each
// element if those elements are accessed individually. The parameter is a
// limit on the number of members in the composite variable that the pass will
// consider replacing.
//ScalarReplacementPass(uint32_t size_limit = 100);
// Creates a loop fission pass.
// This pass will split all top level loops whose register pressure exceedes the
// given |threshold|.
//LoopFissionPass(size_t threshold);
// Creates a loop fusion pass.
// This pass will look for adjacent loops that are compatible and legal to be
// fused. The fuse all such loops as long as the register usage for the fused
// loop stays under the threshold defined by |max_registers_per_loop|.
//LoopFusionPass(size_t max_registers_per_loop);
}

View File

@ -0,0 +1,232 @@
use std::fmt;
/// Certain target environments impose additional restrictions on SPIR-V, so it's
/// often necessary to specify which one applies. `Universal_*` implies an
/// environment-agnostic SPIR-V.
///
/// When an API method needs to derive a SPIR-V version from a target environment
/// the method will choose the highest version of SPIR-V supported by the target
/// environment. Examples:
/// SPV_ENV_VULKAN_1_0 -> SPIR-V 1.0
/// SPV_ENV_VULKAN_1_1 -> SPIR-V 1.3
/// SPV_ENV_VULKAN_1_1_SPIRV_1_4 -> SPIR-V 1.4
/// SPV_ENV_VULKAN_1_2 -> SPIR-V 1.5
///
/// Consult the description of API entry points for specific rules.
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(C)]
#[allow(non_camel_case_types)]
pub enum TargetEnv {
/// SPIR-V 1.0 latest revision, no other restrictions.
Universal_1_0,
/// Vulkan 1.0 latest revision.
Vulkan_1_0,
/// SPIR-V 1.1 latest revision, no other restrictions.
Universal_1_1,
/// OpenCL Full Profile 2.1 latest revision.
OpenCL_2_1,
/// OpenCL Full Profile 2.2 latest revision.
OpenCL_2_2,
/// OpenGL 4.0 plus GL_ARB_gl_spirv, latest revisions.
OpenGL_4_0,
/// OpenGL 4.1 plus GL_ARB_gl_spirv, latest revisions.
OpenGL_4_1,
/// OpenGL 4.2 plus GL_ARB_gl_spirv, latest revisions.
OpenGL_4_2,
/// OpenGL 4.3 plus GL_ARB_gl_spirv, latest revisions.
OpenGL_4_3,
/// OpenGL 4.5 plus GL_ARB_gl_spirv, latest revisions.
OpenGL_4_5,
/// SPIR-V 1.2, latest revision, no other restrictions.
Universal_1_2,
/// OpenCL Full Profile 1.2 plus cl_khr_il_program, latest revision.
OpenCL_1_2,
/// OpenCL Embedded Profile 1.2 plus cl_khr_il_program, latest revision.
OpenCLEmbedded_1_2,
/// OpenCL Full Profile 2.0 plus cl_khr_il_program, latest revision.
OpenCL_2_0,
/// OpenCL Embedded Profile 2.0 plus cl_khr_il_program, latest revision.
OpenCLEmbedded_2_0,
/// OpenCL Embedded Profile 2.1 latest revision.
OpenCLEmbedded_2_1,
/// OpenCL Embedded Profile 2.2 latest revision.
OpenCLEmbedded_2_2,
/// SPIR-V 1.3 latest revision, no other restrictions.
Universal_1_3,
/// Vulkan 1.1 latest revision.
Vulkan_1_1,
/// Work in progress WebGPU 1.0.
WebGPU_0,
/// SPIR-V 1.4 latest revision, no other restrictions.
Universal_1_4,
/// Vulkan 1.1 with VK_KHR_spirv_1_4, i.e. SPIR-V 1.4 binary.
Vulkan_1_1_Spirv_1_4,
/// SPIR-V 1.5 latest revision, no other restrictions.
Universal_1_5,
/// Vulkan 1.2 latest revision.
Vulkan_1_2,
}
impl Default for TargetEnv {
fn default() -> Self {
// This is the default target environment for (AFAICT) all spirv-tools
Self::Universal_1_5
}
}
impl std::str::FromStr for TargetEnv {
type Err = SpirvResult;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"vulkan1.1spv1.4" => Self::Vulkan_1_1_Spirv_1_4,
"vulkan1.0" => Self::Vulkan_1_0,
"vulkan1.1" => Self::Vulkan_1_1,
"vulkan1.2" => Self::Vulkan_1_2,
"spv1.0" => Self::Universal_1_0,
"spv1.1" => Self::Universal_1_1,
"spv1.2" => Self::Universal_1_2,
"spv1.3" => Self::Universal_1_3,
"spv1.4" => Self::Universal_1_4,
"spv1.5" => Self::Universal_1_5,
"opencl1.2embedded" => Self::OpenCLEmbedded_1_2,
"opencl1.2" => Self::OpenCL_1_2,
"opencl2.0embedded" => Self::OpenCLEmbedded_2_0,
"opencl2.0" => Self::OpenCL_2_0,
"opencl2.1embedded" => Self::OpenCLEmbedded_2_1,
"opencl2.1" => Self::OpenCL_2_1,
"opencl2.2embedded" => Self::OpenCLEmbedded_2_2,
"opencl2.2" => Self::OpenCL_2_2,
"opengl4.0" => Self::OpenGL_4_0,
"opengl4.1" => Self::OpenGL_4_1,
"opengl4.2" => Self::OpenGL_4_2,
"opengl4.3" => Self::OpenGL_4_3,
"opengl4.5" => Self::OpenGL_4_5,
"webgpu0" => Self::WebGPU_0,
_ => return Err(SpirvResult::InvalidValue),
})
}
}
impl fmt::Display for TargetEnv {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Vulkan_1_1_Spirv_1_4 => "vulkan1.1spv1.4",
Self::Vulkan_1_0 => "vulkan1.0",
Self::Vulkan_1_1 => "vulkan1.1",
Self::Vulkan_1_2 => "vulkan1.2",
Self::Universal_1_0 => "spv1.0",
Self::Universal_1_1 => "spv1.1",
Self::Universal_1_2 => "spv1.2",
Self::Universal_1_3 => "spv1.3",
Self::Universal_1_4 => "spv1.4",
Self::Universal_1_5 => "spv1.5",
Self::OpenCLEmbedded_1_2 => "opencl1.2embedded",
Self::OpenCL_1_2 => "opencl1.2",
Self::OpenCLEmbedded_2_0 => "opencl2.0embedded",
Self::OpenCL_2_0 => "opencl2.0",
Self::OpenCLEmbedded_2_1 => "opencl2.1embedded",
Self::OpenCL_2_1 => "opencl2.1",
Self::OpenCLEmbedded_2_2 => "opencl2.2embedded",
Self::OpenCL_2_2 => "opencl2.2",
Self::OpenGL_4_0 => "opengl4.0",
Self::OpenGL_4_1 => "opengl4.1",
Self::OpenGL_4_2 => "opengl4.2",
Self::OpenGL_4_3 => "opengl4.3",
Self::OpenGL_4_5 => "opengl4.5",
Self::WebGPU_0 => "webgpu0",
})
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(i32)] // SPV_FORCE_32_BIT_ENUM
pub enum SpirvResult {
Success = 0,
Unsupported = 1,
EndOfStream = 2,
Warning = 3,
FailedMatch = 4,
/// Success, but signals early termination.
RequestedTermination = 5,
InternalError = -1,
OutOfMemory = -2,
InvalidPointer = -3,
InvalidBinary = -4,
InvalidText = -5,
InvalidTable = -6,
InvalidValue = -7,
InvalidDiagnostic = -8,
InvalidLookup = -9,
InvalidId = -10,
InvalidCfg = -11,
InvalidLayout = -12,
InvalidCapability = -13,
/// Indicates data rules validation failure.
InvalidData = -14,
MissingExtension = -15,
/// Indicates wrong SPIR-V version
WrongVersion = -16,
}
impl fmt::Display for SpirvResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use SpirvResult::*;
match self {
Success => f.write_str("success"),
Unsupported => f.write_str("unsupported"),
EndOfStream => f.write_str("end of stream"),
Warning => f.write_str("warning"),
FailedMatch => f.write_str("failed match"),
RequestedTermination => f.write_str("requested termination"),
InternalError => f.write_str("internal error"),
OutOfMemory => f.write_str("out of memory"),
InvalidPointer => f.write_str("invalid pointer"),
InvalidBinary => f.write_str("invalid binary"),
InvalidText => f.write_str("invalid text"),
InvalidTable => f.write_str("invalid table"),
InvalidValue => f.write_str("invalid value"),
InvalidDiagnostic => f.write_str("invalid diagnostic"),
InvalidLookup => f.write_str("invalid lookup"),
InvalidId => f.write_str("invalid id"),
InvalidCfg => f.write_str("invalid cfg"),
InvalidLayout => f.write_str("invalid layout"),
InvalidCapability => f.write_str("invalid capability"),
InvalidData => f.write_str("invalid data"),
MissingExtension => f.write_str("missing extension"),
WrongVersion => f.write_str("wrong SPIR-V version"),
}
}
}
impl std::error::Error for SpirvResult {}
#[repr(C)]
pub struct Binary {
pub code: *const u32,
pub size: usize,
}
#[repr(C)]
pub struct ToolContext {
_unused: [u8; 0],
}
extern "C" {
/// Creates a context object for most of the SPIRV-Tools API.
/// Returns null if env is invalid.
///
/// See specific API calls for how the target environment is interpeted
/// (particularly assembly and validation).
#[link_name = "spvContextCreate"]
pub fn context_create(env: TargetEnv) -> *mut ToolContext;
/// Destroys the given context object.
#[link_name = "spvContextDestroy"]
pub fn context_destroy(opt: *mut ToolContext);
/// Frees a binary stream from memory. This is a no-op if binary is a null
/// pointer.
#[link_name = "spvBinaryDestroy"]
pub fn binary_destroy(binary: *mut Binary);
}

131
spirv-tools-sys/src/val.rs Normal file
View File

@ -0,0 +1,131 @@
use crate::shared;
#[repr(C)]
pub struct ValidatorOptions {
_unused: [u8; 0],
}
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum ValidatorLimits {
StructMembers,
StructDepth,
LocalVariables,
GlobalVariables,
SwitchBranches,
FunctionArgs,
ControlFlowNestingDepth,
AccessChainIndexes,
IdBound,
}
extern "C" {
/// Validates a raw SPIR-V binary for correctness. Any errors will be written
/// into *diagnostic if diagnostic is non-null, otherwise the context's message
/// consumer will be used.
#[link_name = "spvValidateBinary"]
pub fn validate(
tool: *const shared::ToolContext,
binary: *const u32,
size: usize,
options: *const ValidatorOptions,
diagnostic: *mut *mut crate::diagnostics::Diagnostic,
) -> crate::shared::SpirvResult;
/// Creates a Validator options object with default options. Returns a valid
/// options object. The object remains valid until it is passed into
/// spvValidatorOptionsDestroy.
#[link_name = "spvValidatorOptionsCreate"]
pub fn validator_options_create() -> *mut ValidatorOptions;
/// Destroys the given Validator options object.
#[link_name = "spvValidatorOptionsDestroy"]
pub fn validator_options_destroy(opts: *mut ValidatorOptions);
/// Records the maximum Universal Limit that is considered valid in the given
/// Validator options object. <options> argument must be a valid options object.
#[link_name = "spvValidatorOptionsSetUniversalLimit"]
pub fn validator_options_set_limit(
opts: *mut ValidatorOptions,
limit_type: ValidatorLimits,
limit: u32,
);
/// Record whether or not the validator should relax the rules on types for
/// stores to structs. When relaxed, it will allow a type mismatch as long as
/// the types are structs with the same layout. Two structs have the same layout
/// if
///
/// 1) the members of the structs are either the same type or are structs with
/// same layout, and
///
/// 2) the decorations that affect the memory layout are identical for both
/// types. Other decorations are not relevant.
#[link_name = "spvValidatorOptionsSetRelaxStoreStruct"]
pub fn validator_options_set_relax_store_struct(opts: *mut ValidatorOptions, toggle: bool);
/// Records whether or not the validator should relax the rules on pointer usage
/// in logical addressing mode.
///
/// When relaxed, it will allow the following usage cases of pointers:
/// 1) OpVariable allocating an object whose type is a pointer type
/// 2) OpReturnValue returning a pointer value
#[link_name = "spvValidatorOptionsSetRelaxLogicalPointer"]
pub fn validator_options_set_relax_logical_pointer(opts: *mut ValidatorOptions, toggle: bool);
/// Records whether or not the validator should relax the rules because it is
/// expected that the optimizations will make the code legal.
///
/// When relaxed, it will allow the following:
/// 1) It will allow relaxed logical pointers. Setting this option will also
/// set that option.
/// 2) Pointers that are pass as parameters to function calls do not have to
/// match the storage class of the formal parameter.
/// 3) Pointers that are actaul parameters on function calls do not have to point
/// to the same type pointed as the formal parameter. The types just need to
/// logically match.
#[link_name = "spvValidatorOptionsSetBeforeHlslLegalization"]
pub fn validator_options_set_before_legalization(opts: *mut ValidatorOptions, toggle: bool);
/// Records whether the validator should use "relaxed" block layout rules.
/// Relaxed layout rules are described by Vulkan extension
/// VK_KHR_relaxed_block_layout, and they affect uniform blocks, storage blocks,
/// and push constants.
///
/// This is enabled by default when targeting Vulkan 1.1 or later.
/// Relaxed layout is more permissive than the default rules in Vulkan 1.0.
#[link_name = "spvValidatorOptionsSetRelaxBlockLayout"]
pub fn validator_options_set_relax_block_layout(opts: *mut ValidatorOptions, toggle: bool);
/// Records whether the validator should use standard block layout rules for
/// uniform blocks.
#[link_name = "spvValidatorOptionsSetUniformBufferStandardLayout"]
pub fn validator_options_set_uniform_buffer_standard_layout(
opts: *mut ValidatorOptions,
toggle: bool,
);
/// Records whether the validator should use "scalar" block layout rules.
/// Scalar layout rules are more permissive than relaxed block layout.
///
/// See Vulkan extnesion VK_EXT_scalar_block_layout. The scalar alignment is
/// defined as follows:
/// - scalar alignment of a scalar is the scalar size
/// - scalar alignment of a vector is the scalar alignment of its component
/// - scalar alignment of a matrix is the scalar alignment of its component
/// - scalar alignment of an array is the scalar alignment of its element
/// - scalar alignment of a struct is the max scalar alignment among its
/// members
///
/// For a struct in Uniform, StorageClass, or PushConstant:
/// - a member Offset must be a multiple of the member's scalar alignment
/// - ArrayStride or MatrixStride must be a multiple of the array or matrix
/// scalar alignment
#[link_name = "spvValidatorOptionsSetScalarBlockLayout"]
pub fn validator_options_set_scalar_block_layout(opts: *mut ValidatorOptions, toggle: bool);
/// Records whether or not the validator should skip validating standard
/// uniform/storage block layout.
#[link_name = "spvValidatorOptionsSetSkipBlockLayout"]
pub fn validator_options_set_skip_block_layout(opts: *mut ValidatorOptions, toggle: bool);
}

23
spirv-tools/Cargo.toml Normal file
View File

@ -0,0 +1,23 @@
[package]
name = "spirv-tools"
version = "0.1.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
[features]
use-installed-tools = ["spirv-tools-sys/use-installed-tools", "memchr", "tempfile"]
use-compiled-tools = ["spirv-tools-sys/use-compiled-tools"]
[dependencies]
spirv-tools-sys = { path = "../spirv-tools-sys", default-features = false }
# Used for parsing output when running binaries
memchr = { version = "2.3", optional = true }
tempfile = { version = "3.1", optional = true }
[dev-dependencies]
structopt = "0.3"
[[example]]
name = "as"
required-features = ["use-compiled-tools"]

View File

@ -0,0 +1,62 @@
use structopt::StructOpt;
/// Create a SPIR-V binary module from SPIR-V assembly text
#[derive(StructOpt)]
struct Args {
/// Set the output filename. Use '-' for stdout.
#[structopt(short, default_value = "out.spv")]
output: String,
/// Numeric IDs in the binary will have the same values as in the
/// source. Non-numeric IDs are allocated by filling in the gaps,
/// starting with 1 and going up.
#[structopt(long = "preserve-numeric-ids")]
preserve_ids: bool,
/// Use specified environment.
#[structopt(long = "target-env", parse(try_from_str))]
target_env: Option<spirv_tools::TargetEnv>,
/// The input file. Use '-' for stdin.
#[structopt(name = "FILE")]
input: String,
}
fn main() {
use spirv_tools::assembler::{self, Assembler};
let args = Args::from_args();
let contents = if args.input == "-" {
use std::io::Read;
let mut v = Vec::with_capacity(1024);
std::io::stdin()
.read_to_end(&mut v)
.expect("failed to read stdin");
String::from_utf8(v).expect("stdin had invalid utf-8")
} else {
std::fs::read_to_string(&args.input).expect("failed to read input file")
};
let assembler_opts = assembler::AssemblerOptions {
preserve_numeric_ids: args.preserve_ids,
};
let assembler =
assembler::compiled::CompiledAssembler::with_env(args.target_env.unwrap_or_default());
match assembler.assemble(&contents, assembler_opts) {
Ok(binary) => {
if args.output == "-" {
use std::io::Write;
std::io::stdout()
.lock()
.write_all(binary.as_ref())
.expect("failed to write binary to stdout");
} else {
std::fs::write(args.output, &binary).expect("failed to write binary");
}
}
Err(e) => {
eprintln!("{}", e);
std::process::exit(1);
}
}
}

View File

@ -0,0 +1,50 @@
#[cfg(feature = "use-compiled-tools")]
pub mod compiled;
#[cfg(feature = "use-installed-tools")]
pub mod tool;
#[derive(Copy, Clone, Default)]
pub struct AssemblerOptions {
/// Numeric IDs in the binary will have the same values as in the source.
/// Non-numeric IDs are allocated by filling in the gaps, starting with 1
/// and going up.
pub preserve_numeric_ids: bool,
}
impl Into<u32> for AssemblerOptions {
fn into(self) -> u32 {
// This is weird, the "none" is 1, so I'm not sure if that means having
// it disables all other options or...?
let mut res = 0; //assembler::BinaryOptions::None as u32;
if self.preserve_numeric_ids {
res |= spirv_tools_sys::assembler::BinaryOptions::PreserveNumberIds as u32;
}
res
}
}
pub trait Assembler: Default {
fn with_env(target_env: crate::TargetEnv) -> Self;
fn assemble(
&self,
text: &str,
options: AssemblerOptions,
) -> Result<crate::binary::Binary, crate::error::Error>;
}
pub fn create(te: Option<crate::TargetEnv>) -> impl Assembler {
let target_env = te.unwrap_or_default();
#[cfg(feature = "use-compiled-tools")]
{
compiled::CompiledAssembler::with_env(target_env)
}
#[cfg(all(feature = "use-installed-tools", not(feature = "use-compiled-tools")))]
{
tool::ToolAssembler::with_env(target_env)
}
}

View File

@ -0,0 +1,71 @@
use spirv_tools_sys::{assembler, shared};
pub struct CompiledAssembler {
inner: *mut shared::ToolContext,
}
use super::Assembler;
impl Assembler for CompiledAssembler {
fn with_env(target_env: crate::TargetEnv) -> Self {
Self {
inner: unsafe { shared::context_create(target_env) },
}
}
fn assemble(
&self,
text: &str,
options: super::AssemblerOptions,
) -> Result<crate::binary::Binary, crate::error::Error> {
unsafe {
let mut binary = std::ptr::null_mut();
let mut diagnostic = std::ptr::null_mut();
let res = assembler::assemble(
self.inner,
text.as_ptr() as *const _,
text.len(),
options.into(),
&mut binary,
&mut diagnostic,
);
// Always wrap diagnostic, it's fine if it's null
use std::convert::TryFrom;
let diagnostic = crate::error::Diagnostic::try_from(diagnostic).ok();
match res {
shared::SpirvResult::Success => {
if binary.is_null() {
return Err(crate::error::Error {
inner: shared::SpirvResult::InternalError,
diagnostic: Some("spirv assemble indicated success but did not return a valid binary".to_owned().into()),
});
}
let bin = crate::binary::external::ExternalBinary::new(binary);
Ok(crate::binary::Binary::External(bin))
}
other => Err(crate::error::Error {
inner: other,
diagnostic,
}),
}
}
}
}
impl Default for CompiledAssembler {
fn default() -> Self {
Self::with_env(crate::TargetEnv::default())
}
}
impl Drop for CompiledAssembler {
fn drop(&mut self) {
unsafe {
shared::context_destroy(self.inner);
}
}
}

View File

@ -0,0 +1,36 @@
pub struct ToolAssembler {
target_env: crate::TargetEnv,
}
use super::Assembler;
impl Assembler for ToolAssembler {
fn with_env(target_env: crate::TargetEnv) -> Self {
Self { target_env }
}
fn assemble(
&self,
text: &str,
options: super::AssemblerOptions,
) -> Result<crate::binary::Binary, crate::error::Error> {
let mut cmd = std::process::Command::new("spirv-as");
cmd.arg("--target-env").arg(self.target_env.to_string());
if options.preserve_numeric_ids {
cmd.arg("--preserve-numeric-ids");
}
let cmd_output =
crate::cmd::exec(cmd, Some(text.as_bytes()), crate::cmd::Output::Retrieve)?;
use std::convert::TryFrom;
crate::binary::Binary::try_from(cmd_output.binary)
}
}
impl Default for ToolAssembler {
fn default() -> Self {
Self::with_env(crate::TargetEnv::default())
}
}

86
spirv-tools/src/binary.rs Normal file
View File

@ -0,0 +1,86 @@
#[cfg(feature = "use-compiled-tools")]
pub mod external {
use spirv_tools_sys::shared;
pub struct ExternalBinary {
inner: *mut shared::Binary,
}
impl ExternalBinary {
pub(crate) fn new(bin: *mut shared::Binary) -> Self {
Self { inner: bin }
}
}
impl AsRef<[u32]> for ExternalBinary {
fn as_ref(&self) -> &[u32] {
unsafe { std::slice::from_raw_parts((*self.inner).code, (*self.inner).size) }
}
}
impl AsRef<[u8]> for ExternalBinary {
fn as_ref(&self) -> &[u8] {
unsafe {
std::slice::from_raw_parts(
(*self.inner).code as *const u8,
(*self.inner).size * std::mem::size_of::<u32>(),
)
}
}
}
impl Drop for ExternalBinary {
fn drop(&mut self) {
unsafe {
shared::binary_destroy(self.inner);
}
}
}
}
pub enum Binary {
#[cfg(feature = "use-compiled-tools")]
External(self::external::ExternalBinary),
OwnedU32(Vec<u32>),
OwnedU8(Vec<u8>),
}
impl std::convert::TryFrom<Vec<u8>> for Binary {
type Error = crate::Error;
fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {
if v.len() % std::mem::size_of::<u32>() != 0 {
Err(crate::Error {
inner: spirv_tools_sys::shared::SpirvResult::InvalidBinary,
diagnostic: None,
})
} else {
Ok(Binary::OwnedU8(v))
}
}
}
impl AsRef<[u32]> for Binary {
fn as_ref(&self) -> &[u32] {
match self {
#[cfg(feature = "use-compiled-tools")]
Self::External(bin) => bin.as_ref(),
Self::OwnedU32(v) => &v,
Self::OwnedU8(v) => {
// If you hit a panic here it's because try_from wasn't used ;)
crate::util::to_binary(&v).unwrap()
}
}
}
}
impl AsRef<[u8]> for Binary {
fn as_ref(&self) -> &[u8] {
match self {
#[cfg(feature = "use-compiled-tools")]
Self::External(bin) => bin.as_ref(),
Self::OwnedU32(v) => crate::util::from_binary(&v),
Self::OwnedU8(v) => &v,
}
}
}

189
spirv-tools/src/cmd.rs Normal file
View File

@ -0,0 +1,189 @@
use crate::error::Message;
use std::process::{Command, Stdio};
pub enum CmdError {
/// The binary failed to spawn, probably because it's not installed
/// or not in PATH
BinaryNotFound(std::io::Error),
/// An I/O error occurred accessing the process' pipes
Io(std::io::Error),
/// The binary ran, but returned a non-zero exit code and (hopefully)
/// diagnostics
ToolErrors {
exit_code: i32,
/// Messages that were parsed from the output
messages: Vec<Message>,
},
}
impl From<CmdError> for crate::error::Error {
fn from(ce: CmdError) -> Self {
use crate::SpirvResult;
match ce {
CmdError::BinaryNotFound(e) => Self {
inner: SpirvResult::Unsupported,
diagnostic: Some(format!("failed spawn executable: {}", e).into()),
},
CmdError::Io(e) => Self {
inner: SpirvResult::EndOfStream,
diagnostic: Some(
format!("i/o error occurred communicating with executable: {}", e).into(),
),
},
CmdError::ToolErrors {
exit_code,
messages,
} => {
// The C API just puts the last message as the diagnostic, so just do the
// same for now
let diagnostic = messages
.into_iter()
.last()
.map(crate::error::Diagnostic::from)
.unwrap_or_else(|| {
crate::error::Diagnostic::from(format!(
"tool exited with code {} and no output",
exit_code
))
});
Self {
inner: SpirvResult::InternalError, // this isn't really correct
diagnostic: Some(diagnostic),
}
}
}
}
}
pub struct CmdOutput {
/// The output the command is actually supposed to give back
pub binary: Vec<u8>,
/// Warning or Info level diagnostics that were gathered during execution
pub messages: Vec<Message>,
}
#[derive(PartialEq, Copy, Clone)]
pub enum Output {
/// Doesn't try to read stdout for tool output (other than diagnostics)
Ignore,
/// Attempts to retrieve the tool's output from stdout
Retrieve,
}
pub fn exec(
mut cmd: Command,
input: Option<&[u8]>,
retrieve_output: Output,
) -> Result<CmdOutput, CmdError> {
cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
// Create a temp dir for the input and/or output of the tool
let temp_dir = tempfile::tempdir().map_err(CmdError::Io)?;
// Output
let output_path = temp_dir.path().join("output");
if retrieve_output == Output::Retrieve {
cmd.arg("-o").arg(&output_path);
}
// Input
if let Some(input) = input {
let input_path = temp_dir.path().join("input");
std::fs::write(&input_path, input).map_err(CmdError::Io)?;
cmd.arg(&input_path);
}
let child = cmd.spawn().map_err(CmdError::BinaryNotFound)?;
let output = child.wait_with_output().map_err(CmdError::Io)?;
let code = match output.status.code() {
Some(code) => code,
None => {
#[cfg(unix)]
let message = {
use std::os::unix::process::ExitStatusExt;
format!(
"process terminated by signal: {}",
output.status.signal().unwrap_or(666)
)
};
#[cfg(not(unix))]
let message = "process ended in an unknown state".to_owned();
return Err(CmdError::ToolErrors {
exit_code: -1,
messages: vec![Message::fatal(message)],
});
}
};
// stderr should only ever contain error+ level diagnostics
if code != 0 {
let messages: Vec<_> = match String::from_utf8(output.stderr) {
Ok(errors) => errors
.lines()
.filter_map(|line| crate::error::Message::parse(line))
.collect(),
Err(e) => vec![Message::fatal(format!(
"unable to read stderr ({}) but process exited with code {}",
e, code
))],
};
return Err(CmdError::ToolErrors {
exit_code: code,
messages,
});
}
fn split(haystack: &[u8], needle: u8) -> impl Iterator<Item = &[u8]> {
struct Split<'a> {
haystack: &'a [u8],
needle: u8,
}
impl<'a> Iterator for Split<'a> {
type Item = &'a [u8];
fn next(&mut self) -> Option<&'a [u8]> {
if self.haystack.is_empty() {
return None;
}
let (ret, remaining) = match memchr::memchr(self.needle, self.haystack) {
Some(pos) => (&self.haystack[..pos], &self.haystack[pos + 1..]),
None => (self.haystack, &[][..]),
};
self.haystack = remaining;
Some(ret)
}
}
Split { haystack, needle }
}
let binary = match retrieve_output {
Output::Retrieve => std::fs::read(&output_path).map_err(CmdError::Io)?,
Output::Ignore => Vec::new(),
};
// Since we are retrieving the results via stdout, but it can also contain
// diagnostic messages, we need to be careful
let mut messages = Vec::new();
for line in split(&output.stdout, b'\n') {
if let Ok(s) = std::str::from_utf8(line) {
if let Some(msg) = crate::error::Message::parse(s) {
messages.push(msg);
continue;
}
}
break;
}
Ok(CmdOutput { binary, messages })
}

199
spirv-tools/src/error.rs Normal file
View File

@ -0,0 +1,199 @@
use spirv_tools_sys::{diagnostics, shared};
pub use diagnostics::MessageLevel;
pub use shared::SpirvResult;
#[derive(Debug, PartialEq)]
pub struct Error {
pub inner: shared::SpirvResult,
pub diagnostic: Option<Diagnostic>,
}
use std::fmt;
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.diagnostic {
Some(diag) => f.write_fmt(format_args!(
"{}:{}:{} - {}",
self.inner, diag.line, diag.column, diag.message
)),
None => f.write_fmt(format_args!("{}", self.inner)),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.inner)
}
}
#[derive(Debug, PartialEq)]
pub struct Diagnostic {
pub line: usize,
pub column: usize,
pub index: usize,
pub message: String,
pub is_text: bool,
}
#[cfg(feature = "use-compiled-tools")]
impl std::convert::TryFrom<*mut diagnostics::Diagnostic> for Diagnostic {
type Error = shared::SpirvResult;
#[allow(clippy::not_unsafe_ptr_arg_deref)]
fn try_from(diag: *mut diagnostics::Diagnostic) -> Result<Self, Self::Error> {
unsafe {
if diag.is_null() {
return Err(shared::SpirvResult::Success);
}
let message = std::ffi::CStr::from_ptr((*diag).error)
.to_string_lossy()
.to_string();
let res = Self {
line: (*diag).position.line,
column: (*diag).position.column,
index: (*diag).position.index,
message,
is_text: (*diag).is_text_source,
};
diagnostics::diagnostic_destroy(diag);
Ok(res)
}
}
}
impl From<String> for Diagnostic {
fn from(message: String) -> Self {
Self {
line: 0,
column: 0,
index: 0,
is_text: false,
message,
}
}
}
impl From<Message> for Diagnostic {
fn from(msg: Message) -> Self {
Self {
line: msg.line,
column: msg.column,
index: msg.index,
message: msg.message,
is_text: false,
}
}
}
#[derive(Debug)]
pub struct Message {
pub level: MessageLevel,
pub source: Option<String>,
pub line: usize,
pub column: usize,
pub index: usize,
pub message: String,
}
impl Message {
#[cfg(feature = "use-installed-tools")]
pub(crate) fn fatal(message: String) -> Self {
Self {
level: MessageLevel::Fatal,
source: None,
line: 0,
column: 0,
index: 0,
message,
}
}
#[cfg(feature = "use-compiled-tools")]
pub(crate) fn from_parts(
level: MessageLevel,
source: *const std::os::raw::c_char,
source_pos: *const diagnostics::Position,
msg: *const std::os::raw::c_char,
) -> Self {
unsafe {
let source = std::ffi::CStr::from_ptr(source).to_string_lossy();
let message = std::ffi::CStr::from_ptr(msg).to_string_lossy();
let (line, column, index) = if source_pos.is_null() {
(0, 0, 0)
} else {
(
(*source_pos).line,
(*source_pos).column,
(*source_pos).index,
)
};
Self {
level,
source: if source.is_empty() {
None
} else {
Some(source.into_owned())
},
line,
column,
index,
message: message.into_owned(),
}
}
}
#[cfg(feature = "use-installed-tools")]
pub(crate) fn parse(s: &str) -> Option<Self> {
s.find(": ")
.and_then(|i| {
let level = match &s[..i] {
"error" => MessageLevel::Error,
"warning" => MessageLevel::Warning,
"info" => MessageLevel::Info,
_ => return None,
};
Some((level, i))
})
.and_then(|(level, i)| {
s[i + 7..]
.find(": ")
.and_then(|i2| {
s[i + 7..i + 7 + i2]
.parse::<usize>()
.ok()
.map(|index| (index, i2))
})
.map(|(index, i2)| (level, index, i + 7 + i2 + 2))
})
.map(|(level, index, last)| Self {
level,
index,
message: s[last..].to_owned(),
source: None,
line: 0,
column: 0,
})
}
}
pub trait MessageCallback {
fn on_message(&mut self, msg: Message);
}
impl<F> MessageCallback for F
where
F: FnMut(Message),
{
fn on_message(&mut self, msg: Message) {
self(msg)
}
}

14
spirv-tools/src/lib.rs Normal file
View File

@ -0,0 +1,14 @@
pub mod assembler;
pub mod binary;
pub mod opt;
pub mod val;
pub mod error;
pub use error::{Error, SpirvResult};
pub use spirv_tools_sys::shared::TargetEnv;
#[cfg(feature = "use-installed-tools")]
pub(crate) mod cmd;
pub mod util;

66
spirv-tools/src/opt.rs Normal file
View File

@ -0,0 +1,66 @@
#[cfg(feature = "use-compiled-tools")]
pub mod compiled;
#[cfg(feature = "use-installed-tools")]
pub mod tool;
pub use spirv_tools_sys::opt::Passes;
/// Options for specifying the behavior of the optimizer
#[derive(Default, Clone)]
pub struct Options {
/// Records the validator options that should be passed to the validator,
/// the validator will run with the options before optimizer.
pub validator_options: Option<crate::val::ValidatorOptions>,
/// Records the maximum possible value for the id bound.
pub max_id_bound: Option<u32>,
/// Records whether all bindings within the module should be preserved.
pub preserve_bindings: bool,
/// Records whether all specialization constants within the module
/// should be preserved.
pub preserve_spec_constants: bool,
}
pub trait Optimizer {
fn with_env(target_env: crate::TargetEnv) -> Self;
fn optimize<MC: crate::error::MessageCallback>(
&self,
input: &[u32],
msg_callback: &mut MC,
options: Option<Options>,
) -> Result<crate::binary::Binary, crate::Error>;
/// Register a single pass with the the optimizer.
fn register_pass(&mut self, pass: Passes) -> &mut Self;
/// Registers passes that attempt to improve performance of generated code.
/// This sequence of passes is subject to constant review and will change
/// from time to time.
fn register_performance_passes(&mut self) -> &mut Self;
/// Registers passes that attempt to improve the size of generated code.
/// This sequence of passes is subject to constant review and will change
/// from time to time.
fn register_size_passes(&mut self) -> &mut Self;
/// Registers passes that attempt to legalize the generated code.
///
/// Note: this recipe is specially designed for legalizing SPIR-V. It should be
/// used by compilers after translating HLSL source code literally. It should
/// *not* be used by general workloads for performance or size improvement.
///
/// This sequence of passes is subject to constant review and will change
/// from time to time.
fn register_hlsl_legalization_passes(&mut self) -> &mut Self;
}
pub fn create(te: Option<crate::TargetEnv>) -> impl Optimizer {
let target_env = te.unwrap_or_default();
#[cfg(feature = "use-compiled-tools")]
{
compiled::CompiledOptimizer::with_env(target_env)
}
#[cfg(all(feature = "use-installed-tools", not(feature = "use-compiled-tools")))]
{
tool::ToolOptimizer::with_env(target_env)
}
}

View File

@ -0,0 +1,206 @@
use crate::error;
use spirv_tools_sys::opt;
pub struct Options {
pub(crate) inner: *mut opt::OptimizerOptions,
}
impl From<super::Options> for Options {
fn from(o: super::Options) -> Self {
unsafe {
let inner = opt::optimizer_options_create();
if let Some(vopts) = o.validator_options {
let vopts = crate::val::compiled::Options::from(vopts);
opt::optimizer_options_run_validator(inner, true);
// The validator options are copied, so it's fine to drop vopts
// after this call
opt::optimizer_options_set_validator_options(inner, vopts.inner);
}
if let Some(max_bound) = o.max_id_bound {
opt::optimizer_options_set_max_id_bound(inner, max_bound);
}
if o.preserve_bindings {
opt::optimizer_options_preserve_bindings(inner, true);
}
if o.preserve_spec_constants {
opt::optimizer_options_preserve_spec_constants(inner, true);
}
Self { inner }
}
}
}
impl Drop for Options {
#[inline]
fn drop(&mut self) {
unsafe { opt::optimizer_options_destroy(self.inner) }
}
}
pub struct CompiledOptimizer {
inner: *mut opt::Optimizer,
}
use super::Optimizer;
impl Optimizer for CompiledOptimizer {
fn with_env(target: crate::TargetEnv) -> Self {
Self {
inner: unsafe { opt::optimizer_create(target) },
}
}
fn optimize<MC: error::MessageCallback>(
&self,
input: &[u32],
msg_callback: &mut MC,
options: Option<super::Options>,
) -> Result<crate::binary::Binary, crate::Error> {
unsafe {
struct Ctx<'a> {
cb: &'a mut dyn error::MessageCallback,
}
let mut ctx = Ctx { cb: msg_callback };
let cb_ctx: *mut std::ffi::c_void = std::mem::transmute(&mut ctx);
extern "C" fn callback(
level: spirv_tools_sys::diagnostics::MessageLevel,
source: *const std::os::raw::c_char,
source_pos: *const spirv_tools_sys::diagnostics::Position,
msg: *const std::os::raw::c_char,
ctx: *mut std::ffi::c_void,
) {
unsafe {
let ctx: &mut Ctx<'_> = &mut *(ctx as *mut Ctx);
let msg = error::Message::from_parts(level, source, source_pos, msg);
ctx.cb.on_message(msg);
}
}
let mut binary = std::ptr::null_mut();
let options = options.map(Options::from);
let options = match options {
Some(opts) => opts.inner,
None => std::ptr::null(),
};
let res = opt::optimizer_run(
self.inner,
input.as_ptr(),
input.len(),
&mut binary,
callback,
cb_ctx,
options,
);
match res {
spirv_tools_sys::shared::SpirvResult::Success => {
if binary.is_null() {
return Err(error::Error {
inner: spirv_tools_sys::shared::SpirvResult::InternalError,
diagnostic: Some(crate::error::Diagnostic {
line: 0,
column: 0,
index: 0,
message: "spirv optimizer indicated success but did not return a valid binary".to_owned(),
is_text: false,
}),
});
}
Ok(crate::binary::Binary::External(
crate::binary::external::ExternalBinary::new(binary),
))
}
other => Err(error::Error {
inner: other,
diagnostic: None,
}),
}
}
}
/// Register a single pass with the the optimizer.
#[inline]
fn register_pass(&mut self, pass: super::Passes) -> &mut Self {
unsafe { opt::optimizer_register_pass(self.inner, pass) }
self
}
/// Registers passes that attempt to improve performance of generated code.
/// This sequence of passes is subject to constant review and will change
/// from time to time.
#[inline]
fn register_performance_passes(&mut self) -> &mut Self {
unsafe { opt::optimizer_register_performance_passes(self.inner) }
self
}
/// Registers passes that attempt to improve the size of generated code.
/// This sequence of passes is subject to constant review and will change
/// from time to time.
#[inline]
fn register_size_passes(&mut self) -> &mut Self {
unsafe { opt::optimizer_register_size_passes(self.inner) }
self
}
// /// Registers passes that have been prescribed for converting from Vulkan to
// /// WebGPU. This sequence of passes is subject to constant review and will
// /// change from time to time.
// #[inline]
// pub fn register_vulkan_to_webgpu_passes(&mut self) -> &mut Self {
// unsafe { opt::optimizer_register_vulkan_to_webgpu_passes(self.inner) }
// self
// }
// /// Registers passes that have been prescribed for converting from WebGPU to
// /// Vulkan. This sequence of passes is subject to constant review and will
// /// change from time to time.
// #[inline]
// pub fn register_webgpu_to_vulkan_passes(&mut self) -> &mut Self {
// unsafe { opt::optimizer_register_webgpu_to_vulkan_passes(self.inner) }
// self
// }
/// Registers passes that attempt to legalize the generated code.
///
/// Note: this recipe is specially designed for legalizing SPIR-V. It should be
/// used by compilers after translating HLSL source code literally. It should
/// *not* be used by general workloads for performance or size improvement.
///
/// This sequence of passes is subject to constant review and will change
/// from time to time.
#[inline]
fn register_hlsl_legalization_passes(&mut self) -> &mut Self {
unsafe { opt::optimizer_register_hlsl_legalization_passes(self.inner) }
self
}
}
impl Default for CompiledOptimizer {
fn default() -> Self {
Self::with_env(crate::TargetEnv::default())
}
}
impl Drop for CompiledOptimizer {
#[inline]
fn drop(&mut self) {
unsafe { opt::optimizer_destroy(self.inner) }
}
}

185
spirv-tools/src/opt/tool.rs Normal file
View File

@ -0,0 +1,185 @@
use crate::error;
#[derive(Default)]
pub struct ToolOptimizer {
target_env: crate::TargetEnv,
passes: Vec<super::Passes>,
use_perf_passes: bool,
use_size_passes: bool,
//use_vulkan_to_webgpu: bool,
//use_webgpu_to_vulkan: bool,
legalize_hlsl: bool,
}
use super::Optimizer;
impl Optimizer for ToolOptimizer {
fn with_env(target_env: crate::TargetEnv) -> Self {
Self {
target_env,
..Default::default()
}
}
fn optimize<MC: error::MessageCallback>(
&self,
input: &[u32],
msg_callback: &mut MC,
options: Option<super::Options>,
) -> Result<crate::binary::Binary, crate::Error> {
let mut cmd = std::process::Command::new("spirv-opt");
cmd.arg("--target-env").arg(self.target_env.to_string());
cmd.args(
self.passes
.iter()
.filter_map(|p| pass_to_string(*p).map(|s| format!("--{}", s))),
);
if self.use_perf_passes {
cmd.arg("-O");
}
if self.use_size_passes {
cmd.arg("-Os");
}
if self.legalize_hlsl {
cmd.arg("--legalize-hlsl");
}
if let Some(opts) = options {
if let Some(max_id_bound) = opts.max_id_bound {
cmd.arg(format!("--max-id-bound={}", max_id_bound));
}
if opts.preserve_bindings {
cmd.arg("--preserve-bindings");
}
if opts.preserve_spec_constants {
cmd.arg("--preserve-spec-constants");
}
if let Some(vopts) = opts.validator_options {
crate::val::tool::add_options(&mut cmd, vopts);
}
}
let input = crate::util::from_binary(input);
let cmd_output = crate::cmd::exec(cmd, Some(input), crate::cmd::Output::Retrieve)?;
for msg in cmd_output.messages {
msg_callback.on_message(msg);
}
use std::convert::TryFrom;
crate::binary::Binary::try_from(cmd_output.binary)
}
/// Register a single pass with the the optimizer.
#[inline]
fn register_pass(&mut self, pass: super::Passes) -> &mut Self {
self.passes.push(pass);
self
}
/// Registers passes that attempt to improve performance of generated code.
/// This sequence of passes is subject to constant review and will change
/// from time to time.
#[inline]
fn register_performance_passes(&mut self) -> &mut Self {
self.use_perf_passes = true;
self
}
/// Registers passes that attempt to improve the size of generated code.
/// This sequence of passes is subject to constant review and will change
/// from time to time.
#[inline]
fn register_size_passes(&mut self) -> &mut Self {
self.use_size_passes = true;
self
}
/// Registers passes that attempt to legalize the generated code.
///
/// Note: this recipe is specially designed for legalizing SPIR-V. It should be
/// used by compilers after translating HLSL source code literally. It should
/// *not* be used by general workloads for performance or size improvement.
///
/// This sequence of passes is subject to constant review and will change
/// from time to time.
#[inline]
fn register_hlsl_legalization_passes(&mut self) -> &mut Self {
self.legalize_hlsl = true;
self
}
}
fn pass_to_string(pass: super::Passes) -> Option<&'static str> {
use super::Passes::*;
Some(match pass {
Null => return None,
StripAtomicCounterMemory => "strip-atomic-counter-memory",
StripDebugInfo => "strip-debug",
StripReflectInfo => "strip-reflect",
EliminateDeadFunctions => "eliminate-dead-functions",
EliminateDeadMembers => "eliminate-dead-members",
FlattenDecoration => "flatten-decorations",
FreezeSpecConstantValue => "freeze-spec-const",
FoldSpecConstantOpAndComposite => "fold-spec-const-op-composite",
UnifyConstant => "unify-const",
EliminateDeadConstant => "eliminate-dead-const",
StrengthReduction => "strength-reduction",
BlockMerge => "merge-blocks",
InlineExhaustive => "inline-entry-points-exhaustive",
InlineOpaque => "inline-entry-points-opaque",
LocalSingleBlockLoadStoreElim => "eliminate-local-single-block",
DeadBranchElim => "eliminate-dead-branches",
LocalMultiStoreElim => "eliminate-local-multi-store",
LocalAccessChainConvert => "convert-local-access-chains",
LocalSingleStoreElim => "eliminate-local-single-store",
InsertExtractElim => "eliminate-insert-extract",
DeadInsertElim => "eliminate-dead-inserts",
AggressiveDCE => "eliminate-dead-code-aggressive",
PropagateLineInfo => "propagate-line-info",
RedundantLineInfoElim => "eliminate-redundant-line-info",
CompactIds => "compact-ids",
RemoveDuplicates => "remove-duplicates",
CFGCleanup => "cfg-cleanup",
DeadVariableElimination => "eliminate-dead-variables",
MergeReturn => "merge-return",
LocalRedundancyElimination => "local-redundancy-elimination",
LoopInvariantCodeMotion => "loop-invariant-code-motion",
LoopPeeling => "loop-peeling",
LoopUnswitch => "loop-unswitch",
RedundancyElimination => "redundancy-elimination",
PrivateToLocal => "private-to-local",
ConditionalConstantPropagation => "ccp",
Workaround1209 => "workaround-1209",
IfConversion => "if-conversion",
ReplaceInvalidOpcode => "replace-invalid-opcode",
Simplification => "simplify-instructions",
SSARewrite => "ssa-rewrite",
ConvertRelaxedToHalf => "convert-relaxed-to-half",
RelaxFloatOps => "relax-float-ops",
CopyPropagateArrays => "copy-propagate-arrays",
VectorDCE => "vector-dce",
ReduceLoadSize => "reduce-load-size",
CombineAccessChains => "combine-access-chains",
UpgradeMemoryModel => "upgrade-memory-model",
CodeSinking => "code-sink",
GenerateWebGPUInitializers => "generate-webgpu-initializers",
FixStorageClass => "fix-storage-class",
LegalizeVectorShuffle => "legalize-vector-shuffle",
DecomposeInitializedVariables => "decompose-initialized-variables",
SplitInvalidUnreachable => "split-invalid-unreachable",
GraphicsRobustAccess => "graphics-robust-access",
DescriptorScalarReplacement => "descriptor-scalar-replacement",
WrapOpKill => "wrap-opkill",
AmdExtToKhr => "amd-ext-to-khr",
})
}

24
spirv-tools/src/util.rs Normal file
View File

@ -0,0 +1,24 @@
pub fn from_binary(bin: &[u32]) -> &[u8] {
unsafe {
std::slice::from_raw_parts(
bin.as_ptr() as *const u8,
bin.len() * std::mem::size_of::<u32>(),
)
}
}
pub fn to_binary(bytes: &[u8]) -> Result<&[u32], crate::Error> {
if bytes.len() % std::mem::size_of::<u32>() != 0 {
return Err(crate::Error {
inner: spirv_tools_sys::shared::SpirvResult::InvalidBinary,
diagnostic: None,
});
}
Ok(unsafe {
std::slice::from_raw_parts(
bytes.as_ptr() as *const u32,
bytes.len() / std::mem::size_of::<u32>(),
)
})
}

94
spirv-tools/src/val.rs Normal file
View File

@ -0,0 +1,94 @@
#[cfg(feature = "use-compiled-tools")]
pub mod compiled;
#[cfg(feature = "use-installed-tools")]
pub mod tool;
#[derive(Default, Clone)]
pub struct ValidatorOptions {
/// Record whether or not the validator should relax the rules on types for
/// stores to structs. When relaxed, it will allow a type mismatch as long as
/// the types are structs with the same layout. Two structs have the same layout
/// if
///
/// 1) the members of the structs are either the same type or are structs with
/// same layout, and
///
/// 2) the decorations that affect the memory layout are identical for both
/// types. Other decorations are not relevant.
pub relax_struct_store: bool,
/// Records whether or not the validator should relax the rules on pointer usage
/// in logical addressing mode.
///
/// When relaxed, it will allow the following usage cases of pointers:
/// 1) OpVariable allocating an object whose type is a pointer type
/// 2) OpReturnValue returning a pointer value
pub relax_logical_pointer: bool,
/// Records whether or not the validator should relax the rules because it is
/// expected that the optimizations will make the code legal.
///
/// When relaxed, it will allow the following:
/// 1) It will allow relaxed logical pointers. Setting this option will also
/// set that option.
/// 2) Pointers that are pass as parameters to function calls do not have to
/// match the storage class of the formal parameter.
/// 3) Pointers that are actaul parameters on function calls do not have to point
/// to the same type pointed as the formal parameter. The types just need to
/// logically match.
pub before_legalization: bool,
/// Records whether the validator should use "relaxed" block layout rules.
/// Relaxed layout rules are described by Vulkan extension
/// VK_KHR_relaxed_block_layout, and they affect uniform blocks, storage blocks,
/// and push constants.
///
/// This is enabled by default when targeting Vulkan 1.1 or later.
/// Relaxed layout is more permissive than the default rules in Vulkan 1.0.
pub relax_block_layout: Option<bool>,
/// Records whether the validator should use standard block layout rules for
/// uniform blocks.
pub uniform_buffer_standard_layout: bool,
/// Records whether the validator should use "scalar" block layout rules.
/// Scalar layout rules are more permissive than relaxed block layout.
///
/// See Vulkan extnesion VK_EXT_scalar_block_layout. The scalar alignment is
/// defined as follows:
/// - scalar alignment of a scalar is the scalar size
/// - scalar alignment of a vector is the scalar alignment of its component
/// - scalar alignment of a matrix is the scalar alignment of its component
/// - scalar alignment of an array is the scalar alignment of its element
/// - scalar alignment of a struct is the max scalar alignment among its
/// members
///
/// For a struct in Uniform, StorageClass, or PushConstant:
/// - a member Offset must be a multiple of the member's scalar alignment
/// - ArrayStride or MatrixStride must be a multiple of the array or matrix
/// scalar alignment
pub scalar_block_layout: bool,
/// Records whether or not the validator should skip validating standard
/// uniform/storage block layout.
pub skip_block_layout: bool,
/// Applies a maximum to one or more Universal limits
pub max_limits: Vec<(spirv_tools_sys::val::ValidatorLimits, u32)>,
}
pub trait Validator: Default {
fn with_env(target_env: crate::TargetEnv) -> Self;
fn validate(
&self,
binary: &[u32],
options: Option<ValidatorOptions>,
) -> Result<(), crate::error::Error>;
}
pub fn create(te: Option<crate::TargetEnv>) -> impl Validator {
let target_env = te.unwrap_or_default();
#[cfg(feature = "use-compiled-tools")]
{
compiled::CompiledValidator::with_env(target_env)
}
#[cfg(all(feature = "use-installed-tools", not(feature = "use-compiled-tools")))]
{
tool::ToolValidator::with_env(target_env)
}
}

View File

@ -0,0 +1,117 @@
use spirv_tools_sys::{shared, val};
pub struct Options {
pub(crate) inner: *mut val::ValidatorOptions,
}
impl From<super::ValidatorOptions> for Options {
fn from(vo: super::ValidatorOptions) -> Self {
unsafe {
let inner = val::validator_options_create();
// This is AFAICT the only one that _can_ default to true based on our target
// so we treat it differently
if let Some(relax) = vo.relax_block_layout {
val::validator_options_set_relax_block_layout(inner, relax);
}
if vo.relax_struct_store {
val::validator_options_set_relax_store_struct(inner, true);
}
if vo.relax_logical_pointer {
val::validator_options_set_relax_logical_pointer(inner, true);
}
if vo.before_legalization {
val::validator_options_set_before_legalization(inner, true);
}
if vo.uniform_buffer_standard_layout {
val::validator_options_set_uniform_buffer_standard_layout(inner, true);
}
if vo.scalar_block_layout {
val::validator_options_set_scalar_block_layout(inner, true);
}
if vo.skip_block_layout {
val::validator_options_set_skip_block_layout(inner, true);
}
for (limit, val) in vo.max_limits {
val::validator_options_set_limit(inner, limit, val);
}
Self { inner }
}
}
}
impl Drop for Options {
fn drop(&mut self) {
unsafe { val::validator_options_destroy(self.inner) }
}
}
pub struct CompiledValidator {
inner: *mut shared::ToolContext,
}
use super::Validator;
impl Validator for CompiledValidator {
fn with_env(target_env: crate::TargetEnv) -> Self {
Self {
inner: unsafe { shared::context_create(target_env) },
}
}
fn validate(
&self,
binary: &[u32],
options: Option<super::ValidatorOptions>,
) -> Result<(), crate::error::Error> {
unsafe {
let mut diagnostic = std::ptr::null_mut();
let options = options.map(Options::from);
let options = match options {
Some(opts) => opts.inner,
None => std::ptr::null(),
};
let res = val::validate(
self.inner,
binary.as_ptr(),
binary.len(),
options,
&mut diagnostic,
);
use std::convert::TryFrom;
let diagnostic = crate::error::Diagnostic::try_from(diagnostic).ok();
match res {
shared::SpirvResult::Success => Ok(()),
other => Err(crate::error::Error {
inner: other,
diagnostic,
}),
}
}
}
}
impl Default for CompiledValidator {
fn default() -> Self {
Self::with_env(crate::TargetEnv::default())
}
}
impl Drop for CompiledValidator {
fn drop(&mut self) {
unsafe { shared::context_destroy(self.inner) }
}
}

View File

@ -0,0 +1,87 @@
use std::process::Command;
#[derive(Default)]
pub struct ToolValidator {
target_env: crate::TargetEnv,
}
use super::Validator;
impl Validator for ToolValidator {
fn with_env(target_env: crate::TargetEnv) -> Self {
Self { target_env }
}
fn validate(
&self,
binary: &[u32],
options: Option<super::ValidatorOptions>,
) -> Result<(), crate::error::Error> {
let mut cmd = Command::new("spirv-val");
cmd.arg("--target-env").arg(self.target_env.to_string());
if let Some(opts) = options {
add_options(&mut cmd, opts);
}
let input = crate::util::from_binary(binary);
crate::cmd::exec(cmd, Some(input), crate::cmd::Output::Ignore)?;
Ok(())
}
}
pub(crate) fn add_options(cmd: &mut Command, opts: super::ValidatorOptions) {
if opts.relax_logical_pointer {
cmd.arg("--relax-logical-pointer");
}
if let Some(true) = opts.relax_block_layout {
cmd.arg("--relax-block-layout");
}
if opts.uniform_buffer_standard_layout {
cmd.arg("--uniform-buffer-standard-layout");
}
if opts.scalar_block_layout {
cmd.arg("--scalar-block-layout");
}
if opts.skip_block_layout {
cmd.arg("--skip-block-layout");
}
if opts.relax_struct_store {
cmd.arg("--relax-struct-store");
}
if opts.before_legalization {
cmd.arg("--before-hlsl-legalization");
}
add_limits(cmd, &opts.max_limits);
}
fn add_limits(cmd: &mut Command, limits: &[(spirv_tools_sys::val::ValidatorLimits, u32)]) {
use spirv_tools_sys::val::ValidatorLimits;
for (limit, val) in limits {
cmd.arg(format!(
"--max-{}",
match limit {
ValidatorLimits::StructMembers => "struct-members",
ValidatorLimits::StructDepth => "struct-depth",
ValidatorLimits::LocalVariables => "local-variables",
ValidatorLimits::GlobalVariables => "global-variables",
ValidatorLimits::SwitchBranches => "switch-branches",
ValidatorLimits::FunctionArgs => "function-args",
ValidatorLimits::ControlFlowNestingDepth => "control-flow-nesting-depth",
ValidatorLimits::AccessChainIndexes => "access-chain-indexes",
ValidatorLimits::IdBound => "id-bound",
}
))
.arg(val.to_string());
}
}