From 6689a54d8a046063fad176ffc0fcc1c2cfbe02e8 Mon Sep 17 00:00:00 2001 From: Shahbaz Youssefi Date: Thu, 21 Jan 2021 00:36:14 -0500 Subject: [PATCH] Vulkan: autogen for SPIR-V instruction build and parse Handwritten SPIR-V instruction parse and build code is replaced with autogenerated functions based on the SPIR-V grammar. Bug: angleproject:4889 Change-Id: I09d724fd944e79c03fe4eadca3ee3e3ef0b49872 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2644721 Commit-Queue: Shahbaz Youssefi Reviewed-by: Jamie Madill Reviewed-by: Tim Van Patten --- BUILD.gn | 2 + .../SPIR-V_helpers.json | 14 + scripts/run_code_generation.py | 2 + src/common/FastVector.h | 12 +- src/common/spirv/BUILD.gn | 29 + .../spirv/gen_spirv_builder_and_parser.py | 527 +++ .../spirv_instruction_builder_autogen.cpp | 3507 ++++++++++++++ .../spirv/spirv_instruction_builder_autogen.h | 1121 +++++ .../spirv_instruction_parser_autogen.cpp | 4036 +++++++++++++++++ .../spirv/spirv_instruction_parser_autogen.h | 1137 +++++ src/common/spirv/spirv_types.h | 102 + .../renderer/glslang_wrapper_utils.cpp | 1598 ++----- 12 files changed, 10988 insertions(+), 1099 deletions(-) create mode 100644 scripts/code_generation_hashes/SPIR-V_helpers.json create mode 100644 src/common/spirv/BUILD.gn create mode 100755 src/common/spirv/gen_spirv_builder_and_parser.py create mode 100644 src/common/spirv/spirv_instruction_builder_autogen.cpp create mode 100644 src/common/spirv/spirv_instruction_builder_autogen.h create mode 100644 src/common/spirv/spirv_instruction_parser_autogen.cpp create mode 100644 src/common/spirv/spirv_instruction_parser_autogen.h create mode 100644 src/common/spirv/spirv_types.h diff --git a/BUILD.gn b/BUILD.gn index 3e5ac3617..2f17f02dc 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -685,6 +685,8 @@ if (angle_enable_vulkan || angle_enable_metal) { ] deps = [ ":libANGLE_headers", + "$angle_root/src/common/spirv:angle_spirv_builder", + "$angle_root/src/common/spirv:angle_spirv_parser", "${angle_glslang_dir}:glslang_default_resource_limits_sources", "${angle_glslang_dir}:glslang_lib_sources", "${angle_spirv_headers_dir}:spv_headers", diff --git a/scripts/code_generation_hashes/SPIR-V_helpers.json b/scripts/code_generation_hashes/SPIR-V_helpers.json new file mode 100644 index 000000000..cced70d71 --- /dev/null +++ b/scripts/code_generation_hashes/SPIR-V_helpers.json @@ -0,0 +1,14 @@ +{ + "src/common/spirv/gen_spirv_builder_and_parser.py": + "02381e3a7cf898265de3ba438b3b6e5e", + "src/common/spirv/spirv_instruction_builder_autogen.cpp": + "b9c0c27ab2de86955528d4d8ba9be817", + "src/common/spirv/spirv_instruction_builder_autogen.h": + "9629f02ff30720ec38a9aad0fc5c1503", + "src/common/spirv/spirv_instruction_parser_autogen.cpp": + "55d28bb4b003dbecf31e162ff996fc4f", + "src/common/spirv/spirv_instruction_parser_autogen.h": + "68c5746bc94e6b9f891ff2a11869ccd1", + "third_party/vulkan-deps/spirv-headers/src/include/spirv/1.0/spirv.core.grammar.json": + "a8c4239344b2fc10bfc4ace7ddee1867" +} \ No newline at end of file diff --git a/scripts/run_code_generation.py b/scripts/run_code_generation.py index 15471c97c..e5d54ed38 100755 --- a/scripts/run_code_generation.py +++ b/scripts/run_code_generation.py @@ -115,6 +115,8 @@ generators = { 'scripts/gen_proc_table.py', 'restricted traces': 'src/tests/restricted_traces/gen_restricted_traces.py', + 'SPIR-V helpers': + 'src/common/spirv/gen_spirv_builder_and_parser.py', 'Static builtins': 'src/compiler/translator/gen_builtin_symbols.py', 'uniform type': diff --git a/src/common/FastVector.h b/src/common/FastVector.h index ff7f161f2..c7520d059 100644 --- a/src/common/FastVector.h +++ b/src/common/FastVector.h @@ -70,6 +70,9 @@ class FastVector final void push_back(const value_type &value); void push_back(value_type &&value); + template + void emplace_back(Args &&... args); + void pop_back(); reference front(); @@ -287,10 +290,17 @@ ANGLE_INLINE void FastVector::push_back(const value_type &value) template ANGLE_INLINE void FastVector::push_back(value_type &&value) +{ + emplace_back(std::move(value)); +} + +template +template +ANGLE_INLINE void FastVector::emplace_back(Args &&... args) { if (mSize == mReservedSize) ensure_capacity(mSize + 1); - mData[mSize++] = std::move(value); + mData[mSize++] = std::move(T(std::forward(args)...)); } template diff --git a/src/common/spirv/BUILD.gn b/src/common/spirv/BUILD.gn new file mode 100644 index 000000000..0ca6174b6 --- /dev/null +++ b/src/common/spirv/BUILD.gn @@ -0,0 +1,29 @@ +# Copyright 2021 The ANGLE Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("../../../gni/angle.gni") + +angle_source_set("angle_spirv_builder") { + sources = [ + "spirv_instruction_builder_autogen.cpp", + "spirv_instruction_builder_autogen.h", + "spirv_types.h", + ] + deps = [ + "$angle_root:angle_common", + "${angle_spirv_headers_dir}:spv_headers", + ] +} + +angle_source_set("angle_spirv_parser") { + sources = [ + "spirv_instruction_parser_autogen.cpp", + "spirv_instruction_parser_autogen.h", + "spirv_types.h", + ] + deps = [ + "$angle_root:angle_common", + "${angle_spirv_headers_dir}:spv_headers", + ] +} diff --git a/src/common/spirv/gen_spirv_builder_and_parser.py b/src/common/spirv/gen_spirv_builder_and_parser.py new file mode 100755 index 000000000..4579df6c3 --- /dev/null +++ b/src/common/spirv/gen_spirv_builder_and_parser.py @@ -0,0 +1,527 @@ +#!/usr/bin/python +# Copyright 2021 The ANGLE Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# gen_spirv_builder_and_parser.py: +# Code generation for SPIR-V instruction builder and parser. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. + +import itertools +import json +import os +import sys + +# ANGLE uses SPIR-V 1.0 currently, so there's no reason to generate code for newer instructions. +SPIRV_GRAMMAR_FILE = '../../../third_party/vulkan-deps/spirv-headers/src/include/spirv/1.0/spirv.core.grammar.json' + +# The script has two sets of outputs, a header and source file for SPIR-V code generation, and a +# header and source file for SPIR-V parsing. +SPIRV_BUILDER_FILE = 'spirv_instruction_builder' +SPIRV_PARSER_FILE = 'spirv_instruction_parser' + +# The types are either defined in spirv_types.h (to use strong types), or are enums that are +# defined by SPIR-V headers. +ANGLE_DEFINED_TYPES = [ + 'IdRef', 'IdResult', 'IdResultType', 'IdMemorySemantics', 'IdScope', 'LiteralInteger', + 'LiteralString', 'LiteralContextDependentNumber', 'LiteralExtInstInteger', + 'PairLiteralIntegerIdRef', 'PairIdRefLiteralInteger', 'PairIdRefIdRef' +] + +HEADER_TEMPLATE = """// GENERATED FILE - DO NOT EDIT. +// Generated by {script_name} using data from {data_source_name}. +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// {file_name}_autogen.h: +// Functions to {verb} SPIR-V binary for each instruction. + +#ifndef COMMON_SPIRV_{file_name_capitalized}AUTOGEN_H_ +#define COMMON_SPIRV_{file_name_capitalized}AUTOGEN_H_ + +#include + +#include "spirv_types.h" + +namespace angle +{{ +namespace spirv +{{ +{prototype_list} +}} // namespace spirv +}} // namespace angle + +#endif // COMMON_SPIRV_{file_name_capitalized}AUTOGEN_H_ +""" + +SOURCE_TEMPLATE = """// GENERATED FILE - DO NOT EDIT. +// Generated by {script_name} using data from {data_source_name}. +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// {file_name}_autogen.cpp: +// Functions to {verb} SPIR-V binary for each instruction. + +#include "{file_name}_autogen.h" + +#include + +#include "common/debug.h" + +namespace angle +{{ +namespace spirv +{{ +{helper_functions} + +{function_list} +}} // namespace spirv +}} // namespace angle +""" + +BUILDER_HELPER_FUNCTIONS = """namespace +{ +uint32_t MakeLengthOp(size_t length, spv::Op op) +{ + ASSERT(length <= 0xFFFFu); + ASSERT(op <= 0xFFFFu); + + return static_cast(length) << 16 | op; +} +} // anonymous namespace""" + +PARSER_FIXED_FUNCTIONS_PROTOTYPES = """void GetInstructionOpAndLength(const uint32_t *_instruction, + spv::Op *opOut, uint32_t *lengthOut); +""" + +PARSER_FIXED_FUNCTIONS = """void GetInstructionOpAndLength(const uint32_t *_instruction, + spv::Op *opOut, uint32_t *lengthOut) +{ + constexpr uint32_t kOpMask = 0xFFFFu; + *opOut = static_cast(_instruction[0] & kOpMask); + *lengthOut = _instruction[0] >> 16; +} +""" + +TEMPLATE_BUILDER_FUNCTION_PROTOTYPE = """void Write{op}(std::vector *blob {param_list})""" +TEMPLATE_BUILDER_FUNCTION_BODY = """{{ + const size_t startSize = blob->size(); + blob->push_back(0); + {push_back_lines} + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::Op{op}); +}} +""" + +TEMPLATE_PARSER_FUNCTION_PROTOTYPE = """void Parse{op}(const uint32_t *_instruction {param_list})""" +TEMPLATE_PARSER_FUNCTION_BODY = """{{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::Op{op}); + uint32_t _o = 1; + {parse_lines} +}} +""" + + +def load_grammar(grammar_file): + with open(grammar_file) as grammar_in: + grammar = json.loads(grammar_in.read()) + + return grammar + + +def remove_chars(string, chars): + return filter(lambda c: c not in chars, string) + + +def make_camel_case(name): + return name[0].lower() + name[1:] + + +class Writer: + + def __init__(self): + self.path_prefix = os.path.dirname(os.path.realpath(__file__)) + os.path.sep + self.grammar = load_grammar(self.path_prefix + SPIRV_GRAMMAR_FILE) + + # If an instruction has a parameter of these types, the instruction is ignored + self.unsupported_kinds = set(['LiteralSpecConstantOpInteger']) + # If an instruction requires a capability of these kinds, the instruction is ignored + self.unsupported_capabilities = set(['Kernel']) + # If an instruction requires an extension other than these, the instruction is ignored + self.supported_extensions = set([]) + # List of bit masks. These have 'Mask' added to their typename in SPIR-V headers. + self.bit_mask_types = set([]) + + # List of generated instructions builder/parser functions so far. + self.instruction_builder_prototypes = [] + self.instruction_builder_impl = [] + self.instruction_parser_prototypes = [PARSER_FIXED_FUNCTIONS_PROTOTYPES] + self.instruction_parser_impl = [PARSER_FIXED_FUNCTIONS] + + def write_builder_and_parser(self): + """Generates four files, a set of header and source files for generating SPIR-V instructions + and a set for parsing SPIR-V instructions. Only Vulkan instructions are processed (and not + OpenCL for example), and some assumptions are made based on ANGLE's usage (for example that + constants always fit in one 32-bit unit, as GLES doesn't support double or 64-bit types). + + Additionally, enums and other parameter 'kinds' are not parsed from the json file, but + rather use the definitions from the SPIR-V headers repository and the spirv_types.h file.""" + + # Recurse through capabilities and accumulate ones that depend on unsupported ones. + self.accumulate_unsupported_capabilities() + + self.find_bit_mask_types() + + for instruction in self.grammar['instructions']: + self.generate_instruction_functions(instruction) + + # Write out the files. + data_source_base_name = os.path.basename(SPIRV_GRAMMAR_FILE) + builder_template_args = { + 'script_name': sys.argv[0], + 'data_source_name': data_source_base_name, + 'file_name': SPIRV_BUILDER_FILE, + 'file_name_capitalized': remove_chars(SPIRV_BUILDER_FILE.upper(), '_'), + 'verb': 'generate', + 'helper_functions': BUILDER_HELPER_FUNCTIONS, + 'prototype_list': ''.join(self.instruction_builder_prototypes), + 'function_list': ''.join(self.instruction_builder_impl) + } + parser_template_args = { + 'script_name': sys.argv[0], + 'data_source_name': data_source_base_name, + 'file_name': SPIRV_PARSER_FILE, + 'file_name_capitalized': remove_chars(SPIRV_PARSER_FILE.upper(), '_'), + 'verb': 'parse', + 'helper_functions': '', + 'prototype_list': ''.join(self.instruction_parser_prototypes), + 'function_list': ''.join(self.instruction_parser_impl) + } + + with (open(self.path_prefix + SPIRV_BUILDER_FILE + '_autogen.h', 'w')) as f: + f.write(HEADER_TEMPLATE.format(**builder_template_args)) + + with (open(self.path_prefix + SPIRV_BUILDER_FILE + '_autogen.cpp', 'w')) as f: + f.write(SOURCE_TEMPLATE.format(**builder_template_args)) + + with (open(self.path_prefix + SPIRV_PARSER_FILE + '_autogen.h', 'w')) as f: + f.write(HEADER_TEMPLATE.format(**parser_template_args)) + + with (open(self.path_prefix + SPIRV_PARSER_FILE + '_autogen.cpp', 'w')) as f: + f.write(SOURCE_TEMPLATE.format(**parser_template_args)) + + def requires_unsupported_capability(self, item): + depends = item.get('capabilities', []) + return any([dep in self.unsupported_capabilities for dep in depends]) + + def requires_unsupported_extension(self, item): + extensions = item.get('extensions', []) + return any([ext not in self.supported_extensions for ext in extensions]) + + def accumulate_unsupported_capabilities(self): + operand_kinds = self.grammar['operand_kinds'] + + # Find the Capability enum + for kind in filter(lambda entry: entry['kind'] == 'Capability', operand_kinds): + capabilities = kind['enumerants'] + for capability in capabilities: + name = capability['enumerant'] + # For each capability, see if any of the capabilities they depend on is unsupported. + # If so, add the capability to the list of unsupported ones. + if self.requires_unsupported_capability(capability): + self.unsupported_capabilities.add(name) + continue + # Do the same for extensions + if self.requires_unsupported_extension(capability): + self.unsupported_capabilities.add(name) + + def find_bit_mask_types(self): + operand_kinds = self.grammar['operand_kinds'] + + # Find the BitEnum categories + for bitEnumEntry in filter(lambda entry: entry['category'] == 'BitEnum', operand_kinds): + self.bit_mask_types.add(bitEnumEntry['kind']) + + def get_operand_name(self, operand): + kind = operand['kind'] + name = operand.get('name') + + # If no name is given, derive the name from the kind + if name is None: + assert (kind.find(' ') == -1) + return make_camel_case(kind) + + quantifier = operand.get('quantifier', '') + name = remove_chars(name, "'") + + # First, a number of special-cases for optional lists + if quantifier == '*': + # For IdRefs, change 'Xyz 1', +\n'Xyz 2', +\n...' to xyzList + if kind == 'IdRef': + if name.find(' ') != -1: + name = name[0:name.find(' ')] + return make_camel_case(name) + 'List' + + # Otherwise, it's a pair in the form of 'Xyz, Abc, ...', which is changed to + # xyzAbcPairList + name = remove_chars(name, " ,.") + return make_camel_case(name) + 'PairList' + + # Otherwise, remove invalid characters and make the first letter lower case. + name = remove_chars(name, " .,+\n~") + name = make_camel_case(name) + + # Make sure the name is not a C++ keyword + return 'default_' if name == 'default' else name + + def get_operand_namespace(self, kind): + return '' if kind in ANGLE_DEFINED_TYPES else 'spv::' + + def get_operand_type_suffix(self, kind): + return 'Mask' if kind in self.bit_mask_types else '' + + def get_kind_cpp_type(self, kind): + return self.get_operand_namespace(kind) + kind + self.get_operand_type_suffix(kind) + + def get_operand_type_in_and_out(self, operand): + kind = operand['kind'] + quantifier = operand.get('quantifier', '') + + is_array = quantifier == '*' + is_optional = quantifier == '?' + cpp_type = self.get_kind_cpp_type(kind) + + if is_array: + type_in = 'const ' + cpp_type + 'List &' + type_out = cpp_type + 'List *' + elif is_optional: + type_in = cpp_type + ' *' + type_out = cpp_type + ' *' + else: + type_in = cpp_type + type_out = cpp_type + ' *' + + return (type_in, type_out, is_array, is_optional) + + def get_operand_push_back_line(self, operand, operand_name, is_array, is_optional): + kind = operand['kind'] + pre = '' + post = '' + accessor = '.' + item = operand_name + item_dereferenced = item + if is_optional: + # If optional, surround with an if. + pre = 'if (' + operand_name + ') {\n' + post = '\n}' + accessor = '->' + item_dereferenced = '*' + item + elif is_array: + # If array, surround with a loop. + pre = 'for (const auto &operand : ' + operand_name + ') {\n' + post = '\n}' + item = 'operand' + item_dereferenced = item + + # Usually the operand is one uint32_t, but it may be pair. Handle the pairs especially. + if kind == 'PairLiteralIntegerIdRef': + line = 'blob->push_back(' + item + accessor + 'literal);' + line += 'blob->push_back(' + item + accessor + 'id);' + elif kind == 'PairIdRefLiteralInteger': + line = 'blob->push_back(' + item + accessor + 'id);' + line += 'blob->push_back(' + item + accessor + 'literal);' + elif kind == 'PairIdRefIdRef': + line = 'blob->push_back(' + item + accessor + 'id1);' + line += 'blob->push_back(' + item + accessor + 'id2);' + elif kind == 'LiteralString': + line = '{size_t d = blob->size();' + line += 'blob->resize(d + strlen(' + item_dereferenced + ') / 4 + 1, 0);' + # We currently don't have any big-endian devices in the list of supported platforms. + # Literal strings in SPIR-V are stored little-endian (SPIR-V 1.0 Section 2.2.1, Literal + # String), so if a big-endian device is to be supported, the string copy here should + # be adjusted. + line += 'ASSERT(IsLittleEndian());' + line += 'strcpy(reinterpret_cast(blob->data() + d), ' + item_dereferenced + ');}' + else: + line = 'blob->push_back(' + item_dereferenced + ');' + + return pre + line + post + + def get_operand_parse_line(self, operand, operand_name, is_array, is_optional): + kind = operand['kind'] + pre = '' + post = '' + accessor = '->' + + if is_optional: + # If optional, surround with an if, both checking if argument is provided, and whether + # it exists. + pre = 'if (' + operand_name + ' && _o < _length) {\n' + post = '\n}' + elif is_array: + # If array, surround with an if and a loop. + pre = 'if (' + operand_name + ') {\n' + pre += 'while (_o < _length) {\n' + post = '\n}}' + accessor = '.' + + # Usually the operand is one uint32_t, but it may be pair. Handle the pairs especially. + if kind == 'PairLiteralIntegerIdRef': + if is_array: + line = operand_name + '->emplace_back(' + kind + '{LiteralInteger(_instruction[_o]), IdRef(_instruction[_o + 1])});' + line += '_o += 2;' + else: + line = operand_name + '->literal = LiteralInteger(_instruction[_o++]);' + line += operand_name + '->id = IdRef(_instruction[_o++]);' + elif kind == 'PairIdRefLiteralInteger': + if is_array: + line = operand_name + '->emplace_back(' + kind + '{IdRef(_instruction[_o]), LiteralInteger(_instruction[_o + 1])});' + line += '_o += 2;' + else: + line = operand_name + '->id = IdRef(_instruction[_o++]);' + line += operand_name + '->literal = LiteralInteger(_instruction[_o++]);' + elif kind == 'PairIdRefIdRef': + if is_array: + line = operand_name + '->emplace_back(' + kind + '{IdRef(_instruction[_o]), IdRef(_instruction[_o + 1])});' + line += '_o += 2;' + else: + line = operand_name + '->id1 = IdRef(_instruction[_o++]);' + line += operand_name + '->id2 = IdRef(_instruction[_o++]);' + elif kind == 'LiteralString': + # The length of string in words is ceil((strlen(str) + 1) / 4). This is equal to + # (strlen(str)+1+3) / 4, which is equal to strlen(str)/4+1. + assert (not is_array) + # See handling of LiteralString in get_operand_push_back_line. + line = 'ASSERT(IsLittleEndian());' + line += '*' + operand_name + ' = reinterpret_cast(&_instruction[_o]);' + line += '_o += strlen(*' + operand_name + ') / 4 + 1;' + else: + if is_array: + line = operand_name + '->emplace_back(_instruction[_o++]);' + else: + line = '*' + operand_name + ' = ' + self.get_kind_cpp_type( + kind) + '(_instruction[_o++]);' + + return pre + line + post + + def process_operand(self, operand, cpp_operands_in, cpp_operands_out, cpp_in_parse_lines, + cpp_out_push_back_lines): + operand_name = self.get_operand_name(operand) + type_in, type_out, is_array, is_optional = self.get_operand_type_in_and_out(operand) + + # Make the parameter list + cpp_operands_in.append(', ' + type_in + ' ' + operand_name) + cpp_operands_out.append(', ' + type_out + ' ' + operand_name) + + # Make the builder body lines + cpp_out_push_back_lines.append( + self.get_operand_push_back_line(operand, operand_name, is_array, is_optional)) + + # Make the parser body lines + cpp_in_parse_lines.append( + self.get_operand_parse_line(operand, operand_name, is_array, is_optional)) + + def generate_instruction_functions(self, instruction): + name = instruction['opname'] + assert (name.startswith('Op')) + name = name[2:] + + # Skip if the instruction depends on a capability or extension we aren't interested in + if self.requires_unsupported_capability(instruction): + return + if self.requires_unsupported_extension(instruction): + return + + operands = instruction.get('operands', []) + + # Skip if any of the operands are not supported + if any([operand['kind'] in self.unsupported_kinds for operand in operands]): + return + + cpp_operands_in = [] + cpp_operands_out = [] + cpp_in_parse_lines = [] + cpp_out_push_back_lines = [] + + for operand in operands: + self.process_operand(operand, cpp_operands_in, cpp_operands_out, cpp_in_parse_lines, + cpp_out_push_back_lines) + + # get_operand_parse_line relies on there only being one array parameter, and it being + # the last. + assert (operand.get('quantifier') != '*' or len(cpp_in_parse_lines) == len(operands)) + + if operand['kind'] == 'Decoration': + # Special handling of Op*Decorate instructions with a Decoration operand. That + # operand always comes last, and implies a number of LiteralIntegers to follow. + assert (len(cpp_in_parse_lines) == len(operands)) + + decoration_operands = { + 'name': 'values', + 'kind': 'LiteralInteger', + 'quantifier': '*' + } + self.process_operand(decoration_operands, cpp_operands_in, cpp_operands_out, + cpp_in_parse_lines, cpp_out_push_back_lines) + + elif operand['kind'] == 'ImageOperands': + # Special handling of OpImage* instructions with an ImageOperands operand. That + # operand always comes last, and implies a number of IdRefs to follow with different + # meanings based on the bits set in said operand. + assert (len(cpp_in_parse_lines) == len(operands)) + + image_operands = {'name': 'imageOperandIds', 'kind': 'IdRef', 'quantifier': '*'} + self.process_operand(image_operands, cpp_operands_in, cpp_operands_out, + cpp_in_parse_lines, cpp_out_push_back_lines) + + # Make the builder prototype body + builder_prototype = TEMPLATE_BUILDER_FUNCTION_PROTOTYPE.format( + op=name, param_list=''.join(cpp_operands_in)) + self.instruction_builder_prototypes.append(builder_prototype + ';\n') + self.instruction_builder_impl.append( + builder_prototype + '\n' + TEMPLATE_BUILDER_FUNCTION_BODY.format( + op=name, push_back_lines='\n'.join(cpp_out_push_back_lines))) + + if len(operands) == 0: + return + + parser_prototype = TEMPLATE_PARSER_FUNCTION_PROTOTYPE.format( + op=name, param_list=''.join(cpp_operands_out)) + self.instruction_parser_prototypes.append(parser_prototype + ';\n') + self.instruction_parser_impl.append( + parser_prototype + '\n' + TEMPLATE_PARSER_FUNCTION_BODY.format( + op=name, parse_lines='\n'.join(cpp_in_parse_lines))) + + +def main(): + + # auto_script parameters. + if len(sys.argv) > 1: + if sys.argv[1] == 'inputs': + print(SPIRV_GRAMMAR_FILE) + elif sys.argv[1] == 'outputs': + output_files_base = [SPIRV_BUILDER_FILE, SPIRV_PARSER_FILE] + output_files = [ + '_autogen.'.join(pair) + for pair in itertools.product(output_files_base, ['h', 'cpp']) + ] + print(','.join(output_files)) + else: + print('Invalid script parameters') + return 1 + return 0 + + writer = Writer() + writer.write_builder_and_parser() + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/common/spirv/spirv_instruction_builder_autogen.cpp b/src/common/spirv/spirv_instruction_builder_autogen.cpp new file mode 100644 index 000000000..f26f36c38 --- /dev/null +++ b/src/common/spirv/spirv_instruction_builder_autogen.cpp @@ -0,0 +1,3507 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_spirv_builder_and_parser.py using data from spirv.core.grammar.json. +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// spirv_instruction_builder_autogen.cpp: +// Functions to generate SPIR-V binary for each instruction. + +#include "spirv_instruction_builder_autogen.h" + +#include + +#include "common/debug.h" + +namespace angle +{ +namespace spirv +{ +namespace +{ +uint32_t MakeLengthOp(size_t length, spv::Op op) +{ + ASSERT(length <= 0xFFFFu); + ASSERT(op <= 0xFFFFu); + + return static_cast(length) << 16 | op; +} +} // anonymous namespace + +void WriteNop(std::vector *blob) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpNop); +} +void WriteUndef(std::vector *blob, IdResultType idResultType, IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpUndef); +} +void WriteSourceContinued(std::vector *blob, LiteralString continuedSource) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + { + size_t d = blob->size(); + blob->resize(d + strlen(continuedSource) / 4 + 1, 0); + ASSERT(IsLittleEndian()); + strcpy(reinterpret_cast(blob->data() + d), continuedSource); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSourceContinued); +} +void WriteSource(std::vector *blob, + spv::SourceLanguage sourceLanguage, + LiteralInteger version, + IdRef *file, + LiteralString *source) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(sourceLanguage); + blob->push_back(version); + if (file) + { + blob->push_back(*file); + } + if (source) + { + { + size_t d = blob->size(); + blob->resize(d + strlen(*source) / 4 + 1, 0); + ASSERT(IsLittleEndian()); + strcpy(reinterpret_cast(blob->data() + d), *source); + } + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSource); +} +void WriteSourceExtension(std::vector *blob, LiteralString extension) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + { + size_t d = blob->size(); + blob->resize(d + strlen(extension) / 4 + 1, 0); + ASSERT(IsLittleEndian()); + strcpy(reinterpret_cast(blob->data() + d), extension); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSourceExtension); +} +void WriteName(std::vector *blob, IdRef target, LiteralString name) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(target); + { + size_t d = blob->size(); + blob->resize(d + strlen(name) / 4 + 1, 0); + ASSERT(IsLittleEndian()); + strcpy(reinterpret_cast(blob->data() + d), name); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpName); +} +void WriteMemberName(std::vector *blob, + IdRef type, + LiteralInteger member, + LiteralString name) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(type); + blob->push_back(member); + { + size_t d = blob->size(); + blob->resize(d + strlen(name) / 4 + 1, 0); + ASSERT(IsLittleEndian()); + strcpy(reinterpret_cast(blob->data() + d), name); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpMemberName); +} +void WriteString(std::vector *blob, IdResult idResult, LiteralString string) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + { + size_t d = blob->size(); + blob->resize(d + strlen(string) / 4 + 1, 0); + ASSERT(IsLittleEndian()); + strcpy(reinterpret_cast(blob->data() + d), string); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpString); +} +void WriteLine(std::vector *blob, IdRef file, LiteralInteger line, LiteralInteger column) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(file); + blob->push_back(line); + blob->push_back(column); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpLine); +} +void WriteExtension(std::vector *blob, LiteralString name) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + { + size_t d = blob->size(); + blob->resize(d + strlen(name) / 4 + 1, 0); + ASSERT(IsLittleEndian()); + strcpy(reinterpret_cast(blob->data() + d), name); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpExtension); +} +void WriteExtInstImport(std::vector *blob, IdResult idResult, LiteralString name) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + { + size_t d = blob->size(); + blob->resize(d + strlen(name) / 4 + 1, 0); + ASSERT(IsLittleEndian()); + strcpy(reinterpret_cast(blob->data() + d), name); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpExtInstImport); +} +void WriteExtInst(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef set, + LiteralExtInstInteger instruction, + const IdRefList &operandList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(set); + blob->push_back(instruction); + for (const auto &operand : operandList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpExtInst); +} +void WriteMemoryModel(std::vector *blob, + spv::AddressingModel addressingModel, + spv::MemoryModel memoryModel) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(addressingModel); + blob->push_back(memoryModel); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpMemoryModel); +} +void WriteEntryPoint(std::vector *blob, + spv::ExecutionModel executionModel, + IdRef entryPoint, + LiteralString name, + const IdRefList &interfaceList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(executionModel); + blob->push_back(entryPoint); + { + size_t d = blob->size(); + blob->resize(d + strlen(name) / 4 + 1, 0); + ASSERT(IsLittleEndian()); + strcpy(reinterpret_cast(blob->data() + d), name); + } + for (const auto &operand : interfaceList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpEntryPoint); +} +void WriteExecutionMode(std::vector *blob, IdRef entryPoint, spv::ExecutionMode mode) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(entryPoint); + blob->push_back(mode); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpExecutionMode); +} +void WriteCapability(std::vector *blob, spv::Capability capability) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(capability); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpCapability); +} +void WriteTypeVoid(std::vector *blob, IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeVoid); +} +void WriteTypeBool(std::vector *blob, IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeBool); +} +void WriteTypeInt(std::vector *blob, + IdResult idResult, + LiteralInteger width, + LiteralInteger signedness) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(width); + blob->push_back(signedness); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeInt); +} +void WriteTypeFloat(std::vector *blob, IdResult idResult, LiteralInteger width) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(width); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeFloat); +} +void WriteTypeVector(std::vector *blob, + IdResult idResult, + IdRef componentType, + LiteralInteger componentCount) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(componentType); + blob->push_back(componentCount); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeVector); +} +void WriteTypeMatrix(std::vector *blob, + IdResult idResult, + IdRef columnType, + LiteralInteger columnCount) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(columnType); + blob->push_back(columnCount); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeMatrix); +} +void WriteTypeImage(std::vector *blob, + IdResult idResult, + IdRef sampledType, + spv::Dim dim, + LiteralInteger depth, + LiteralInteger arrayed, + LiteralInteger mS, + LiteralInteger sampled, + spv::ImageFormat imageFormat, + spv::AccessQualifier *accessQualifier) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(sampledType); + blob->push_back(dim); + blob->push_back(depth); + blob->push_back(arrayed); + blob->push_back(mS); + blob->push_back(sampled); + blob->push_back(imageFormat); + if (accessQualifier) + { + blob->push_back(*accessQualifier); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeImage); +} +void WriteTypeSampler(std::vector *blob, IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeSampler); +} +void WriteTypeSampledImage(std::vector *blob, IdResult idResult, IdRef imageType) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(imageType); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeSampledImage); +} +void WriteTypeArray(std::vector *blob, IdResult idResult, IdRef elementType, IdRef length) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(elementType); + blob->push_back(length); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeArray); +} +void WriteTypeRuntimeArray(std::vector *blob, IdResult idResult, IdRef elementType) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(elementType); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeRuntimeArray); +} +void WriteTypeStruct(std::vector *blob, IdResult idResult, const IdRefList &memberList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + for (const auto &operand : memberList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeStruct); +} +void WriteTypePointer(std::vector *blob, + IdResult idResult, + spv::StorageClass storageClass, + IdRef type) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(storageClass); + blob->push_back(type); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypePointer); +} +void WriteTypeFunction(std::vector *blob, + IdResult idResult, + IdRef returnType, + const IdRefList ¶meterList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + blob->push_back(returnType); + for (const auto &operand : parameterList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeFunction); +} +void WriteTypeForwardPointer(std::vector *blob, + IdRef pointerType, + spv::StorageClass storageClass) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(pointerType); + blob->push_back(storageClass); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeForwardPointer); +} +void WriteConstantTrue(std::vector *blob, IdResultType idResultType, IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConstantTrue); +} +void WriteConstantFalse(std::vector *blob, IdResultType idResultType, IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConstantFalse); +} +void WriteConstant(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + LiteralContextDependentNumber value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConstant); +} +void WriteConstantComposite(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + const IdRefList &constituentsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + for (const auto &operand : constituentsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConstantComposite); +} +void WriteConstantNull(std::vector *blob, IdResultType idResultType, IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConstantNull); +} +void WriteSpecConstantTrue(std::vector *blob, + IdResultType idResultType, + IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSpecConstantTrue); +} +void WriteSpecConstantFalse(std::vector *blob, + IdResultType idResultType, + IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSpecConstantFalse); +} +void WriteSpecConstant(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + LiteralContextDependentNumber value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSpecConstant); +} +void WriteSpecConstantComposite(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + const IdRefList &constituentsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + for (const auto &operand : constituentsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSpecConstantComposite); +} +void WriteFunction(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + spv::FunctionControlMask functionControl, + IdRef functionType) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(functionControl); + blob->push_back(functionType); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFunction); +} +void WriteFunctionParameter(std::vector *blob, + IdResultType idResultType, + IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFunctionParameter); +} +void WriteFunctionEnd(std::vector *blob) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFunctionEnd); +} +void WriteFunctionCall(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef function, + const IdRefList &argumentList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(function); + for (const auto &operand : argumentList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFunctionCall); +} +void WriteVariable(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + spv::StorageClass storageClass, + IdRef *initializer) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(storageClass); + if (initializer) + { + blob->push_back(*initializer); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpVariable); +} +void WriteImageTexelPointer(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + IdRef sample) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(image); + blob->push_back(coordinate); + blob->push_back(sample); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageTexelPointer); +} +void WriteLoad(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + spv::MemoryAccessMask *memoryAccess) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + if (memoryAccess) + { + blob->push_back(*memoryAccess); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpLoad); +} +void WriteStore(std::vector *blob, + IdRef pointer, + IdRef object, + spv::MemoryAccessMask *memoryAccess) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(pointer); + blob->push_back(object); + if (memoryAccess) + { + blob->push_back(*memoryAccess); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpStore); +} +void WriteCopyMemory(std::vector *blob, + IdRef target, + IdRef source, + spv::MemoryAccessMask *memoryAccess) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(target); + blob->push_back(source); + if (memoryAccess) + { + blob->push_back(*memoryAccess); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpCopyMemory); +} +void WriteCopyMemorySized(std::vector *blob, + IdRef target, + IdRef source, + IdRef size, + spv::MemoryAccessMask *memoryAccess) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(target); + blob->push_back(source); + blob->push_back(size); + if (memoryAccess) + { + blob->push_back(*memoryAccess); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpCopyMemorySized); +} +void WriteAccessChain(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + const IdRefList &indexesList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + for (const auto &operand : indexesList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAccessChain); +} +void WriteInBoundsAccessChain(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + const IdRefList &indexesList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + for (const auto &operand : indexesList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpInBoundsAccessChain); +} +void WriteArrayLength(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef structure, + LiteralInteger arraymember) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(structure); + blob->push_back(arraymember); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpArrayLength); +} +void WriteInBoundsPtrAccessChain(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef element, + const IdRefList &indexesList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + blob->push_back(element); + for (const auto &operand : indexesList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpInBoundsPtrAccessChain); +} +void WriteDecorate(std::vector *blob, + IdRef target, + spv::Decoration decoration, + const LiteralIntegerList &valuesPairList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(target); + blob->push_back(decoration); + for (const auto &operand : valuesPairList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpDecorate); +} +void WriteMemberDecorate(std::vector *blob, + IdRef structureType, + LiteralInteger member, + spv::Decoration decoration, + const LiteralIntegerList &valuesPairList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(structureType); + blob->push_back(member); + blob->push_back(decoration); + for (const auto &operand : valuesPairList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpMemberDecorate); +} +void WriteDecorationGroup(std::vector *blob, IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpDecorationGroup); +} +void WriteGroupDecorate(std::vector *blob, + IdRef decorationGroup, + const IdRefList &targetsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(decorationGroup); + for (const auto &operand : targetsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupDecorate); +} +void WriteGroupMemberDecorate(std::vector *blob, + IdRef decorationGroup, + const PairIdRefLiteralIntegerList &targetsPairList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(decorationGroup); + for (const auto &operand : targetsPairList) + { + blob->push_back(operand.id); + blob->push_back(operand.literal); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupMemberDecorate); +} +void WriteVectorExtractDynamic(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector, + IdRef index) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(vector); + blob->push_back(index); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpVectorExtractDynamic); +} +void WriteVectorInsertDynamic(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector, + IdRef component, + IdRef index) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(vector); + blob->push_back(component); + blob->push_back(index); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpVectorInsertDynamic); +} +void WriteVectorShuffle(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector1, + IdRef vector2, + const LiteralIntegerList &componentsPairList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(vector1); + blob->push_back(vector2); + for (const auto &operand : componentsPairList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpVectorShuffle); +} +void WriteCompositeConstruct(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + const IdRefList &constituentsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + for (const auto &operand : constituentsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpCompositeConstruct); +} +void WriteCompositeExtract(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef composite, + const LiteralIntegerList &indexesPairList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(composite); + for (const auto &operand : indexesPairList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpCompositeExtract); +} +void WriteCompositeInsert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef object, + IdRef composite, + const LiteralIntegerList &indexesPairList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(object); + blob->push_back(composite); + for (const auto &operand : indexesPairList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpCompositeInsert); +} +void WriteCopyObject(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpCopyObject); +} +void WriteTranspose(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef matrix) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(matrix); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTranspose); +} +void WriteSampledImage(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef sampler) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(image); + blob->push_back(sampler); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSampledImage); +} +void WriteImageSampleImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSampleImplicitLod); +} +void WriteImageSampleExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(imageOperands); + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSampleExplicitLod); +} +void WriteImageSampleDrefImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSampleDrefImplicitLod); +} +void WriteImageSampleDrefExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + blob->push_back(imageOperands); + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSampleDrefExplicitLod); +} +void WriteImageSampleProjImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSampleProjImplicitLod); +} +void WriteImageSampleProjExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(imageOperands); + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSampleProjExplicitLod); +} +void WriteImageSampleProjDrefImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSampleProjDrefImplicitLod); +} +void WriteImageSampleProjDrefExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + blob->push_back(imageOperands); + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSampleProjDrefExplicitLod); +} +void WriteImageFetch(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(image); + blob->push_back(coordinate); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageFetch); +} +void WriteImageGather(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef component, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(component); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageGather); +} +void WriteImageDrefGather(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageDrefGather); +} +void WriteImageRead(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(image); + blob->push_back(coordinate); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageRead); +} +void WriteImageWrite(std::vector *blob, + IdRef image, + IdRef coordinate, + IdRef texel, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(image); + blob->push_back(coordinate); + blob->push_back(texel); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageWrite); +} +void WriteImage(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImage); +} +void WriteImageQueryLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageQueryLod); +} +void WriteConvertFToU(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef floatValue) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(floatValue); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConvertFToU); +} +void WriteConvertFToS(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef floatValue) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(floatValue); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConvertFToS); +} +void WriteConvertSToF(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef signedValue) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(signedValue); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConvertSToF); +} +void WriteConvertUToF(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef unsignedValue) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(unsignedValue); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConvertUToF); +} +void WriteUConvert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef unsignedValue) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(unsignedValue); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpUConvert); +} +void WriteSConvert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef signedValue) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(signedValue); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSConvert); +} +void WriteFConvert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef floatValue) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(floatValue); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFConvert); +} +void WriteQuantizeToF16(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpQuantizeToF16); +} +void WriteConvertPtrToU(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConvertPtrToU); +} +void WriteConvertUToPtr(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef integerValue) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(integerValue); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConvertUToPtr); +} +void WriteBitcast(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBitcast); +} +void WriteSNegate(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSNegate); +} +void WriteFNegate(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFNegate); +} +void WriteIAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpIAdd); +} +void WriteFAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFAdd); +} +void WriteISub(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpISub); +} +void WriteFSub(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFSub); +} +void WriteIMul(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpIMul); +} +void WriteFMul(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFMul); +} +void WriteUDiv(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpUDiv); +} +void WriteSDiv(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSDiv); +} +void WriteFDiv(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFDiv); +} +void WriteUMod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpUMod); +} +void WriteSRem(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSRem); +} +void WriteSMod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSMod); +} +void WriteFRem(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFRem); +} +void WriteFMod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFMod); +} +void WriteVectorTimesScalar(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector, + IdRef scalar) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(vector); + blob->push_back(scalar); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpVectorTimesScalar); +} +void WriteMatrixTimesScalar(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef matrix, + IdRef scalar) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(matrix); + blob->push_back(scalar); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpMatrixTimesScalar); +} +void WriteVectorTimesMatrix(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector, + IdRef matrix) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(vector); + blob->push_back(matrix); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpVectorTimesMatrix); +} +void WriteMatrixTimesVector(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef matrix, + IdRef vector) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(matrix); + blob->push_back(vector); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpMatrixTimesVector); +} +void WriteMatrixTimesMatrix(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef leftMatrix, + IdRef rightMatrix) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(leftMatrix); + blob->push_back(rightMatrix); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpMatrixTimesMatrix); +} +void WriteOuterProduct(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector1, + IdRef vector2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(vector1); + blob->push_back(vector2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpOuterProduct); +} +void WriteDot(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector1, + IdRef vector2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(vector1); + blob->push_back(vector2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpDot); +} +void WriteIAddCarry(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpIAddCarry); +} +void WriteISubBorrow(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpISubBorrow); +} +void WriteUMulExtended(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpUMulExtended); +} +void WriteSMulExtended(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSMulExtended); +} +void WriteAny(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(vector); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAny); +} +void WriteAll(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(vector); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAll); +} +void WriteIsNan(std::vector *blob, IdResultType idResultType, IdResult idResult, IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpIsNan); +} +void WriteIsInf(std::vector *blob, IdResultType idResultType, IdResult idResult, IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpIsInf); +} +void WriteLogicalEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpLogicalEqual); +} +void WriteLogicalNotEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpLogicalNotEqual); +} +void WriteLogicalOr(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpLogicalOr); +} +void WriteLogicalAnd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpLogicalAnd); +} +void WriteLogicalNot(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpLogicalNot); +} +void WriteSelect(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef condition, + IdRef object1, + IdRef object2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(condition); + blob->push_back(object1); + blob->push_back(object2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSelect); +} +void WriteIEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpIEqual); +} +void WriteINotEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpINotEqual); +} +void WriteUGreaterThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpUGreaterThan); +} +void WriteSGreaterThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSGreaterThan); +} +void WriteUGreaterThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpUGreaterThanEqual); +} +void WriteSGreaterThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSGreaterThanEqual); +} +void WriteULessThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpULessThan); +} +void WriteSLessThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSLessThan); +} +void WriteULessThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpULessThanEqual); +} +void WriteSLessThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSLessThanEqual); +} +void WriteFOrdEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFOrdEqual); +} +void WriteFUnordEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFUnordEqual); +} +void WriteFOrdNotEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFOrdNotEqual); +} +void WriteFUnordNotEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFUnordNotEqual); +} +void WriteFOrdLessThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFOrdLessThan); +} +void WriteFUnordLessThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFUnordLessThan); +} +void WriteFOrdGreaterThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFOrdGreaterThan); +} +void WriteFUnordGreaterThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFUnordGreaterThan); +} +void WriteFOrdLessThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFOrdLessThanEqual); +} +void WriteFUnordLessThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFUnordLessThanEqual); +} +void WriteFOrdGreaterThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFOrdGreaterThanEqual); +} +void WriteFUnordGreaterThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFUnordGreaterThanEqual); +} +void WriteShiftRightLogical(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef shift) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + blob->push_back(shift); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpShiftRightLogical); +} +void WriteShiftRightArithmetic(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef shift) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + blob->push_back(shift); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpShiftRightArithmetic); +} +void WriteShiftLeftLogical(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef shift) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + blob->push_back(shift); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpShiftLeftLogical); +} +void WriteBitwiseOr(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBitwiseOr); +} +void WriteBitwiseXor(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBitwiseXor); +} +void WriteBitwiseAnd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand1); + blob->push_back(operand2); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBitwiseAnd); +} +void WriteNot(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(operand); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpNot); +} +void WriteBitFieldInsert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef insert, + IdRef offset, + IdRef count) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + blob->push_back(insert); + blob->push_back(offset); + blob->push_back(count); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBitFieldInsert); +} +void WriteBitFieldSExtract(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef offset, + IdRef count) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + blob->push_back(offset); + blob->push_back(count); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBitFieldSExtract); +} +void WriteBitFieldUExtract(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef offset, + IdRef count) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + blob->push_back(offset); + blob->push_back(count); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBitFieldUExtract); +} +void WriteBitReverse(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBitReverse); +} +void WriteBitCount(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(base); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBitCount); +} +void WriteDPdx(std::vector *blob, IdResultType idResultType, IdResult idResult, IdRef p) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(p); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpDPdx); +} +void WriteDPdy(std::vector *blob, IdResultType idResultType, IdResult idResult, IdRef p) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(p); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpDPdy); +} +void WriteFwidth(std::vector *blob, IdResultType idResultType, IdResult idResult, IdRef p) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(p); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFwidth); +} +void WriteDPdxFine(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(p); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpDPdxFine); +} +void WriteDPdyFine(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(p); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpDPdyFine); +} +void WriteFwidthFine(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(p); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFwidthFine); +} +void WriteDPdxCoarse(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(p); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpDPdxCoarse); +} +void WriteDPdyCoarse(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(p); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpDPdyCoarse); +} +void WriteFwidthCoarse(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(p); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpFwidthCoarse); +} +void WriteEmitVertex(std::vector *blob) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpEmitVertex); +} +void WriteEndPrimitive(std::vector *blob) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpEndPrimitive); +} +void WriteEmitStreamVertex(std::vector *blob, IdRef stream) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(stream); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpEmitStreamVertex); +} +void WriteEndStreamPrimitive(std::vector *blob, IdRef stream) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(stream); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpEndStreamPrimitive); +} +void WriteControlBarrier(std::vector *blob, + IdScope execution, + IdScope memory, + IdMemorySemantics semantics) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(execution); + blob->push_back(memory); + blob->push_back(semantics); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpControlBarrier); +} +void WriteMemoryBarrier(std::vector *blob, IdScope memory, IdMemorySemantics semantics) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(memory); + blob->push_back(semantics); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpMemoryBarrier); +} +void WriteAtomicLoad(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicLoad); +} +void WriteAtomicStore(std::vector *blob, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicStore); +} +void WriteAtomicExchange(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicExchange); +} +void WriteAtomicCompareExchange(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics equal, + IdMemorySemantics unequal, + IdRef value, + IdRef comparator) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(equal); + blob->push_back(unequal); + blob->push_back(value); + blob->push_back(comparator); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicCompareExchange); +} +void WriteAtomicIIncrement(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicIIncrement); +} +void WriteAtomicIDecrement(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicIDecrement); +} +void WriteAtomicIAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicIAdd); +} +void WriteAtomicISub(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicISub); +} +void WriteAtomicSMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicSMin); +} +void WriteAtomicUMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicUMin); +} +void WriteAtomicSMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicSMax); +} +void WriteAtomicUMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicUMax); +} +void WriteAtomicAnd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicAnd); +} +void WriteAtomicOr(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicOr); +} +void WriteAtomicXor(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(pointer); + blob->push_back(scope); + blob->push_back(semantics); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpAtomicXor); +} +void WritePhi(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + const PairIdRefIdRefList &variableParentPairList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + for (const auto &operand : variableParentPairList) + { + blob->push_back(operand.id1); + blob->push_back(operand.id2); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpPhi); +} +void WriteLoopMerge(std::vector *blob, + IdRef mergeBlock, + IdRef continueTarget, + spv::LoopControlMask loopControl) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(mergeBlock); + blob->push_back(continueTarget); + blob->push_back(loopControl); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpLoopMerge); +} +void WriteSelectionMerge(std::vector *blob, + IdRef mergeBlock, + spv::SelectionControlMask selectionControl) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(mergeBlock); + blob->push_back(selectionControl); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSelectionMerge); +} +void WriteLabel(std::vector *blob, IdResult idResult) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResult); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpLabel); +} +void WriteBranch(std::vector *blob, IdRef targetLabel) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(targetLabel); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBranch); +} +void WriteBranchConditional(std::vector *blob, + IdRef condition, + IdRef trueLabel, + IdRef falseLabel, + const LiteralIntegerList &branchweightsPairList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(condition); + blob->push_back(trueLabel); + blob->push_back(falseLabel); + for (const auto &operand : branchweightsPairList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpBranchConditional); +} +void WriteSwitch(std::vector *blob, + IdRef selector, + IdRef default_, + const PairLiteralIntegerIdRefList &targetPairList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(selector); + blob->push_back(default_); + for (const auto &operand : targetPairList) + { + blob->push_back(operand.literal); + blob->push_back(operand.id); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpSwitch); +} +void WriteKill(std::vector *blob) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpKill); +} +void WriteReturn(std::vector *blob) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpReturn); +} +void WriteReturnValue(std::vector *blob, IdRef value) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(value); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpReturnValue); +} +void WriteUnreachable(std::vector *blob) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpUnreachable); +} +void WriteGroupAll(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + IdRef predicate) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(predicate); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupAll); +} +void WriteGroupAny(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + IdRef predicate) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(predicate); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupAny); +} +void WriteGroupBroadcast(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + IdRef value, + IdRef localId) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(value); + blob->push_back(localId); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupBroadcast); +} +void WriteGroupIAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupIAdd); +} +void WriteGroupFAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupFAdd); +} +void WriteGroupFMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupFMin); +} +void WriteGroupUMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupUMin); +} +void WriteGroupSMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupSMin); +} +void WriteGroupFMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupFMax); +} +void WriteGroupUMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupUMax); +} +void WriteGroupSMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupSMax); +} +void WriteImageSparseSampleImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSparseSampleImplicitLod); +} +void WriteImageSparseSampleExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(imageOperands); + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSparseSampleExplicitLod); +} +void WriteImageSparseSampleDrefImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSparseSampleDrefImplicitLod); +} +void WriteImageSparseSampleDrefExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + blob->push_back(imageOperands); + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSparseSampleDrefExplicitLod); +} +void WriteImageSparseSampleProjImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSparseSampleProjImplicitLod); +} +void WriteImageSparseSampleProjExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(imageOperands); + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSparseSampleProjExplicitLod); +} +void WriteImageSparseSampleProjDrefImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSparseSampleProjDrefImplicitLod); +} +void WriteImageSparseSampleProjDrefExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + blob->push_back(imageOperands); + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = + MakeLengthOp(blob->size() - startSize, spv::OpImageSparseSampleProjDrefExplicitLod); +} +void WriteImageSparseFetch(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(image); + blob->push_back(coordinate); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSparseFetch); +} +void WriteImageSparseGather(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef component, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(component); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSparseGather); +} +void WriteImageSparseDrefGather(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(sampledImage); + blob->push_back(coordinate); + blob->push_back(dref); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSparseDrefGather); +} +void WriteImageSparseTexelsResident(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef residentCode) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(residentCode); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSparseTexelsResident); +} +void WriteNoLine(std::vector *blob) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpNoLine); +} +void WriteImageSparseRead(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(image); + blob->push_back(coordinate); + if (imageOperands) + { + blob->push_back(*imageOperands); + } + for (const auto &operand : imageOperandIdsList) + { + blob->push_back(operand); + } + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageSparseRead); +} +void WriteGroupIAddNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupIAddNonUniformAMD); +} +void WriteGroupFAddNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupFAddNonUniformAMD); +} +void WriteGroupFMinNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupFMinNonUniformAMD); +} +void WriteGroupUMinNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupUMinNonUniformAMD); +} +void WriteGroupSMinNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupSMinNonUniformAMD); +} +void WriteGroupFMaxNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupFMaxNonUniformAMD); +} +void WriteGroupUMaxNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupUMaxNonUniformAMD); +} +void WriteGroupSMaxNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x) +{ + const size_t startSize = blob->size(); + blob->push_back(0); + blob->push_back(idResultType); + blob->push_back(idResult); + blob->push_back(execution); + blob->push_back(operation); + blob->push_back(x); + (*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpGroupSMaxNonUniformAMD); +} + +} // namespace spirv +} // namespace angle diff --git a/src/common/spirv/spirv_instruction_builder_autogen.h b/src/common/spirv/spirv_instruction_builder_autogen.h new file mode 100644 index 000000000..a3cf8d1df --- /dev/null +++ b/src/common/spirv/spirv_instruction_builder_autogen.h @@ -0,0 +1,1121 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_spirv_builder_and_parser.py using data from spirv.core.grammar.json. +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// spirv_instruction_builder_autogen.h: +// Functions to generate SPIR-V binary for each instruction. + +#ifndef COMMON_SPIRV_SPIRVINSTRUCTIONBUILDERAUTOGEN_H_ +#define COMMON_SPIRV_SPIRVINSTRUCTIONBUILDERAUTOGEN_H_ + +#include + +#include "spirv_types.h" + +namespace angle +{ +namespace spirv +{ +void WriteNop(std::vector *blob); +void WriteUndef(std::vector *blob, IdResultType idResultType, IdResult idResult); +void WriteSourceContinued(std::vector *blob, LiteralString continuedSource); +void WriteSource(std::vector *blob, + spv::SourceLanguage sourceLanguage, + LiteralInteger version, + IdRef *file, + LiteralString *source); +void WriteSourceExtension(std::vector *blob, LiteralString extension); +void WriteName(std::vector *blob, IdRef target, LiteralString name); +void WriteMemberName(std::vector *blob, + IdRef type, + LiteralInteger member, + LiteralString name); +void WriteString(std::vector *blob, IdResult idResult, LiteralString string); +void WriteLine(std::vector *blob, IdRef file, LiteralInteger line, LiteralInteger column); +void WriteExtension(std::vector *blob, LiteralString name); +void WriteExtInstImport(std::vector *blob, IdResult idResult, LiteralString name); +void WriteExtInst(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef set, + LiteralExtInstInteger instruction, + const IdRefList &operandList); +void WriteMemoryModel(std::vector *blob, + spv::AddressingModel addressingModel, + spv::MemoryModel memoryModel); +void WriteEntryPoint(std::vector *blob, + spv::ExecutionModel executionModel, + IdRef entryPoint, + LiteralString name, + const IdRefList &interfaceList); +void WriteExecutionMode(std::vector *blob, IdRef entryPoint, spv::ExecutionMode mode); +void WriteCapability(std::vector *blob, spv::Capability capability); +void WriteTypeVoid(std::vector *blob, IdResult idResult); +void WriteTypeBool(std::vector *blob, IdResult idResult); +void WriteTypeInt(std::vector *blob, + IdResult idResult, + LiteralInteger width, + LiteralInteger signedness); +void WriteTypeFloat(std::vector *blob, IdResult idResult, LiteralInteger width); +void WriteTypeVector(std::vector *blob, + IdResult idResult, + IdRef componentType, + LiteralInteger componentCount); +void WriteTypeMatrix(std::vector *blob, + IdResult idResult, + IdRef columnType, + LiteralInteger columnCount); +void WriteTypeImage(std::vector *blob, + IdResult idResult, + IdRef sampledType, + spv::Dim dim, + LiteralInteger depth, + LiteralInteger arrayed, + LiteralInteger mS, + LiteralInteger sampled, + spv::ImageFormat imageFormat, + spv::AccessQualifier *accessQualifier); +void WriteTypeSampler(std::vector *blob, IdResult idResult); +void WriteTypeSampledImage(std::vector *blob, IdResult idResult, IdRef imageType); +void WriteTypeArray(std::vector *blob, + IdResult idResult, + IdRef elementType, + IdRef length); +void WriteTypeRuntimeArray(std::vector *blob, IdResult idResult, IdRef elementType); +void WriteTypeStruct(std::vector *blob, IdResult idResult, const IdRefList &memberList); +void WriteTypePointer(std::vector *blob, + IdResult idResult, + spv::StorageClass storageClass, + IdRef type); +void WriteTypeFunction(std::vector *blob, + IdResult idResult, + IdRef returnType, + const IdRefList ¶meterList); +void WriteTypeForwardPointer(std::vector *blob, + IdRef pointerType, + spv::StorageClass storageClass); +void WriteConstantTrue(std::vector *blob, IdResultType idResultType, IdResult idResult); +void WriteConstantFalse(std::vector *blob, IdResultType idResultType, IdResult idResult); +void WriteConstant(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + LiteralContextDependentNumber value); +void WriteConstantComposite(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + const IdRefList &constituentsList); +void WriteConstantNull(std::vector *blob, IdResultType idResultType, IdResult idResult); +void WriteSpecConstantTrue(std::vector *blob, + IdResultType idResultType, + IdResult idResult); +void WriteSpecConstantFalse(std::vector *blob, + IdResultType idResultType, + IdResult idResult); +void WriteSpecConstant(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + LiteralContextDependentNumber value); +void WriteSpecConstantComposite(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + const IdRefList &constituentsList); +void WriteFunction(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + spv::FunctionControlMask functionControl, + IdRef functionType); +void WriteFunctionParameter(std::vector *blob, + IdResultType idResultType, + IdResult idResult); +void WriteFunctionEnd(std::vector *blob); +void WriteFunctionCall(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef function, + const IdRefList &argumentList); +void WriteVariable(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + spv::StorageClass storageClass, + IdRef *initializer); +void WriteImageTexelPointer(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + IdRef sample); +void WriteLoad(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + spv::MemoryAccessMask *memoryAccess); +void WriteStore(std::vector *blob, + IdRef pointer, + IdRef object, + spv::MemoryAccessMask *memoryAccess); +void WriteCopyMemory(std::vector *blob, + IdRef target, + IdRef source, + spv::MemoryAccessMask *memoryAccess); +void WriteCopyMemorySized(std::vector *blob, + IdRef target, + IdRef source, + IdRef size, + spv::MemoryAccessMask *memoryAccess); +void WriteAccessChain(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + const IdRefList &indexesList); +void WriteInBoundsAccessChain(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + const IdRefList &indexesList); +void WriteArrayLength(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef structure, + LiteralInteger arraymember); +void WriteInBoundsPtrAccessChain(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef element, + const IdRefList &indexesList); +void WriteDecorate(std::vector *blob, + IdRef target, + spv::Decoration decoration, + const LiteralIntegerList &valuesPairList); +void WriteMemberDecorate(std::vector *blob, + IdRef structureType, + LiteralInteger member, + spv::Decoration decoration, + const LiteralIntegerList &valuesPairList); +void WriteDecorationGroup(std::vector *blob, IdResult idResult); +void WriteGroupDecorate(std::vector *blob, + IdRef decorationGroup, + const IdRefList &targetsList); +void WriteGroupMemberDecorate(std::vector *blob, + IdRef decorationGroup, + const PairIdRefLiteralIntegerList &targetsPairList); +void WriteVectorExtractDynamic(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector, + IdRef index); +void WriteVectorInsertDynamic(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector, + IdRef component, + IdRef index); +void WriteVectorShuffle(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector1, + IdRef vector2, + const LiteralIntegerList &componentsPairList); +void WriteCompositeConstruct(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + const IdRefList &constituentsList); +void WriteCompositeExtract(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef composite, + const LiteralIntegerList &indexesPairList); +void WriteCompositeInsert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef object, + IdRef composite, + const LiteralIntegerList &indexesPairList); +void WriteCopyObject(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand); +void WriteTranspose(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef matrix); +void WriteSampledImage(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef sampler); +void WriteImageSampleImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSampleExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSampleDrefImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSampleDrefExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSampleProjImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSampleProjExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSampleProjDrefImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSampleProjDrefExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageFetch(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageGather(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef component, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageDrefGather(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageRead(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageWrite(std::vector *blob, + IdRef image, + IdRef coordinate, + IdRef texel, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImage(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage); +void WriteImageQueryLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate); +void WriteConvertFToU(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef floatValue); +void WriteConvertFToS(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef floatValue); +void WriteConvertSToF(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef signedValue); +void WriteConvertUToF(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef unsignedValue); +void WriteUConvert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef unsignedValue); +void WriteSConvert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef signedValue); +void WriteFConvert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef floatValue); +void WriteQuantizeToF16(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef value); +void WriteConvertPtrToU(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer); +void WriteConvertUToPtr(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef integerValue); +void WriteBitcast(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand); +void WriteSNegate(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand); +void WriteFNegate(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand); +void WriteIAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteISub(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFSub(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteIMul(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFMul(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteUDiv(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteSDiv(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFDiv(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteUMod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteSRem(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteSMod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFRem(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFMod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteVectorTimesScalar(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector, + IdRef scalar); +void WriteMatrixTimesScalar(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef matrix, + IdRef scalar); +void WriteVectorTimesMatrix(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector, + IdRef matrix); +void WriteMatrixTimesVector(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef matrix, + IdRef vector); +void WriteMatrixTimesMatrix(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef leftMatrix, + IdRef rightMatrix); +void WriteOuterProduct(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector1, + IdRef vector2); +void WriteDot(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector1, + IdRef vector2); +void WriteIAddCarry(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteISubBorrow(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteUMulExtended(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteSMulExtended(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteAny(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector); +void WriteAll(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef vector); +void WriteIsNan(std::vector *blob, IdResultType idResultType, IdResult idResult, IdRef x); +void WriteIsInf(std::vector *blob, IdResultType idResultType, IdResult idResult, IdRef x); +void WriteLogicalEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteLogicalNotEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteLogicalOr(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteLogicalAnd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteLogicalNot(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand); +void WriteSelect(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef condition, + IdRef object1, + IdRef object2); +void WriteIEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteINotEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteUGreaterThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteSGreaterThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteUGreaterThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteSGreaterThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteULessThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteSLessThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteULessThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteSLessThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFOrdEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFUnordEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFOrdNotEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFUnordNotEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFOrdLessThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFUnordLessThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFOrdGreaterThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFUnordGreaterThan(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFOrdLessThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFUnordLessThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFOrdGreaterThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteFUnordGreaterThanEqual(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteShiftRightLogical(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef shift); +void WriteShiftRightArithmetic(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef shift); +void WriteShiftLeftLogical(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef shift); +void WriteBitwiseOr(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteBitwiseXor(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteBitwiseAnd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand1, + IdRef operand2); +void WriteNot(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef operand); +void WriteBitFieldInsert(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef insert, + IdRef offset, + IdRef count); +void WriteBitFieldSExtract(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef offset, + IdRef count); +void WriteBitFieldUExtract(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base, + IdRef offset, + IdRef count); +void WriteBitReverse(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base); +void WriteBitCount(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef base); +void WriteDPdx(std::vector *blob, IdResultType idResultType, IdResult idResult, IdRef p); +void WriteDPdy(std::vector *blob, IdResultType idResultType, IdResult idResult, IdRef p); +void WriteFwidth(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p); +void WriteDPdxFine(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p); +void WriteDPdyFine(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p); +void WriteFwidthFine(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p); +void WriteDPdxCoarse(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p); +void WriteDPdyCoarse(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p); +void WriteFwidthCoarse(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef p); +void WriteEmitVertex(std::vector *blob); +void WriteEndPrimitive(std::vector *blob); +void WriteEmitStreamVertex(std::vector *blob, IdRef stream); +void WriteEndStreamPrimitive(std::vector *blob, IdRef stream); +void WriteControlBarrier(std::vector *blob, + IdScope execution, + IdScope memory, + IdMemorySemantics semantics); +void WriteMemoryBarrier(std::vector *blob, IdScope memory, IdMemorySemantics semantics); +void WriteAtomicLoad(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics); +void WriteAtomicStore(std::vector *blob, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicExchange(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicCompareExchange(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics equal, + IdMemorySemantics unequal, + IdRef value, + IdRef comparator); +void WriteAtomicIIncrement(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics); +void WriteAtomicIDecrement(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics); +void WriteAtomicIAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicISub(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicSMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicUMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicSMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicUMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicAnd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicOr(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WriteAtomicXor(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef pointer, + IdScope scope, + IdMemorySemantics semantics, + IdRef value); +void WritePhi(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + const PairIdRefIdRefList &variableParentPairList); +void WriteLoopMerge(std::vector *blob, + IdRef mergeBlock, + IdRef continueTarget, + spv::LoopControlMask loopControl); +void WriteSelectionMerge(std::vector *blob, + IdRef mergeBlock, + spv::SelectionControlMask selectionControl); +void WriteLabel(std::vector *blob, IdResult idResult); +void WriteBranch(std::vector *blob, IdRef targetLabel); +void WriteBranchConditional(std::vector *blob, + IdRef condition, + IdRef trueLabel, + IdRef falseLabel, + const LiteralIntegerList &branchweightsPairList); +void WriteSwitch(std::vector *blob, + IdRef selector, + IdRef default_, + const PairLiteralIntegerIdRefList &targetPairList); +void WriteKill(std::vector *blob); +void WriteReturn(std::vector *blob); +void WriteReturnValue(std::vector *blob, IdRef value); +void WriteUnreachable(std::vector *blob); +void WriteGroupAll(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + IdRef predicate); +void WriteGroupAny(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + IdRef predicate); +void WriteGroupBroadcast(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + IdRef value, + IdRef localId); +void WriteGroupIAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupFAdd(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupFMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupUMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupSMin(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupFMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupUMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupSMax(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteImageSparseSampleImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseSampleExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseSampleDrefImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseSampleDrefExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseSampleProjImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseSampleProjExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseSampleProjDrefImplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseSampleProjDrefExplicitLod(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseFetch(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseGather(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef component, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseDrefGather(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef sampledImage, + IdRef coordinate, + IdRef dref, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteImageSparseTexelsResident(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef residentCode); +void WriteNoLine(std::vector *blob); +void WriteImageSparseRead(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdRef image, + IdRef coordinate, + spv::ImageOperandsMask *imageOperands, + const IdRefList &imageOperandIdsList); +void WriteGroupIAddNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupFAddNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupFMinNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupUMinNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupSMinNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupFMaxNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupUMaxNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); +void WriteGroupSMaxNonUniformAMD(std::vector *blob, + IdResultType idResultType, + IdResult idResult, + IdScope execution, + spv::GroupOperation operation, + IdRef x); + +} // namespace spirv +} // namespace angle + +#endif // COMMON_SPIRV_SPIRVINSTRUCTIONBUILDERAUTOGEN_H_ diff --git a/src/common/spirv/spirv_instruction_parser_autogen.cpp b/src/common/spirv/spirv_instruction_parser_autogen.cpp new file mode 100644 index 000000000..43d5309cf --- /dev/null +++ b/src/common/spirv/spirv_instruction_parser_autogen.cpp @@ -0,0 +1,4036 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_spirv_builder_and_parser.py using data from spirv.core.grammar.json. +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// spirv_instruction_parser_autogen.cpp: +// Functions to parse SPIR-V binary for each instruction. + +#include "spirv_instruction_parser_autogen.h" + +#include + +#include "common/debug.h" + +namespace angle +{ +namespace spirv +{ + +void GetInstructionOpAndLength(const uint32_t *_instruction, spv::Op *opOut, uint32_t *lengthOut) +{ + constexpr uint32_t kOpMask = 0xFFFFu; + *opOut = static_cast(_instruction[0] & kOpMask); + *lengthOut = _instruction[0] >> 16; +} +void ParseUndef(const uint32_t *_instruction, IdResultType *idResultType, IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpUndef); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); +} +void ParseSourceContinued(const uint32_t *_instruction, LiteralString *continuedSource) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSourceContinued); + uint32_t _o = 1; + ASSERT(IsLittleEndian()); + *continuedSource = reinterpret_cast(&_instruction[_o]); + _o += strlen(*continuedSource) / 4 + 1; +} +void ParseSource(const uint32_t *_instruction, + spv::SourceLanguage *sourceLanguage, + LiteralInteger *version, + IdRef *file, + LiteralString *source) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSource); + uint32_t _o = 1; + *sourceLanguage = spv::SourceLanguage(_instruction[_o++]); + *version = LiteralInteger(_instruction[_o++]); + if (file && _o < _length) + { + *file = IdRef(_instruction[_o++]); + } + if (source && _o < _length) + { + ASSERT(IsLittleEndian()); + *source = reinterpret_cast(&_instruction[_o]); + _o += strlen(*source) / 4 + 1; + } +} +void ParseSourceExtension(const uint32_t *_instruction, LiteralString *extension) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSourceExtension); + uint32_t _o = 1; + ASSERT(IsLittleEndian()); + *extension = reinterpret_cast(&_instruction[_o]); + _o += strlen(*extension) / 4 + 1; +} +void ParseName(const uint32_t *_instruction, IdRef *target, LiteralString *name) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpName); + uint32_t _o = 1; + *target = IdRef(_instruction[_o++]); + ASSERT(IsLittleEndian()); + *name = reinterpret_cast(&_instruction[_o]); + _o += strlen(*name) / 4 + 1; +} +void ParseMemberName(const uint32_t *_instruction, + IdRef *type, + LiteralInteger *member, + LiteralString *name) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpMemberName); + uint32_t _o = 1; + *type = IdRef(_instruction[_o++]); + *member = LiteralInteger(_instruction[_o++]); + ASSERT(IsLittleEndian()); + *name = reinterpret_cast(&_instruction[_o]); + _o += strlen(*name) / 4 + 1; +} +void ParseString(const uint32_t *_instruction, IdResult *idResult, LiteralString *string) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpString); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + ASSERT(IsLittleEndian()); + *string = reinterpret_cast(&_instruction[_o]); + _o += strlen(*string) / 4 + 1; +} +void ParseLine(const uint32_t *_instruction, + IdRef *file, + LiteralInteger *line, + LiteralInteger *column) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpLine); + uint32_t _o = 1; + *file = IdRef(_instruction[_o++]); + *line = LiteralInteger(_instruction[_o++]); + *column = LiteralInteger(_instruction[_o++]); +} +void ParseExtension(const uint32_t *_instruction, LiteralString *name) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpExtension); + uint32_t _o = 1; + ASSERT(IsLittleEndian()); + *name = reinterpret_cast(&_instruction[_o]); + _o += strlen(*name) / 4 + 1; +} +void ParseExtInstImport(const uint32_t *_instruction, IdResult *idResult, LiteralString *name) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpExtInstImport); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + ASSERT(IsLittleEndian()); + *name = reinterpret_cast(&_instruction[_o]); + _o += strlen(*name) / 4 + 1; +} +void ParseExtInst(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *set, + LiteralExtInstInteger *instruction, + IdRefList *operandList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpExtInst); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *set = IdRef(_instruction[_o++]); + *instruction = LiteralExtInstInteger(_instruction[_o++]); + if (operandList) + { + while (_o < _length) + { + operandList->emplace_back(_instruction[_o++]); + } + } +} +void ParseMemoryModel(const uint32_t *_instruction, + spv::AddressingModel *addressingModel, + spv::MemoryModel *memoryModel) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpMemoryModel); + uint32_t _o = 1; + *addressingModel = spv::AddressingModel(_instruction[_o++]); + *memoryModel = spv::MemoryModel(_instruction[_o++]); +} +void ParseEntryPoint(const uint32_t *_instruction, + spv::ExecutionModel *executionModel, + IdRef *entryPoint, + LiteralString *name, + IdRefList *interfaceList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpEntryPoint); + uint32_t _o = 1; + *executionModel = spv::ExecutionModel(_instruction[_o++]); + *entryPoint = IdRef(_instruction[_o++]); + ASSERT(IsLittleEndian()); + *name = reinterpret_cast(&_instruction[_o]); + _o += strlen(*name) / 4 + 1; + if (interfaceList) + { + while (_o < _length) + { + interfaceList->emplace_back(_instruction[_o++]); + } + } +} +void ParseExecutionMode(const uint32_t *_instruction, IdRef *entryPoint, spv::ExecutionMode *mode) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpExecutionMode); + uint32_t _o = 1; + *entryPoint = IdRef(_instruction[_o++]); + *mode = spv::ExecutionMode(_instruction[_o++]); +} +void ParseCapability(const uint32_t *_instruction, spv::Capability *capability) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpCapability); + uint32_t _o = 1; + *capability = spv::Capability(_instruction[_o++]); +} +void ParseTypeVoid(const uint32_t *_instruction, IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeVoid); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); +} +void ParseTypeBool(const uint32_t *_instruction, IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeBool); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); +} +void ParseTypeInt(const uint32_t *_instruction, + IdResult *idResult, + LiteralInteger *width, + LiteralInteger *signedness) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeInt); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *width = LiteralInteger(_instruction[_o++]); + *signedness = LiteralInteger(_instruction[_o++]); +} +void ParseTypeFloat(const uint32_t *_instruction, IdResult *idResult, LiteralInteger *width) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeFloat); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *width = LiteralInteger(_instruction[_o++]); +} +void ParseTypeVector(const uint32_t *_instruction, + IdResult *idResult, + IdRef *componentType, + LiteralInteger *componentCount) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeVector); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *componentType = IdRef(_instruction[_o++]); + *componentCount = LiteralInteger(_instruction[_o++]); +} +void ParseTypeMatrix(const uint32_t *_instruction, + IdResult *idResult, + IdRef *columnType, + LiteralInteger *columnCount) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeMatrix); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *columnType = IdRef(_instruction[_o++]); + *columnCount = LiteralInteger(_instruction[_o++]); +} +void ParseTypeImage(const uint32_t *_instruction, + IdResult *idResult, + IdRef *sampledType, + spv::Dim *dim, + LiteralInteger *depth, + LiteralInteger *arrayed, + LiteralInteger *mS, + LiteralInteger *sampled, + spv::ImageFormat *imageFormat, + spv::AccessQualifier *accessQualifier) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeImage); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *sampledType = IdRef(_instruction[_o++]); + *dim = spv::Dim(_instruction[_o++]); + *depth = LiteralInteger(_instruction[_o++]); + *arrayed = LiteralInteger(_instruction[_o++]); + *mS = LiteralInteger(_instruction[_o++]); + *sampled = LiteralInteger(_instruction[_o++]); + *imageFormat = spv::ImageFormat(_instruction[_o++]); + if (accessQualifier && _o < _length) + { + *accessQualifier = spv::AccessQualifier(_instruction[_o++]); + } +} +void ParseTypeSampler(const uint32_t *_instruction, IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeSampler); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); +} +void ParseTypeSampledImage(const uint32_t *_instruction, IdResult *idResult, IdRef *imageType) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeSampledImage); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *imageType = IdRef(_instruction[_o++]); +} +void ParseTypeArray(const uint32_t *_instruction, + IdResult *idResult, + IdRef *elementType, + IdRef *length) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeArray); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *elementType = IdRef(_instruction[_o++]); + *length = IdRef(_instruction[_o++]); +} +void ParseTypeRuntimeArray(const uint32_t *_instruction, IdResult *idResult, IdRef *elementType) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeRuntimeArray); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *elementType = IdRef(_instruction[_o++]); +} +void ParseTypeStruct(const uint32_t *_instruction, IdResult *idResult, IdRefList *memberList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeStruct); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + if (memberList) + { + while (_o < _length) + { + memberList->emplace_back(_instruction[_o++]); + } + } +} +void ParseTypePointer(const uint32_t *_instruction, + IdResult *idResult, + spv::StorageClass *storageClass, + IdRef *type) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypePointer); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *storageClass = spv::StorageClass(_instruction[_o++]); + *type = IdRef(_instruction[_o++]); +} +void ParseTypeFunction(const uint32_t *_instruction, + IdResult *idResult, + IdRef *returnType, + IdRefList *parameterList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeFunction); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); + *returnType = IdRef(_instruction[_o++]); + if (parameterList) + { + while (_o < _length) + { + parameterList->emplace_back(_instruction[_o++]); + } + } +} +void ParseTypeForwardPointer(const uint32_t *_instruction, + IdRef *pointerType, + spv::StorageClass *storageClass) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTypeForwardPointer); + uint32_t _o = 1; + *pointerType = IdRef(_instruction[_o++]); + *storageClass = spv::StorageClass(_instruction[_o++]); +} +void ParseConstantTrue(const uint32_t *_instruction, IdResultType *idResultType, IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConstantTrue); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); +} +void ParseConstantFalse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConstantFalse); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); +} +void ParseConstant(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + LiteralContextDependentNumber *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConstant); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *value = LiteralContextDependentNumber(_instruction[_o++]); +} +void ParseConstantComposite(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRefList *constituentsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConstantComposite); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + if (constituentsList) + { + while (_o < _length) + { + constituentsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseConstantNull(const uint32_t *_instruction, IdResultType *idResultType, IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConstantNull); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); +} +void ParseSpecConstantTrue(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSpecConstantTrue); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); +} +void ParseSpecConstantFalse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSpecConstantFalse); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); +} +void ParseSpecConstant(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + LiteralContextDependentNumber *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSpecConstant); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *value = LiteralContextDependentNumber(_instruction[_o++]); +} +void ParseSpecConstantComposite(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRefList *constituentsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSpecConstantComposite); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + if (constituentsList) + { + while (_o < _length) + { + constituentsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseFunction(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + spv::FunctionControlMask *functionControl, + IdRef *functionType) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFunction); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *functionControl = spv::FunctionControlMask(_instruction[_o++]); + *functionType = IdRef(_instruction[_o++]); +} +void ParseFunctionParameter(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFunctionParameter); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); +} +void ParseFunctionCall(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *function, + IdRefList *argumentList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFunctionCall); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *function = IdRef(_instruction[_o++]); + if (argumentList) + { + while (_o < _length) + { + argumentList->emplace_back(_instruction[_o++]); + } + } +} +void ParseVariable(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + spv::StorageClass *storageClass, + IdRef *initializer) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpVariable); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *storageClass = spv::StorageClass(_instruction[_o++]); + if (initializer && _o < _length) + { + *initializer = IdRef(_instruction[_o++]); + } +} +void ParseImageTexelPointer(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + IdRef *sample) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageTexelPointer); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *image = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *sample = IdRef(_instruction[_o++]); +} +void ParseLoad(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + spv::MemoryAccessMask *memoryAccess) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpLoad); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + if (memoryAccess && _o < _length) + { + *memoryAccess = spv::MemoryAccessMask(_instruction[_o++]); + } +} +void ParseStore(const uint32_t *_instruction, + IdRef *pointer, + IdRef *object, + spv::MemoryAccessMask *memoryAccess) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpStore); + uint32_t _o = 1; + *pointer = IdRef(_instruction[_o++]); + *object = IdRef(_instruction[_o++]); + if (memoryAccess && _o < _length) + { + *memoryAccess = spv::MemoryAccessMask(_instruction[_o++]); + } +} +void ParseCopyMemory(const uint32_t *_instruction, + IdRef *target, + IdRef *source, + spv::MemoryAccessMask *memoryAccess) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpCopyMemory); + uint32_t _o = 1; + *target = IdRef(_instruction[_o++]); + *source = IdRef(_instruction[_o++]); + if (memoryAccess && _o < _length) + { + *memoryAccess = spv::MemoryAccessMask(_instruction[_o++]); + } +} +void ParseCopyMemorySized(const uint32_t *_instruction, + IdRef *target, + IdRef *source, + IdRef *size, + spv::MemoryAccessMask *memoryAccess) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpCopyMemorySized); + uint32_t _o = 1; + *target = IdRef(_instruction[_o++]); + *source = IdRef(_instruction[_o++]); + *size = IdRef(_instruction[_o++]); + if (memoryAccess && _o < _length) + { + *memoryAccess = spv::MemoryAccessMask(_instruction[_o++]); + } +} +void ParseAccessChain(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRefList *indexesList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAccessChain); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); + if (indexesList) + { + while (_o < _length) + { + indexesList->emplace_back(_instruction[_o++]); + } + } +} +void ParseInBoundsAccessChain(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRefList *indexesList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpInBoundsAccessChain); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); + if (indexesList) + { + while (_o < _length) + { + indexesList->emplace_back(_instruction[_o++]); + } + } +} +void ParseArrayLength(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *structure, + LiteralInteger *arraymember) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpArrayLength); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *structure = IdRef(_instruction[_o++]); + *arraymember = LiteralInteger(_instruction[_o++]); +} +void ParseInBoundsPtrAccessChain(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *element, + IdRefList *indexesList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpInBoundsPtrAccessChain); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); + *element = IdRef(_instruction[_o++]); + if (indexesList) + { + while (_o < _length) + { + indexesList->emplace_back(_instruction[_o++]); + } + } +} +void ParseDecorate(const uint32_t *_instruction, + IdRef *target, + spv::Decoration *decoration, + LiteralIntegerList *valuesPairList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpDecorate); + uint32_t _o = 1; + *target = IdRef(_instruction[_o++]); + *decoration = spv::Decoration(_instruction[_o++]); + if (valuesPairList) + { + while (_o < _length) + { + valuesPairList->emplace_back(_instruction[_o++]); + } + } +} +void ParseMemberDecorate(const uint32_t *_instruction, + IdRef *structureType, + LiteralInteger *member, + spv::Decoration *decoration, + LiteralIntegerList *valuesPairList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpMemberDecorate); + uint32_t _o = 1; + *structureType = IdRef(_instruction[_o++]); + *member = LiteralInteger(_instruction[_o++]); + *decoration = spv::Decoration(_instruction[_o++]); + if (valuesPairList) + { + while (_o < _length) + { + valuesPairList->emplace_back(_instruction[_o++]); + } + } +} +void ParseDecorationGroup(const uint32_t *_instruction, IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpDecorationGroup); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); +} +void ParseGroupDecorate(const uint32_t *_instruction, + IdRef *decorationGroup, + IdRefList *targetsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupDecorate); + uint32_t _o = 1; + *decorationGroup = IdRef(_instruction[_o++]); + if (targetsList) + { + while (_o < _length) + { + targetsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseGroupMemberDecorate(const uint32_t *_instruction, + IdRef *decorationGroup, + PairIdRefLiteralIntegerList *targetsPairList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupMemberDecorate); + uint32_t _o = 1; + *decorationGroup = IdRef(_instruction[_o++]); + if (targetsPairList) + { + while (_o < _length) + { + targetsPairList->emplace_back(PairIdRefLiteralInteger{ + IdRef(_instruction[_o]), LiteralInteger(_instruction[_o + 1])}); + _o += 2; + } + } +} +void ParseVectorExtractDynamic(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector, + IdRef *index) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpVectorExtractDynamic); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *vector = IdRef(_instruction[_o++]); + *index = IdRef(_instruction[_o++]); +} +void ParseVectorInsertDynamic(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector, + IdRef *component, + IdRef *index) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpVectorInsertDynamic); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *vector = IdRef(_instruction[_o++]); + *component = IdRef(_instruction[_o++]); + *index = IdRef(_instruction[_o++]); +} +void ParseVectorShuffle(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector1, + IdRef *vector2, + LiteralIntegerList *componentsPairList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpVectorShuffle); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *vector1 = IdRef(_instruction[_o++]); + *vector2 = IdRef(_instruction[_o++]); + if (componentsPairList) + { + while (_o < _length) + { + componentsPairList->emplace_back(_instruction[_o++]); + } + } +} +void ParseCompositeConstruct(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRefList *constituentsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpCompositeConstruct); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + if (constituentsList) + { + while (_o < _length) + { + constituentsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseCompositeExtract(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *composite, + LiteralIntegerList *indexesPairList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpCompositeExtract); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *composite = IdRef(_instruction[_o++]); + if (indexesPairList) + { + while (_o < _length) + { + indexesPairList->emplace_back(_instruction[_o++]); + } + } +} +void ParseCompositeInsert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *object, + IdRef *composite, + LiteralIntegerList *indexesPairList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpCompositeInsert); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *object = IdRef(_instruction[_o++]); + *composite = IdRef(_instruction[_o++]); + if (indexesPairList) + { + while (_o < _length) + { + indexesPairList->emplace_back(_instruction[_o++]); + } + } +} +void ParseCopyObject(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpCopyObject); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand = IdRef(_instruction[_o++]); +} +void ParseTranspose(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *matrix) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpTranspose); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *matrix = IdRef(_instruction[_o++]); +} +void ParseSampledImage(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *sampler) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSampledImage); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *image = IdRef(_instruction[_o++]); + *sampler = IdRef(_instruction[_o++]); +} +void ParseImageSampleImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSampleImplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSampleExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSampleExplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSampleDrefImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSampleDrefImplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSampleDrefExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSampleDrefExplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSampleProjImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSampleProjImplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSampleProjExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSampleProjExplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSampleProjDrefImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSampleProjDrefImplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSampleProjDrefExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSampleProjDrefExplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageFetch(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageFetch); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *image = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageGather(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *component, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageGather); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *component = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageDrefGather(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageDrefGather); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageRead(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageRead); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *image = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageWrite(const uint32_t *_instruction, + IdRef *image, + IdRef *coordinate, + IdRef *texel, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageWrite); + uint32_t _o = 1; + *image = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *texel = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImage(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImage); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); +} +void ParseImageQueryLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageQueryLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); +} +void ParseConvertFToU(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *floatValue) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConvertFToU); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *floatValue = IdRef(_instruction[_o++]); +} +void ParseConvertFToS(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *floatValue) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConvertFToS); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *floatValue = IdRef(_instruction[_o++]); +} +void ParseConvertSToF(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *signedValue) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConvertSToF); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *signedValue = IdRef(_instruction[_o++]); +} +void ParseConvertUToF(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *unsignedValue) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConvertUToF); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *unsignedValue = IdRef(_instruction[_o++]); +} +void ParseUConvert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *unsignedValue) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpUConvert); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *unsignedValue = IdRef(_instruction[_o++]); +} +void ParseSConvert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *signedValue) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSConvert); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *signedValue = IdRef(_instruction[_o++]); +} +void ParseFConvert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *floatValue) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFConvert); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *floatValue = IdRef(_instruction[_o++]); +} +void ParseQuantizeToF16(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpQuantizeToF16); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseConvertPtrToU(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConvertPtrToU); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); +} +void ParseConvertUToPtr(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *integerValue) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpConvertUToPtr); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *integerValue = IdRef(_instruction[_o++]); +} +void ParseBitcast(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBitcast); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand = IdRef(_instruction[_o++]); +} +void ParseSNegate(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSNegate); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand = IdRef(_instruction[_o++]); +} +void ParseFNegate(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFNegate); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand = IdRef(_instruction[_o++]); +} +void ParseIAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpIAdd); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFAdd); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseISub(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpISub); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFSub(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFSub); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseIMul(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpIMul); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFMul(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFMul); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseUDiv(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpUDiv); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseSDiv(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSDiv); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFDiv(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFDiv); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseUMod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpUMod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseSRem(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSRem); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseSMod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSMod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFRem(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFRem); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFMod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFMod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseVectorTimesScalar(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector, + IdRef *scalar) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpVectorTimesScalar); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *vector = IdRef(_instruction[_o++]); + *scalar = IdRef(_instruction[_o++]); +} +void ParseMatrixTimesScalar(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *matrix, + IdRef *scalar) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpMatrixTimesScalar); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *matrix = IdRef(_instruction[_o++]); + *scalar = IdRef(_instruction[_o++]); +} +void ParseVectorTimesMatrix(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector, + IdRef *matrix) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpVectorTimesMatrix); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *vector = IdRef(_instruction[_o++]); + *matrix = IdRef(_instruction[_o++]); +} +void ParseMatrixTimesVector(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *matrix, + IdRef *vector) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpMatrixTimesVector); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *matrix = IdRef(_instruction[_o++]); + *vector = IdRef(_instruction[_o++]); +} +void ParseMatrixTimesMatrix(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *leftMatrix, + IdRef *rightMatrix) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpMatrixTimesMatrix); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *leftMatrix = IdRef(_instruction[_o++]); + *rightMatrix = IdRef(_instruction[_o++]); +} +void ParseOuterProduct(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector1, + IdRef *vector2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpOuterProduct); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *vector1 = IdRef(_instruction[_o++]); + *vector2 = IdRef(_instruction[_o++]); +} +void ParseDot(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector1, + IdRef *vector2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpDot); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *vector1 = IdRef(_instruction[_o++]); + *vector2 = IdRef(_instruction[_o++]); +} +void ParseIAddCarry(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpIAddCarry); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseISubBorrow(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpISubBorrow); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseUMulExtended(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpUMulExtended); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseSMulExtended(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSMulExtended); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseAny(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAny); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *vector = IdRef(_instruction[_o++]); +} +void ParseAll(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAll); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *vector = IdRef(_instruction[_o++]); +} +void ParseIsNan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpIsNan); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseIsInf(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpIsInf); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseLogicalEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpLogicalEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseLogicalNotEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpLogicalNotEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseLogicalOr(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpLogicalOr); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseLogicalAnd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpLogicalAnd); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseLogicalNot(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpLogicalNot); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand = IdRef(_instruction[_o++]); +} +void ParseSelect(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *condition, + IdRef *object1, + IdRef *object2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSelect); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *condition = IdRef(_instruction[_o++]); + *object1 = IdRef(_instruction[_o++]); + *object2 = IdRef(_instruction[_o++]); +} +void ParseIEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpIEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseINotEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpINotEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseUGreaterThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpUGreaterThan); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseSGreaterThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSGreaterThan); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseUGreaterThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpUGreaterThanEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseSGreaterThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSGreaterThanEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseULessThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpULessThan); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseSLessThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSLessThan); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseULessThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpULessThanEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseSLessThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSLessThanEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFOrdEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFOrdEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFUnordEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFUnordEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFOrdNotEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFOrdNotEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFUnordNotEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFUnordNotEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFOrdLessThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFOrdLessThan); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFUnordLessThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFUnordLessThan); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFOrdGreaterThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFOrdGreaterThan); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFUnordGreaterThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFUnordGreaterThan); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFOrdLessThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFOrdLessThanEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFUnordLessThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFUnordLessThanEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFOrdGreaterThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFOrdGreaterThanEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseFUnordGreaterThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFUnordGreaterThanEqual); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseShiftRightLogical(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *shift) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpShiftRightLogical); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); + *shift = IdRef(_instruction[_o++]); +} +void ParseShiftRightArithmetic(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *shift) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpShiftRightArithmetic); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); + *shift = IdRef(_instruction[_o++]); +} +void ParseShiftLeftLogical(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *shift) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpShiftLeftLogical); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); + *shift = IdRef(_instruction[_o++]); +} +void ParseBitwiseOr(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBitwiseOr); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseBitwiseXor(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBitwiseXor); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseBitwiseAnd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBitwiseAnd); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand1 = IdRef(_instruction[_o++]); + *operand2 = IdRef(_instruction[_o++]); +} +void ParseNot(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpNot); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *operand = IdRef(_instruction[_o++]); +} +void ParseBitFieldInsert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *insert, + IdRef *offset, + IdRef *count) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBitFieldInsert); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); + *insert = IdRef(_instruction[_o++]); + *offset = IdRef(_instruction[_o++]); + *count = IdRef(_instruction[_o++]); +} +void ParseBitFieldSExtract(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *offset, + IdRef *count) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBitFieldSExtract); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); + *offset = IdRef(_instruction[_o++]); + *count = IdRef(_instruction[_o++]); +} +void ParseBitFieldUExtract(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *offset, + IdRef *count) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBitFieldUExtract); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); + *offset = IdRef(_instruction[_o++]); + *count = IdRef(_instruction[_o++]); +} +void ParseBitReverse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBitReverse); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); +} +void ParseBitCount(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBitCount); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *base = IdRef(_instruction[_o++]); +} +void ParseDPdx(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpDPdx); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *p = IdRef(_instruction[_o++]); +} +void ParseDPdy(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpDPdy); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *p = IdRef(_instruction[_o++]); +} +void ParseFwidth(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFwidth); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *p = IdRef(_instruction[_o++]); +} +void ParseDPdxFine(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpDPdxFine); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *p = IdRef(_instruction[_o++]); +} +void ParseDPdyFine(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpDPdyFine); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *p = IdRef(_instruction[_o++]); +} +void ParseFwidthFine(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFwidthFine); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *p = IdRef(_instruction[_o++]); +} +void ParseDPdxCoarse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpDPdxCoarse); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *p = IdRef(_instruction[_o++]); +} +void ParseDPdyCoarse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpDPdyCoarse); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *p = IdRef(_instruction[_o++]); +} +void ParseFwidthCoarse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpFwidthCoarse); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *p = IdRef(_instruction[_o++]); +} +void ParseEmitStreamVertex(const uint32_t *_instruction, IdRef *stream) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpEmitStreamVertex); + uint32_t _o = 1; + *stream = IdRef(_instruction[_o++]); +} +void ParseEndStreamPrimitive(const uint32_t *_instruction, IdRef *stream) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpEndStreamPrimitive); + uint32_t _o = 1; + *stream = IdRef(_instruction[_o++]); +} +void ParseControlBarrier(const uint32_t *_instruction, + IdScope *execution, + IdScope *memory, + IdMemorySemantics *semantics) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpControlBarrier); + uint32_t _o = 1; + *execution = IdScope(_instruction[_o++]); + *memory = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); +} +void ParseMemoryBarrier(const uint32_t *_instruction, IdScope *memory, IdMemorySemantics *semantics) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpMemoryBarrier); + uint32_t _o = 1; + *memory = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); +} +void ParseAtomicLoad(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicLoad); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); +} +void ParseAtomicStore(const uint32_t *_instruction, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicStore); + uint32_t _o = 1; + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicExchange(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicExchange); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicCompareExchange(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *equal, + IdMemorySemantics *unequal, + IdRef *value, + IdRef *comparator) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicCompareExchange); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *equal = IdMemorySemantics(_instruction[_o++]); + *unequal = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); + *comparator = IdRef(_instruction[_o++]); +} +void ParseAtomicIIncrement(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicIIncrement); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); +} +void ParseAtomicIDecrement(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicIDecrement); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); +} +void ParseAtomicIAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicIAdd); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicISub(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicISub); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicSMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicSMin); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicUMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicUMin); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicSMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicSMax); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicUMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicUMax); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicAnd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicAnd); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicOr(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicOr); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParseAtomicXor(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpAtomicXor); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *pointer = IdRef(_instruction[_o++]); + *scope = IdScope(_instruction[_o++]); + *semantics = IdMemorySemantics(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); +} +void ParsePhi(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + PairIdRefIdRefList *variableParentPairList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpPhi); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + if (variableParentPairList) + { + while (_o < _length) + { + variableParentPairList->emplace_back( + PairIdRefIdRef{IdRef(_instruction[_o]), IdRef(_instruction[_o + 1])}); + _o += 2; + } + } +} +void ParseLoopMerge(const uint32_t *_instruction, + IdRef *mergeBlock, + IdRef *continueTarget, + spv::LoopControlMask *loopControl) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpLoopMerge); + uint32_t _o = 1; + *mergeBlock = IdRef(_instruction[_o++]); + *continueTarget = IdRef(_instruction[_o++]); + *loopControl = spv::LoopControlMask(_instruction[_o++]); +} +void ParseSelectionMerge(const uint32_t *_instruction, + IdRef *mergeBlock, + spv::SelectionControlMask *selectionControl) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSelectionMerge); + uint32_t _o = 1; + *mergeBlock = IdRef(_instruction[_o++]); + *selectionControl = spv::SelectionControlMask(_instruction[_o++]); +} +void ParseLabel(const uint32_t *_instruction, IdResult *idResult) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpLabel); + uint32_t _o = 1; + *idResult = IdResult(_instruction[_o++]); +} +void ParseBranch(const uint32_t *_instruction, IdRef *targetLabel) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBranch); + uint32_t _o = 1; + *targetLabel = IdRef(_instruction[_o++]); +} +void ParseBranchConditional(const uint32_t *_instruction, + IdRef *condition, + IdRef *trueLabel, + IdRef *falseLabel, + LiteralIntegerList *branchweightsPairList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpBranchConditional); + uint32_t _o = 1; + *condition = IdRef(_instruction[_o++]); + *trueLabel = IdRef(_instruction[_o++]); + *falseLabel = IdRef(_instruction[_o++]); + if (branchweightsPairList) + { + while (_o < _length) + { + branchweightsPairList->emplace_back(_instruction[_o++]); + } + } +} +void ParseSwitch(const uint32_t *_instruction, + IdRef *selector, + IdRef *default_, + PairLiteralIntegerIdRefList *targetPairList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpSwitch); + uint32_t _o = 1; + *selector = IdRef(_instruction[_o++]); + *default_ = IdRef(_instruction[_o++]); + if (targetPairList) + { + while (_o < _length) + { + targetPairList->emplace_back(PairLiteralIntegerIdRef{LiteralInteger(_instruction[_o]), + IdRef(_instruction[_o + 1])}); + _o += 2; + } + } +} +void ParseReturnValue(const uint32_t *_instruction, IdRef *value) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpReturnValue); + uint32_t _o = 1; + *value = IdRef(_instruction[_o++]); +} +void ParseGroupAll(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + IdRef *predicate) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupAll); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *predicate = IdRef(_instruction[_o++]); +} +void ParseGroupAny(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + IdRef *predicate) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupAny); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *predicate = IdRef(_instruction[_o++]); +} +void ParseGroupBroadcast(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + IdRef *value, + IdRef *localId) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupBroadcast); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *value = IdRef(_instruction[_o++]); + *localId = IdRef(_instruction[_o++]); +} +void ParseGroupIAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupIAdd); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupFAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupFAdd); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupFMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupFMin); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupUMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupUMin); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupSMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupSMin); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupFMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupFMax); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupUMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupUMax); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupSMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupSMax); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseImageSparseSampleImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseSampleImplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseSampleExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseSampleExplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseSampleDrefImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseSampleDrefImplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseSampleDrefExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseSampleDrefExplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseSampleProjImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseSampleProjImplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseSampleProjExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseSampleProjExplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseSampleProjDrefImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseSampleProjDrefImplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseSampleProjDrefExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseSampleProjDrefExplicitLod); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseFetch(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseFetch); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *image = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseGather(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *component, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseGather); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *component = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseDrefGather(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseDrefGather); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *sampledImage = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + *dref = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseImageSparseTexelsResident(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *residentCode) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseTexelsResident); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *residentCode = IdRef(_instruction[_o++]); +} +void ParseImageSparseRead(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpImageSparseRead); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *image = IdRef(_instruction[_o++]); + *coordinate = IdRef(_instruction[_o++]); + if (imageOperands && _o < _length) + { + *imageOperands = spv::ImageOperandsMask(_instruction[_o++]); + } + if (imageOperandIdsList) + { + while (_o < _length) + { + imageOperandIdsList->emplace_back(_instruction[_o++]); + } + } +} +void ParseGroupIAddNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupIAddNonUniformAMD); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupFAddNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupFAddNonUniformAMD); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupFMinNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupFMinNonUniformAMD); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupUMinNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupUMinNonUniformAMD); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupSMinNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupSMinNonUniformAMD); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupFMaxNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupFMaxNonUniformAMD); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupUMaxNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupUMaxNonUniformAMD); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} +void ParseGroupSMaxNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x) +{ + spv::Op _op; + uint32_t _length; + GetInstructionOpAndLength(_instruction, &_op, &_length); + ASSERT(_op == spv::OpGroupSMaxNonUniformAMD); + uint32_t _o = 1; + *idResultType = IdResultType(_instruction[_o++]); + *idResult = IdResult(_instruction[_o++]); + *execution = IdScope(_instruction[_o++]); + *operation = spv::GroupOperation(_instruction[_o++]); + *x = IdRef(_instruction[_o++]); +} + +} // namespace spirv +} // namespace angle diff --git a/src/common/spirv/spirv_instruction_parser_autogen.h b/src/common/spirv/spirv_instruction_parser_autogen.h new file mode 100644 index 000000000..58fe7d80e --- /dev/null +++ b/src/common/spirv/spirv_instruction_parser_autogen.h @@ -0,0 +1,1137 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_spirv_builder_and_parser.py using data from spirv.core.grammar.json. +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// spirv_instruction_parser_autogen.h: +// Functions to parse SPIR-V binary for each instruction. + +#ifndef COMMON_SPIRV_SPIRVINSTRUCTIONPARSERAUTOGEN_H_ +#define COMMON_SPIRV_SPIRVINSTRUCTIONPARSERAUTOGEN_H_ + +#include + +#include "spirv_types.h" + +namespace angle +{ +namespace spirv +{ +void GetInstructionOpAndLength(const uint32_t *_instruction, spv::Op *opOut, uint32_t *lengthOut); +void ParseUndef(const uint32_t *_instruction, IdResultType *idResultType, IdResult *idResult); +void ParseSourceContinued(const uint32_t *_instruction, LiteralString *continuedSource); +void ParseSource(const uint32_t *_instruction, + spv::SourceLanguage *sourceLanguage, + LiteralInteger *version, + IdRef *file, + LiteralString *source); +void ParseSourceExtension(const uint32_t *_instruction, LiteralString *extension); +void ParseName(const uint32_t *_instruction, IdRef *target, LiteralString *name); +void ParseMemberName(const uint32_t *_instruction, + IdRef *type, + LiteralInteger *member, + LiteralString *name); +void ParseString(const uint32_t *_instruction, IdResult *idResult, LiteralString *string); +void ParseLine(const uint32_t *_instruction, + IdRef *file, + LiteralInteger *line, + LiteralInteger *column); +void ParseExtension(const uint32_t *_instruction, LiteralString *name); +void ParseExtInstImport(const uint32_t *_instruction, IdResult *idResult, LiteralString *name); +void ParseExtInst(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *set, + LiteralExtInstInteger *instruction, + IdRefList *operandList); +void ParseMemoryModel(const uint32_t *_instruction, + spv::AddressingModel *addressingModel, + spv::MemoryModel *memoryModel); +void ParseEntryPoint(const uint32_t *_instruction, + spv::ExecutionModel *executionModel, + IdRef *entryPoint, + LiteralString *name, + IdRefList *interfaceList); +void ParseExecutionMode(const uint32_t *_instruction, IdRef *entryPoint, spv::ExecutionMode *mode); +void ParseCapability(const uint32_t *_instruction, spv::Capability *capability); +void ParseTypeVoid(const uint32_t *_instruction, IdResult *idResult); +void ParseTypeBool(const uint32_t *_instruction, IdResult *idResult); +void ParseTypeInt(const uint32_t *_instruction, + IdResult *idResult, + LiteralInteger *width, + LiteralInteger *signedness); +void ParseTypeFloat(const uint32_t *_instruction, IdResult *idResult, LiteralInteger *width); +void ParseTypeVector(const uint32_t *_instruction, + IdResult *idResult, + IdRef *componentType, + LiteralInteger *componentCount); +void ParseTypeMatrix(const uint32_t *_instruction, + IdResult *idResult, + IdRef *columnType, + LiteralInteger *columnCount); +void ParseTypeImage(const uint32_t *_instruction, + IdResult *idResult, + IdRef *sampledType, + spv::Dim *dim, + LiteralInteger *depth, + LiteralInteger *arrayed, + LiteralInteger *mS, + LiteralInteger *sampled, + spv::ImageFormat *imageFormat, + spv::AccessQualifier *accessQualifier); +void ParseTypeSampler(const uint32_t *_instruction, IdResult *idResult); +void ParseTypeSampledImage(const uint32_t *_instruction, IdResult *idResult, IdRef *imageType); +void ParseTypeArray(const uint32_t *_instruction, + IdResult *idResult, + IdRef *elementType, + IdRef *length); +void ParseTypeRuntimeArray(const uint32_t *_instruction, IdResult *idResult, IdRef *elementType); +void ParseTypeStruct(const uint32_t *_instruction, IdResult *idResult, IdRefList *memberList); +void ParseTypePointer(const uint32_t *_instruction, + IdResult *idResult, + spv::StorageClass *storageClass, + IdRef *type); +void ParseTypeFunction(const uint32_t *_instruction, + IdResult *idResult, + IdRef *returnType, + IdRefList *parameterList); +void ParseTypeForwardPointer(const uint32_t *_instruction, + IdRef *pointerType, + spv::StorageClass *storageClass); +void ParseConstantTrue(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult); +void ParseConstantFalse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult); +void ParseConstant(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + LiteralContextDependentNumber *value); +void ParseConstantComposite(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRefList *constituentsList); +void ParseConstantNull(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult); +void ParseSpecConstantTrue(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult); +void ParseSpecConstantFalse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult); +void ParseSpecConstant(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + LiteralContextDependentNumber *value); +void ParseSpecConstantComposite(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRefList *constituentsList); +void ParseFunction(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + spv::FunctionControlMask *functionControl, + IdRef *functionType); +void ParseFunctionParameter(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult); +void ParseFunctionCall(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *function, + IdRefList *argumentList); +void ParseVariable(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + spv::StorageClass *storageClass, + IdRef *initializer); +void ParseImageTexelPointer(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + IdRef *sample); +void ParseLoad(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + spv::MemoryAccessMask *memoryAccess); +void ParseStore(const uint32_t *_instruction, + IdRef *pointer, + IdRef *object, + spv::MemoryAccessMask *memoryAccess); +void ParseCopyMemory(const uint32_t *_instruction, + IdRef *target, + IdRef *source, + spv::MemoryAccessMask *memoryAccess); +void ParseCopyMemorySized(const uint32_t *_instruction, + IdRef *target, + IdRef *source, + IdRef *size, + spv::MemoryAccessMask *memoryAccess); +void ParseAccessChain(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRefList *indexesList); +void ParseInBoundsAccessChain(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRefList *indexesList); +void ParseArrayLength(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *structure, + LiteralInteger *arraymember); +void ParseInBoundsPtrAccessChain(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *element, + IdRefList *indexesList); +void ParseDecorate(const uint32_t *_instruction, + IdRef *target, + spv::Decoration *decoration, + LiteralIntegerList *valuesPairList); +void ParseMemberDecorate(const uint32_t *_instruction, + IdRef *structureType, + LiteralInteger *member, + spv::Decoration *decoration, + LiteralIntegerList *valuesPairList); +void ParseDecorationGroup(const uint32_t *_instruction, IdResult *idResult); +void ParseGroupDecorate(const uint32_t *_instruction, + IdRef *decorationGroup, + IdRefList *targetsList); +void ParseGroupMemberDecorate(const uint32_t *_instruction, + IdRef *decorationGroup, + PairIdRefLiteralIntegerList *targetsPairList); +void ParseVectorExtractDynamic(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector, + IdRef *index); +void ParseVectorInsertDynamic(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector, + IdRef *component, + IdRef *index); +void ParseVectorShuffle(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector1, + IdRef *vector2, + LiteralIntegerList *componentsPairList); +void ParseCompositeConstruct(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRefList *constituentsList); +void ParseCompositeExtract(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *composite, + LiteralIntegerList *indexesPairList); +void ParseCompositeInsert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *object, + IdRef *composite, + LiteralIntegerList *indexesPairList); +void ParseCopyObject(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand); +void ParseTranspose(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *matrix); +void ParseSampledImage(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *sampler); +void ParseImageSampleImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSampleExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSampleDrefImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSampleDrefExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSampleProjImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSampleProjExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSampleProjDrefImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSampleProjDrefExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageFetch(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageGather(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *component, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageDrefGather(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageRead(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageWrite(const uint32_t *_instruction, + IdRef *image, + IdRef *coordinate, + IdRef *texel, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImage(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage); +void ParseImageQueryLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate); +void ParseConvertFToU(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *floatValue); +void ParseConvertFToS(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *floatValue); +void ParseConvertSToF(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *signedValue); +void ParseConvertUToF(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *unsignedValue); +void ParseUConvert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *unsignedValue); +void ParseSConvert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *signedValue); +void ParseFConvert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *floatValue); +void ParseQuantizeToF16(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *value); +void ParseConvertPtrToU(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer); +void ParseConvertUToPtr(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *integerValue); +void ParseBitcast(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand); +void ParseSNegate(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand); +void ParseFNegate(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand); +void ParseIAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseISub(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFSub(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseIMul(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFMul(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseUDiv(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseSDiv(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFDiv(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseUMod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseSRem(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseSMod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFRem(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFMod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseVectorTimesScalar(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector, + IdRef *scalar); +void ParseMatrixTimesScalar(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *matrix, + IdRef *scalar); +void ParseVectorTimesMatrix(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector, + IdRef *matrix); +void ParseMatrixTimesVector(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *matrix, + IdRef *vector); +void ParseMatrixTimesMatrix(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *leftMatrix, + IdRef *rightMatrix); +void ParseOuterProduct(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector1, + IdRef *vector2); +void ParseDot(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector1, + IdRef *vector2); +void ParseIAddCarry(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseISubBorrow(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseUMulExtended(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseSMulExtended(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseAny(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector); +void ParseAll(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *vector); +void ParseIsNan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *x); +void ParseIsInf(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *x); +void ParseLogicalEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseLogicalNotEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseLogicalOr(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseLogicalAnd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseLogicalNot(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand); +void ParseSelect(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *condition, + IdRef *object1, + IdRef *object2); +void ParseIEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseINotEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseUGreaterThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseSGreaterThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseUGreaterThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseSGreaterThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseULessThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseSLessThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseULessThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseSLessThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFOrdEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFUnordEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFOrdNotEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFUnordNotEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFOrdLessThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFUnordLessThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFOrdGreaterThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFUnordGreaterThan(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFOrdLessThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFUnordLessThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFOrdGreaterThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseFUnordGreaterThanEqual(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseShiftRightLogical(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *shift); +void ParseShiftRightArithmetic(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *shift); +void ParseShiftLeftLogical(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *shift); +void ParseBitwiseOr(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseBitwiseXor(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseBitwiseAnd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand1, + IdRef *operand2); +void ParseNot(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *operand); +void ParseBitFieldInsert(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *insert, + IdRef *offset, + IdRef *count); +void ParseBitFieldSExtract(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *offset, + IdRef *count); +void ParseBitFieldUExtract(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base, + IdRef *offset, + IdRef *count); +void ParseBitReverse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base); +void ParseBitCount(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *base); +void ParseDPdx(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p); +void ParseDPdy(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p); +void ParseFwidth(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p); +void ParseDPdxFine(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p); +void ParseDPdyFine(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p); +void ParseFwidthFine(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p); +void ParseDPdxCoarse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p); +void ParseDPdyCoarse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p); +void ParseFwidthCoarse(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *p); +void ParseEmitStreamVertex(const uint32_t *_instruction, IdRef *stream); +void ParseEndStreamPrimitive(const uint32_t *_instruction, IdRef *stream); +void ParseControlBarrier(const uint32_t *_instruction, + IdScope *execution, + IdScope *memory, + IdMemorySemantics *semantics); +void ParseMemoryBarrier(const uint32_t *_instruction, + IdScope *memory, + IdMemorySemantics *semantics); +void ParseAtomicLoad(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics); +void ParseAtomicStore(const uint32_t *_instruction, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicExchange(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicCompareExchange(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *equal, + IdMemorySemantics *unequal, + IdRef *value, + IdRef *comparator); +void ParseAtomicIIncrement(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics); +void ParseAtomicIDecrement(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics); +void ParseAtomicIAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicISub(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicSMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicUMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicSMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicUMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicAnd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicOr(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParseAtomicXor(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *pointer, + IdScope *scope, + IdMemorySemantics *semantics, + IdRef *value); +void ParsePhi(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + PairIdRefIdRefList *variableParentPairList); +void ParseLoopMerge(const uint32_t *_instruction, + IdRef *mergeBlock, + IdRef *continueTarget, + spv::LoopControlMask *loopControl); +void ParseSelectionMerge(const uint32_t *_instruction, + IdRef *mergeBlock, + spv::SelectionControlMask *selectionControl); +void ParseLabel(const uint32_t *_instruction, IdResult *idResult); +void ParseBranch(const uint32_t *_instruction, IdRef *targetLabel); +void ParseBranchConditional(const uint32_t *_instruction, + IdRef *condition, + IdRef *trueLabel, + IdRef *falseLabel, + LiteralIntegerList *branchweightsPairList); +void ParseSwitch(const uint32_t *_instruction, + IdRef *selector, + IdRef *default_, + PairLiteralIntegerIdRefList *targetPairList); +void ParseReturnValue(const uint32_t *_instruction, IdRef *value); +void ParseGroupAll(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + IdRef *predicate); +void ParseGroupAny(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + IdRef *predicate); +void ParseGroupBroadcast(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + IdRef *value, + IdRef *localId); +void ParseGroupIAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupFAdd(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupFMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupUMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupSMin(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupFMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupUMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupSMax(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseImageSparseSampleImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseSampleExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseSampleDrefImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseSampleDrefExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseSampleProjImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseSampleProjExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseSampleProjDrefImplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseSampleProjDrefExplicitLod(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseFetch(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseGather(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *component, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseDrefGather(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *sampledImage, + IdRef *coordinate, + IdRef *dref, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseImageSparseTexelsResident(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *residentCode); +void ParseImageSparseRead(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdRef *image, + IdRef *coordinate, + spv::ImageOperandsMask *imageOperands, + IdRefList *imageOperandIdsList); +void ParseGroupIAddNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupFAddNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupFMinNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupUMinNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupSMinNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupFMaxNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupUMaxNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); +void ParseGroupSMaxNonUniformAMD(const uint32_t *_instruction, + IdResultType *idResultType, + IdResult *idResult, + IdScope *execution, + spv::GroupOperation *operation, + IdRef *x); + +} // namespace spirv +} // namespace angle + +#endif // COMMON_SPIRV_SPIRVINSTRUCTIONPARSERAUTOGEN_H_ diff --git a/src/common/spirv/spirv_types.h b/src/common/spirv/spirv_types.h new file mode 100644 index 000000000..e5e6f37ea --- /dev/null +++ b/src/common/spirv/spirv_types.h @@ -0,0 +1,102 @@ +// +// Copyright 2021 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// spirv_types.h: +// Strong types for SPIR-V Ids to prevent mistakes when using the builder and parser APIs. +// + +#ifndef COMMON_SPIRV_TYPES_H_ +#define COMMON_SPIRV_TYPES_H_ + +#include + +#include "common/FastVector.h" + +namespace angle +{ +namespace spirv +{ +template +class BoxedUint32 +{ + public: + BoxedUint32() : mValue{0} {} + explicit BoxedUint32(uint32_t value) : mValue{value} {} + template + T as() const + { + return T{mValue}; + } + BoxedUint32(const BoxedUint32 &other) = default; + BoxedUint32 &operator=(const BoxedUint32 &other) = default; + operator uint32_t() const { return mValue.value; } + bool operator==(const BoxedUint32 &other) const { return mValue.value == other.mValue.value; } + // Applicable to ids, which cannot be 0. + bool valid() const { return static_cast(mValue.value); } + + private: + Helper mValue; +}; + +struct IdRefHelper +{ + spv::Id value; +}; +struct LiteralIntegerHelper +{ + uint32_t value; +}; + +using IdRef = BoxedUint32; +// IdResult, IdResultType, IdMemorySemantics and IdScope are all translated as IdRef. This makes +// the type verification weaker, but stops the API from becoming tediously verbose. +using IdResult = IdRef; +using IdResultType = IdRef; +using IdMemorySemantics = IdRef; +using IdScope = IdRef; +using LiteralInteger = BoxedUint32; +using LiteralString = const char *; +// Note: In ANGLE's use cases, all literals fit in 32 bits. +using LiteralContextDependentNumber = LiteralInteger; +// TODO(syoussefi): To be made stronger when generating SPIR-V from the translator. +// http://anglebug.com/4889 +using LiteralExtInstInteger = LiteralInteger; + +struct PairLiteralIntegerIdRef +{ + LiteralInteger literal; + IdRef id; +}; + +struct PairIdRefLiteralInteger +{ + IdRef id; + LiteralInteger literal; +}; + +struct PairIdRefIdRef +{ + IdRef id1; + IdRef id2; +}; + +// Some instructions need 4 components. The drivers uniform struct in ANGLE has 8 fields. A value +// of 8 means almost no instruction would end up making dynamic allocations. Notable exceptions are +// user-defined structs/blocks and OpEntryPoint. +constexpr size_t kFastVectorSize = 8; + +template +using FastVectorHelper = angle::FastVector; + +using IdRefList = FastVectorHelper; +using LiteralIntegerList = FastVectorHelper; +using PairLiteralIntegerIdRefList = FastVectorHelper; +using PairIdRefLiteralIntegerList = FastVectorHelper; +using PairIdRefIdRefList = FastVectorHelper; + +} // namespace spirv +} // namespace angle + +#endif // COMMON_SPIRV_TYPES_H_ diff --git a/src/libANGLE/renderer/glslang_wrapper_utils.cpp b/src/libANGLE/renderer/glslang_wrapper_utils.cpp index 075e4bfdb..30f48ccb3 100644 --- a/src/libANGLE/renderer/glslang_wrapper_utils.cpp +++ b/src/libANGLE/renderer/glslang_wrapper_utils.cpp @@ -24,9 +24,6 @@ ANGLE_REENABLE_SUGGEST_OVERRIDE_WARNINGS ANGLE_REENABLE_SHADOWING_WARNING ANGLE_REENABLE_EXTRA_SEMI_WARNING -// SPIR-V headers include for AST transformation. -#include - // SPIR-V tools include for AST validation. #include @@ -34,6 +31,8 @@ ANGLE_REENABLE_EXTRA_SEMI_WARNING #include #include "common/FixedVector.h" +#include "common/spirv/spirv_instruction_builder_autogen.h" +#include "common/spirv/spirv_instruction_parser_autogen.h" #include "common/string_utils.h" #include "common/utilities.h" #include "libANGLE/Caps.h" @@ -55,6 +54,8 @@ ANGLE_REENABLE_EXTRA_SEMI_WARNING # define ANGLE_DEBUG_SPIRV_TRANSFORMER 0 #endif // !defined(ANGLE_DEBUG_SPIRV_TRANSFORMER) +namespace spirv = angle::spirv; + namespace rx { namespace @@ -1084,34 +1085,6 @@ bool ValidateSpirv(const std::vector &spirvBlob) } #endif // ANGLE_ENABLE_ASSERTS -// SPIR-V 1.0 Table 2: Instruction Physical Layout -uint32_t GetSpirvInstructionLength(const uint32_t *instruction) -{ - return instruction[0] >> 16; -} - -uint32_t GetSpirvInstructionOp(const uint32_t *instruction) -{ - constexpr uint32_t kOpMask = 0xFFFFu; - return instruction[0] & kOpMask; -} - -void SetSpirvInstructionLength(uint32_t *instruction, size_t length) -{ - ASSERT(length < 0xFFFFu); - - constexpr uint32_t kLengthMask = 0xFFFF0000u; - instruction[0] &= ~kLengthMask; - instruction[0] |= length << 16; -} - -void SetSpirvInstructionOp(uint32_t *instruction, uint32_t op) -{ - constexpr uint32_t kOpMask = 0xFFFFu; - instruction[0] &= ~kOpMask; - instruction[0] |= op; -} - // Base class for SPIR-V transformations. class SpirvTransformerBase : angle::NonCopyable { @@ -1145,37 +1118,12 @@ class SpirvTransformerBase : angle::NonCopyable // Common utilities void onTransformBegin(); - const uint32_t *getCurrentInstruction(uint32_t *opCodeOut, uint32_t *wordCountOut) const; - size_t copyInstruction(const uint32_t *instruction, size_t wordCount); - uint32_t getNewId(); - - // Instruction generators: - void writeAccessChain(uint32_t id, uint32_t typeId, uint32_t baseId, uint32_t indexId); - void writeCopyObject(uint32_t id, uint32_t typeId, uint32_t operandId); - void writeCompositeConstruct(uint32_t id, - uint32_t typeId, - const angle::FixedVector &constituents); - void writeCompositeExtract(uint32_t id, uint32_t typeId, uint32_t compositeId, uint32_t field); - void writeConstant(uint32_t id, uint32_t typeId, uint32_t value); - void writeFAdd(uint32_t id, uint32_t typeId, uint32_t operand1, uint32_t operand2); - void writeFMul(uint32_t id, uint32_t typeId, uint32_t operand1, uint32_t operand2); - void writeFNegate(uint32_t id, uint32_t typeId, uint32_t operand); - void writeLoad(uint32_t id, uint32_t typeId, uint32_t pointerId); - void writeMemberDecorate(uint32_t typeId, uint32_t member, uint32_t decoration, uint32_t value); - void writeStore(uint32_t pointerId, uint32_t objectId); - void writeTypeFloat(uint32_t id, uint32_t width); - void writeTypeInt(uint32_t id, uint32_t width, uint32_t signedness); - void writeTypePointer(uint32_t id, uint32_t storageClass, uint32_t typeId); - void writeTypeVector(uint32_t id, uint32_t componentTypeId, uint32_t componentCount); - void writeVariable(uint32_t id, uint32_t typeId, uint32_t storageClass); - void writeVectorShuffle(uint32_t id, - uint32_t typeId, - uint32_t vec1Id, - uint32_t vec2Id, - const angle::FixedVector &fields); + const uint32_t *getCurrentInstruction(spv::Op *opCodeOut, uint32_t *wordCountOut) const; + void copyInstruction(const uint32_t *instruction, size_t wordCount); + spirv::IdRef getNewId(); // SPIR-V to transform: - const std::vector &mSpirvBlobIn; + const SpirvBlob &mSpirvBlobIn; // Input shader variable info map: const ShaderInterfaceVariableInfoMap &mVariableInfoMap; @@ -1216,14 +1164,13 @@ void SpirvTransformerBase::onTransformBegin() mCurrentWord = kHeaderIndexInstructions; } -const uint32_t *SpirvTransformerBase::getCurrentInstruction(uint32_t *opCodeOut, +const uint32_t *SpirvTransformerBase::getCurrentInstruction(spv::Op *opCodeOut, uint32_t *wordCountOut) const { ASSERT(mCurrentWord < mSpirvBlobIn.size()); const uint32_t *instruction = &mSpirvBlobIn[mCurrentWord]; - *wordCountOut = GetSpirvInstructionLength(instruction); - *opCodeOut = GetSpirvInstructionOp(instruction); + spirv::GetInstructionOpAndLength(instruction, opCodeOut, wordCountOut); // Since glslang succeeded in producing SPIR-V, we assume it to be valid. ASSERT(mCurrentWord + *wordCountOut <= mSpirvBlobIn.size()); @@ -1231,403 +1178,14 @@ const uint32_t *SpirvTransformerBase::getCurrentInstruction(uint32_t *opCodeOut, return instruction; } -size_t SpirvTransformerBase::copyInstruction(const uint32_t *instruction, size_t wordCount) +void SpirvTransformerBase::copyInstruction(const uint32_t *instruction, size_t wordCount) { - size_t instructionOffset = mSpirvBlobOut->size(); mSpirvBlobOut->insert(mSpirvBlobOut->end(), instruction, instruction + wordCount); - return instructionOffset; } -uint32_t SpirvTransformerBase::getNewId() +spirv::IdRef SpirvTransformerBase::getNewId() { - return (*mSpirvBlobOut)[kHeaderIndexIndexBound]++; -} - -void SpirvTransformerBase::writeAccessChain(uint32_t id, - uint32_t typeId, - uint32_t baseId, - uint32_t indexId) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpAccessChain - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kBaseIdIndex = 3; - constexpr size_t kIndexIdIndex = 4; - constexpr size_t kAccessChainInstructionLength = 5; - - std::array accessChain = {}; - - // Fill the fields. - SetSpirvInstructionOp(accessChain.data(), spv::OpAccessChain); - SetSpirvInstructionLength(accessChain.data(), kAccessChainInstructionLength); - accessChain[kTypeIdIndex] = typeId; - accessChain[kIdIndex] = id; - accessChain[kBaseIdIndex] = baseId; - accessChain[kIndexIdIndex] = indexId; - - copyInstruction(accessChain.data(), kAccessChainInstructionLength); -} - -void SpirvTransformerBase::writeCopyObject(uint32_t id, uint32_t typeId, uint32_t operandId) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpCopyObject - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kOperandIdIndex = 3; - constexpr size_t kCopyObjectInstructionLength = 4; - - std::array copyObject = {}; - - // Fill the fields. - SetSpirvInstructionOp(copyObject.data(), spv::OpCopyObject); - SetSpirvInstructionLength(copyObject.data(), kCopyObjectInstructionLength); - copyObject[kTypeIdIndex] = typeId; - copyObject[kIdIndex] = id; - copyObject[kOperandIdIndex] = operandId; - - copyInstruction(copyObject.data(), kCopyObjectInstructionLength); -} - -void SpirvTransformerBase::writeCompositeConstruct( - uint32_t id, - uint32_t typeId, - const angle::FixedVector &constituents) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpCompositeConstruct - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kConstituentsIndexStart = 3; - constexpr size_t kConstituentsMaxCount = 4; - constexpr size_t kCompositeConstructInstructionBaseLength = 3; - - ASSERT(kConstituentsMaxCount == constituents.max_size()); - std::array - compositeConstruct = {}; - - // Fill the fields. - SetSpirvInstructionOp(compositeConstruct.data(), spv::OpCompositeConstruct); - SetSpirvInstructionLength(compositeConstruct.data(), - kCompositeConstructInstructionBaseLength + constituents.size()); - compositeConstruct[kTypeIdIndex] = typeId; - compositeConstruct[kIdIndex] = id; - - for (size_t constituentIndex = 0; constituentIndex < constituents.size(); ++constituentIndex) - { - compositeConstruct[kConstituentsIndexStart + constituentIndex] = - constituents[constituentIndex]; - } - - copyInstruction(compositeConstruct.data(), - kCompositeConstructInstructionBaseLength + constituents.size()); -} - -void SpirvTransformerBase::writeCompositeExtract(uint32_t id, - uint32_t typeId, - uint32_t compositeId, - uint32_t field) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpCompositeExtract - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kCompositeIdIndex = 3; - constexpr size_t kFieldIndex = 4; - constexpr size_t kCompositeExtractInstructionLength = 5; - - std::array compositeExtract = {}; - - // Fill the fields. - SetSpirvInstructionOp(compositeExtract.data(), spv::OpCompositeExtract); - SetSpirvInstructionLength(compositeExtract.data(), kCompositeExtractInstructionLength); - compositeExtract[kTypeIdIndex] = typeId; - compositeExtract[kIdIndex] = id; - compositeExtract[kCompositeIdIndex] = compositeId; - compositeExtract[kFieldIndex] = field; - - copyInstruction(compositeExtract.data(), kCompositeExtractInstructionLength); -} - -void SpirvTransformerBase::writeConstant(uint32_t id, uint32_t typeId, uint32_t value) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpConstant - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kValueIndex = 3; - constexpr size_t kConstantInstructionLength = 4; - - std::array constant = {}; - - // Fill the fields. - SetSpirvInstructionOp(constant.data(), spv::OpConstant); - SetSpirvInstructionLength(constant.data(), kConstantInstructionLength); - constant[kTypeIdIndex] = typeId; - constant[kIdIndex] = id; - constant[kValueIndex] = value; - - copyInstruction(constant.data(), kConstantInstructionLength); -} - -void SpirvTransformerBase::writeFAdd(uint32_t id, - uint32_t typeId, - uint32_t operand1, - uint32_t operand2) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpFAdd - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kOperand1Index = 3; - constexpr size_t kOperand2Index = 4; - constexpr size_t kFAddInstructionLength = 5; - - std::array fAdd = {}; - - // Fill the fields. - SetSpirvInstructionOp(fAdd.data(), spv::OpFAdd); - SetSpirvInstructionLength(fAdd.data(), kFAddInstructionLength); - fAdd[kTypeIdIndex] = typeId; - fAdd[kIdIndex] = id; - fAdd[kOperand1Index] = operand1; - fAdd[kOperand2Index] = operand2; - - copyInstruction(fAdd.data(), kFAddInstructionLength); -} - -void SpirvTransformerBase::writeFMul(uint32_t id, - uint32_t typeId, - uint32_t operand1, - uint32_t operand2) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpFMul - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kOperand1Index = 3; - constexpr size_t kOperand2Index = 4; - constexpr size_t kFMulInstructionLength = 5; - - std::array fMul = {}; - - // Fill the fields. - SetSpirvInstructionOp(fMul.data(), spv::OpFMul); - SetSpirvInstructionLength(fMul.data(), kFMulInstructionLength); - fMul[kTypeIdIndex] = typeId; - fMul[kIdIndex] = id; - fMul[kOperand1Index] = operand1; - fMul[kOperand2Index] = operand2; - - copyInstruction(fMul.data(), kFMulInstructionLength); -} - -void SpirvTransformerBase::writeFNegate(uint32_t id, uint32_t typeId, uint32_t operand) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpFNegate - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kOperandIndex = 3; - constexpr size_t kFNegateInstructionLength = 4; - - std::array fNegate = {}; - - // Fill the fields. - SetSpirvInstructionOp(fNegate.data(), spv::OpFNegate); - SetSpirvInstructionLength(fNegate.data(), kFNegateInstructionLength); - fNegate[kTypeIdIndex] = typeId; - fNegate[kIdIndex] = id; - fNegate[kOperandIndex] = operand; - - copyInstruction(fNegate.data(), kFNegateInstructionLength); -} - -void SpirvTransformerBase::writeLoad(uint32_t id, uint32_t typeId, uint32_t pointerId) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpLoad - constexpr size_t kTypeIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kPointerIdIndex = 3; - constexpr size_t kOpLoadInstructionLength = 4; - - std::array load = {}; - - SetSpirvInstructionOp(load.data(), spv::OpLoad); - SetSpirvInstructionLength(load.data(), kOpLoadInstructionLength); - load[kTypeIndex] = typeId; - load[kIdIndex] = id; - load[kPointerIdIndex] = pointerId; - copyInstruction(load.data(), kOpLoadInstructionLength); -} - -void SpirvTransformerBase::writeMemberDecorate(uint32_t typeId, - uint32_t member, - uint32_t decoration, - uint32_t value) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpMemberDecorate - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kMemberIndex = 2; - constexpr size_t kDecorationIndex = 3; - constexpr size_t kValueIndex = 4; - constexpr size_t kOpMemberDecorateInstructionLength = 5; - - std::array memberDecorate = {}; - - SetSpirvInstructionOp(memberDecorate.data(), spv::OpMemberDecorate); - SetSpirvInstructionLength(memberDecorate.data(), kOpMemberDecorateInstructionLength); - memberDecorate[kTypeIdIndex] = typeId; - memberDecorate[kMemberIndex] = member; - memberDecorate[kDecorationIndex] = decoration; - memberDecorate[kValueIndex] = value; - copyInstruction(memberDecorate.data(), kOpMemberDecorateInstructionLength); -} - -void SpirvTransformerBase::writeStore(uint32_t pointerId, uint32_t objectId) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpStore - constexpr size_t kPointerIdIndex = 1; - constexpr size_t kObjectIdIndex = 2; - constexpr size_t kStoreInstructionLength = 3; - - std::array store = {}; - - // Fill the fields. - SetSpirvInstructionOp(store.data(), spv::OpStore); - SetSpirvInstructionLength(store.data(), kStoreInstructionLength); - store[kPointerIdIndex] = pointerId; - store[kObjectIdIndex] = objectId; - - copyInstruction(store.data(), kStoreInstructionLength); -} - -void SpirvTransformerBase::writeTypeFloat(uint32_t id, uint32_t width) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeFloat - constexpr size_t kIdIndex = 1; - constexpr size_t kWidthIndex = 2; - constexpr size_t kTypeFloatInstructionLength = 3; - - std::array typeFloat = {}; - - // Fill the fields. - SetSpirvInstructionOp(typeFloat.data(), spv::OpTypeFloat); - SetSpirvInstructionLength(typeFloat.data(), kTypeFloatInstructionLength); - typeFloat[kIdIndex] = id; - typeFloat[kWidthIndex] = width; - - copyInstruction(typeFloat.data(), kTypeFloatInstructionLength); -} - -void SpirvTransformerBase::writeTypeInt(uint32_t id, uint32_t width, uint32_t signedness) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeInt - constexpr size_t kIdIndex = 1; - constexpr size_t kWidthIndex = 2; - constexpr size_t kSignednessIndex = 3; - constexpr size_t kTypeIntInstructionLength = 4; - - std::array typeInt = {}; - - // Fill the fields. - SetSpirvInstructionOp(typeInt.data(), spv::OpTypeInt); - SetSpirvInstructionLength(typeInt.data(), kTypeIntInstructionLength); - typeInt[kIdIndex] = id; - typeInt[kWidthIndex] = width; - typeInt[kSignednessIndex] = signedness; - - copyInstruction(typeInt.data(), kTypeIntInstructionLength); -} - -void SpirvTransformerBase::writeTypePointer(uint32_t id, uint32_t storageClass, uint32_t typeId) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpTypePointer - constexpr size_t kIdIndex = 1; - constexpr size_t kStorageClassIndex = 2; - constexpr size_t kTypeIdIndex = 3; - constexpr size_t kTypePointerInstructionLength = 4; - - std::array typePointer = {}; - - // Fill the fields. - SetSpirvInstructionOp(typePointer.data(), spv::OpTypePointer); - SetSpirvInstructionLength(typePointer.data(), kTypePointerInstructionLength); - typePointer[kIdIndex] = id; - typePointer[kStorageClassIndex] = storageClass; - typePointer[kTypeIdIndex] = typeId; - - copyInstruction(typePointer.data(), kTypePointerInstructionLength); -} - -void SpirvTransformerBase::writeTypeVector(uint32_t id, - uint32_t componentTypeId, - uint32_t componentCount) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeVector - constexpr size_t kIdIndex = 1; - constexpr size_t kComponentTypeIdIndex = 2; - constexpr size_t kComponentCountIndex = 3; - constexpr size_t kTypeVectorInstructionLength = 4; - - std::array typeVector = {}; - - // Fill the fields. - SetSpirvInstructionOp(typeVector.data(), spv::OpTypeVector); - SetSpirvInstructionLength(typeVector.data(), kTypeVectorInstructionLength); - typeVector[kIdIndex] = id; - typeVector[kComponentTypeIdIndex] = componentTypeId; - typeVector[kComponentCountIndex] = componentCount; - - copyInstruction(typeVector.data(), kTypeVectorInstructionLength); -} - -void SpirvTransformerBase::writeVariable(uint32_t id, uint32_t typeId, uint32_t storageClass) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpVariable - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kStorageClassIndex = 3; - constexpr size_t kVariableInstructionLength = 4; - - std::array variable = {}; - - // Fill the fields. - SetSpirvInstructionOp(variable.data(), spv::OpVariable); - SetSpirvInstructionLength(variable.data(), kVariableInstructionLength); - variable[kTypeIdIndex] = typeId; - variable[kIdIndex] = id; - variable[kStorageClassIndex] = storageClass; - - copyInstruction(variable.data(), kVariableInstructionLength); -} - -void SpirvTransformerBase::writeVectorShuffle(uint32_t id, - uint32_t typeId, - uint32_t vec1Id, - uint32_t vec2Id, - const angle::FixedVector &fields) -{ - // SPIR-V 1.0 Section 3.32 Instructions, OpVectorShuffle - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kVec1IdIndex = 3; - constexpr size_t kVec2IdIndex = 4; - constexpr size_t kFieldsIndexStart = 5; - constexpr size_t kFieldsMaxCount = 4; - constexpr size_t kVectorShuffleInstructionBaseLength = 5; - - ASSERT(kFieldsMaxCount == fields.max_size()); - std::array vectorShuffle = {}; - - // Fill the fields. - SetSpirvInstructionOp(vectorShuffle.data(), spv::OpVectorShuffle); - SetSpirvInstructionLength(vectorShuffle.data(), - kVectorShuffleInstructionBaseLength + fields.size()); - vectorShuffle[kTypeIdIndex] = typeId; - vectorShuffle[kIdIndex] = id; - vectorShuffle[kVec1IdIndex] = vec1Id; - vectorShuffle[kVec2IdIndex] = vec2Id; - - for (size_t fieldIndex = 0; fieldIndex < fields.size(); ++fieldIndex) - { - vectorShuffle[kFieldsIndexStart + fieldIndex] = fields[fieldIndex]; - } - - copyInstruction(vectorShuffle.data(), kVectorShuffleInstructionBaseLength + fields.size()); + return spirv::IdRef((*mSpirvBlobOut)[kHeaderIndexIndexBound]++); } // A SPIR-V transformer. It walks the instructions and modifies them as necessary, for example to @@ -1635,7 +1193,7 @@ void SpirvTransformerBase::writeVectorShuffle(uint32_t id, class SpirvTransformer final : public SpirvTransformerBase { public: - SpirvTransformer(const std::vector &spirvBlobIn, + SpirvTransformer(const SpirvBlob &spirvBlobIn, GlslangSpirvOptions options, const ShaderInterfaceVariableInfoMap &variableInfoMap, SpirvBlob *spirvBlobOut) @@ -1659,7 +1217,6 @@ class SpirvTransformer final : public SpirvTransformerBase void visitDecorate(const uint32_t *instruction); void visitName(const uint32_t *instruction); void visitMemberName(const uint32_t *instruction); - void visitTypeHelper(const uint32_t *instruction, size_t idIndex, size_t typeIdIndex); void visitTypeArray(const uint32_t *instruction); void visitTypeFloat(const uint32_t *instruction); void visitTypeInt(const uint32_t *instruction); @@ -1669,26 +1226,32 @@ class SpirvTransformer final : public SpirvTransformerBase // Instructions that potentially need transformation. They return true if the instruction is // transformed. If false is returned, the instruction should be copied as-is. - bool transformAccessChain(const uint32_t *instruction, size_t wordCount); + bool transformAccessChain(const uint32_t *instruction); bool transformCapability(const uint32_t *instruction, size_t wordCount); - bool transformDebugInfo(const uint32_t *instruction, size_t wordCount); - bool transformEmitVertex(const uint32_t *instruction, size_t wordCount); - bool transformEntryPoint(const uint32_t *instruction, size_t wordCount); - bool transformDecorate(const uint32_t *instruction, size_t wordCount); - bool transformMemberDecorate(const uint32_t *instruction, size_t wordCount); - bool transformTypePointer(const uint32_t *instruction, size_t wordCount); - bool transformTypeStruct(const uint32_t *instruction, size_t wordCount); - bool transformReturn(const uint32_t *instruction, size_t wordCount); - bool transformVariable(const uint32_t *instruction, size_t wordCount); - bool transformExecutionMode(const uint32_t *instruction, size_t wordCount); + bool transformDebugInfo(const uint32_t *instruction, spv::Op op); + bool transformEmitVertex(const uint32_t *instruction); + bool transformEntryPoint(const uint32_t *instruction); + bool transformDecorate(const uint32_t *instruction); + bool transformMemberDecorate(const uint32_t *instruction); + bool transformTypePointer(const uint32_t *instruction); + bool transformTypeStruct(const uint32_t *instruction); + bool transformReturn(const uint32_t *instruction); + bool transformVariable(const uint32_t *instruction); + bool transformExecutionMode(const uint32_t *instruction); // Helpers: + void visitTypeHelper(spirv::IdResult id, spirv::IdRef typeId); void writePendingDeclarations(); void writeInputPreamble(); void writeOutputPrologue(); - void preRotateXY(uint32_t xId, uint32_t yId, uint32_t *rotatedXIdOut, uint32_t *rotatedYIdOut); - void transformZToVulkanClipSpace(uint32_t zId, uint32_t wId, uint32_t *correctedZIdOut); - void writeTransformFeedbackExtensionOutput(uint32_t positionId); + void preRotateXY(spirv::IdRef xId, + spirv::IdRef yId, + spirv::IdRef *rotatedXIdOut, + spirv::IdRef *rotatedYIdOut); + void transformZToVulkanClipSpace(spirv::IdRef zId, + spirv::IdRef wId, + spirv::IdRef *correctedZIdOut); + void writeTransformFeedbackExtensionOutput(spirv::IdRef positionId); // Special flags: GlslangSpirvOptions mOptions; @@ -1696,8 +1259,8 @@ class SpirvTransformer final : public SpirvTransformerBase // Traversal state: bool mInsertFunctionVariables = false; - uint32_t mEntryPointId = 0; - uint32_t mOpFunctionId = 0; + spirv::IdRef mEntryPointId; + spirv::IdRef mOpFunctionId; // Transformation state: @@ -1705,7 +1268,7 @@ class SpirvTransformer final : public SpirvTransformerBase // not all names are interesting (for example function arguments). When the variable // declaration is met (OpVariable), the variable info is matched with the corresponding id's // name based on the Storage Class. - std::vector mNamesById; + std::vector mNamesById; // Tracks whether a given type is an I/O block. I/O blocks are identified by their type name // instead of variable name, but otherwise look like varyings of struct type (which are @@ -1719,12 +1282,12 @@ class SpirvTransformer final : public SpirvTransformerBase // following vector maps the Output type id to the corresponding Private one. struct TransformedIDs { - uint32_t privateID; - uint32_t typeID; + spirv::IdRef privateID; + spirv::IdRef typeID; }; std::vector mTypePointerTransformedId; - std::vector mFixedVaryingId; - std::vector mFixedVaryingTypeId; + std::vector mFixedVaryingId; + std::vector mFixedVaryingTypeId; // gl_PerVertex is unique in that it's the only builtin of struct type. This struct is pruned // by removing trailing inactive members. We therefore need to keep track of what's its type id @@ -1732,14 +1295,14 @@ class SpirvTransformer final : public SpirvTransformerBase // tessellation have two gl_PerVertex declarations, one for input and one for output. struct PerVertexData { - uint32_t typeId; + spirv::IdRef typeId; uint32_t maxActiveMember; }; PerVertexData mOutputPerVertex; PerVertexData mInputPerVertex; // Ids needed to generate transform feedback support code. - uint32_t mTransformFeedbackExtensionPositionId = 0; + spirv::IdRef mTransformFeedbackExtensionPositionId; // A handful of ids that are used to generate gl_Position transformation code (for pre-rotation // or depth correction). These IDs are used to load/store gl_Position and apply modifications @@ -1754,14 +1317,14 @@ class SpirvTransformer final : public SpirvTransformerBase // - mOutputPerVertexTypePointerId: id of OpTypePointer Output %mOutputPerVertex.typeId // - mOutputPerVertexId: id of OpVariable %mOutputPerVertexTypePointerId Output // - uint32_t mFloatId = 0; - uint32_t mVec4Id = 0; - uint32_t mVec4OutTypePointerId = 0; - uint32_t mIntId = 0; - uint32_t mInt0Id = 0; - uint32_t mFloatHalfId = 0; - uint32_t mOutputPerVertexTypePointerId = 0; - uint32_t mOutputPerVertexId = 0; + spirv::IdRef mFloatId; + spirv::IdRef mVec4Id; + spirv::IdRef mVec4OutTypePointerId; + spirv::IdRef mIntId; + spirv::IdRef mInt0Id; + spirv::IdRef mFloatHalfId; + spirv::IdRef mOutputPerVertexTypePointerId; + spirv::IdRef mOutputPerVertexId; }; bool SpirvTransformer::transform() @@ -1801,9 +1364,9 @@ void SpirvTransformer::resolveVariableIds() // Allocate storage for Output type pointer map. At index i, this vector holds the identical // type as %i except for its storage class turned to Private. // Also store a FunctionID and TypeID for when we need to fix a precision mismatch - mTypePointerTransformedId.resize(indexBound, {0, 0}); - mFixedVaryingId.resize(indexBound, {0}); - mFixedVaryingTypeId.resize(indexBound, {0}); + mTypePointerTransformedId.resize(indexBound); + mFixedVaryingId.resize(indexBound); + mFixedVaryingTypeId.resize(indexBound); size_t currentWord = kHeaderIndexInstructions; @@ -1811,8 +1374,9 @@ void SpirvTransformer::resolveVariableIds() { const uint32_t *instruction = &mSpirvBlobIn[currentWord]; - const uint32_t wordCount = GetSpirvInstructionLength(instruction); - const uint32_t opCode = GetSpirvInstructionOp(instruction); + uint32_t wordCount; + spv::Op opCode; + spirv::GetInstructionOpAndLength(instruction, &opCode, &wordCount); switch (opCode) { @@ -1861,13 +1425,15 @@ void SpirvTransformer::resolveVariableIds() void SpirvTransformer::transformInstruction() { uint32_t wordCount; - uint32_t opCode; + spv::Op opCode; const uint32_t *instruction = getCurrentInstruction(&opCode, &wordCount); if (opCode == spv::OpFunction) { - constexpr size_t kFunctionIdIndex = 2; - mOpFunctionId = instruction[kFunctionIdIndex]; + spirv::IdResultType id; + spv::FunctionControlMask functionControl; + spirv::IdRef functionType; + spirv::ParseFunction(instruction, &id, &mOpFunctionId, &functionControl, &functionType); // SPIR-V is structured in sections. Function declarations come last. Only a few // instructions such as Op*Access* or OpEmitVertex opcodes inside functions need to be @@ -1911,14 +1477,14 @@ void SpirvTransformer::transformInstruction() case spv::OpInBoundsAccessChain: case spv::OpPtrAccessChain: case spv::OpInBoundsPtrAccessChain: - transformed = transformAccessChain(instruction, wordCount); + transformed = transformAccessChain(instruction); break; case spv::OpEmitVertex: - transformed = transformEmitVertex(instruction, wordCount); + transformed = transformEmitVertex(instruction); break; case spv::OpReturn: - transformed = transformReturn(instruction, wordCount); + transformed = transformReturn(instruction); break; default: break; @@ -1935,31 +1501,31 @@ void SpirvTransformer::transformInstruction() case spv::OpLine: case spv::OpNoLine: case spv::OpModuleProcessed: - transformed = transformDebugInfo(instruction, wordCount); + transformed = transformDebugInfo(instruction, opCode); break; case spv::OpCapability: transformed = transformCapability(instruction, wordCount); break; case spv::OpEntryPoint: - transformed = transformEntryPoint(instruction, wordCount); + transformed = transformEntryPoint(instruction); break; case spv::OpDecorate: - transformed = transformDecorate(instruction, wordCount); + transformed = transformDecorate(instruction); break; case spv::OpMemberDecorate: - transformed = transformMemberDecorate(instruction, wordCount); + transformed = transformMemberDecorate(instruction); break; case spv::OpTypePointer: - transformed = transformTypePointer(instruction, wordCount); + transformed = transformTypePointer(instruction); break; case spv::OpTypeStruct: - transformed = transformTypeStruct(instruction, wordCount); + transformed = transformTypeStruct(instruction); break; case spv::OpVariable: - transformed = transformVariable(instruction, wordCount); + transformed = transformVariable(instruction); break; case spv::OpExecutionMode: - transformed = transformExecutionMode(instruction, wordCount); + transformed = transformExecutionMode(instruction); break; default: break; @@ -1987,39 +1553,42 @@ void SpirvTransformer::writePendingDeclarations() return; } - if (mFloatId == 0) + if (!mFloatId.valid()) { mFloatId = getNewId(); - writeTypeFloat(mFloatId, 32); + spirv::WriteTypeFloat(mSpirvBlobOut, mFloatId, spirv::LiteralInteger(32)); } - if (mVec4Id == 0) + if (!mVec4Id.valid()) { mVec4Id = getNewId(); - writeTypeVector(mVec4Id, mFloatId, 4); + spirv::WriteTypeVector(mSpirvBlobOut, mVec4Id, mFloatId, spirv::LiteralInteger(4)); } - if (mVec4OutTypePointerId == 0) + if (!mVec4OutTypePointerId.valid()) { mVec4OutTypePointerId = getNewId(); - writeTypePointer(mVec4OutTypePointerId, spv::StorageClassOutput, mVec4Id); + spirv::WriteTypePointer(mSpirvBlobOut, mVec4OutTypePointerId, spv::StorageClassOutput, + mVec4Id); } - if (mIntId == 0) + if (!mIntId.valid()) { mIntId = getNewId(); - writeTypeInt(mIntId, 32, 1); + spirv::WriteTypeInt(mSpirvBlobOut, mIntId, spirv::LiteralInteger(32), + spirv::LiteralInteger(1)); } - ASSERT(mInt0Id == 0); + ASSERT(!mInt0Id.valid()); mInt0Id = getNewId(); - writeConstant(mInt0Id, mIntId, 0); + spirv::WriteConstant(mSpirvBlobOut, mIntId, mInt0Id, spirv::LiteralContextDependentNumber(0)); constexpr uint32_t kFloatHalfAsUint = 0x3F00'0000; - ASSERT(mFloatHalfId == 0); + ASSERT(!mFloatHalfId.valid()); mFloatHalfId = getNewId(); - writeConstant(mFloatHalfId, mFloatId, kFloatHalfAsUint); + spirv::WriteConstant(mSpirvBlobOut, mFloatId, mFloatHalfId, + spirv::LiteralContextDependentNumber(kFloatHalfAsUint)); } // Called by transformInstruction to insert necessary instructions for casting varyings. @@ -2032,26 +1601,28 @@ void SpirvTransformer::writeInputPreamble() } // Copy from corrected varyings to temp global variables with original precision. - for (uint32_t id = 0; id < mVariableInfoById.size(); id++) + for (uint32_t idIndex = 0; idIndex < mVariableInfoById.size(); idIndex++) { + const spirv::IdRef id(idIndex); const ShaderInterfaceVariableInfo *info = mVariableInfoById[id]; if (info && info->useRelaxedPrecision && info->activeStages[mOptions.shaderType] && info->varyingIsInput) { // This is an input varying, need to cast the mediump value that came from // the previous stage into a highp value that the code wants to work with. - ASSERT(mFixedVaryingTypeId[id] != 0); + ASSERT(mFixedVaryingTypeId[id].valid()); // Build OpLoad instruction to load the mediump value into a temporary - uint32_t tempVar = getNewId(); - uint32_t tempVarType = mTypePointerTransformedId[mFixedVaryingTypeId[id]].typeID; - ASSERT(tempVarType != 0); + const spirv::IdRef tempVar(getNewId()); + const spirv::IdRef tempVarType( + mTypePointerTransformedId[mFixedVaryingTypeId[id]].typeID); + ASSERT(tempVarType.valid()); - writeLoad(tempVar, tempVarType, mFixedVaryingId[id]); + spirv::WriteLoad(mSpirvBlobOut, tempVarType, tempVar, mFixedVaryingId[id], nullptr); // Build OpStore instruction to cast the mediump value to highp for use in // the function - writeStore(id, tempVar); + spirv::WriteStore(mSpirvBlobOut, id, tempVar, nullptr); } } } @@ -2067,28 +1638,30 @@ void SpirvTransformer::writeOutputPrologue() } // Copy from temp global variables with original precision to corrected varyings. - for (uint32_t id = 0; id < mVariableInfoById.size(); id++) + for (uint32_t idIndex = 0; idIndex < mVariableInfoById.size(); idIndex++) { + const spirv::IdRef id(idIndex); const ShaderInterfaceVariableInfo *info = mVariableInfoById[id]; if (info && info->useRelaxedPrecision && info->activeStages[mOptions.shaderType] && info->varyingIsOutput) { - ASSERT(mFixedVaryingTypeId[id] != 0); + ASSERT(mFixedVaryingTypeId[id].valid()); // Build OpLoad instruction to load the highp value into a temporary - uint32_t tempVar = getNewId(); - uint32_t tempVarType = mTypePointerTransformedId[mFixedVaryingTypeId[id]].typeID; - ASSERT(tempVarType != 0); + const spirv::IdRef tempVar(getNewId()); + const spirv::IdRef tempVarType( + mTypePointerTransformedId[mFixedVaryingTypeId[id]].typeID); + ASSERT(tempVarType.valid()); - writeLoad(tempVar, tempVarType, id); + spirv::WriteLoad(mSpirvBlobOut, tempVarType, tempVar, id, nullptr); // Build OpStore instruction to cast the highp value to mediump for output - writeStore(mFixedVaryingId[id], tempVar); + spirv::WriteStore(mSpirvBlobOut, mFixedVaryingId[id], tempVar, nullptr); } } // Transform gl_Position to account for prerotation and Vulkan clip space if necessary. - if (mOutputPerVertexId == 0 || + if (!mOutputPerVertexId.valid() || (IsRotationIdentity(mOptions.preRotation) && !mOptions.transformPositionToVulkanClipSpace)) { return; @@ -2129,43 +1702,48 @@ void SpirvTransformer::writeOutputPrologue() // // Store the results back in gl_Position // OpStore %PositionPointer %RotatedPosition // - const uint32_t positionPointerId = getNewId(); - const uint32_t positionId = getNewId(); - const uint32_t xId = getNewId(); - const uint32_t yId = getNewId(); - const uint32_t zId = getNewId(); - const uint32_t wId = getNewId(); - const uint32_t rotatedPositionId = getNewId(); + const spirv::IdRef positionPointerId(getNewId()); + const spirv::IdRef positionId(getNewId()); + const spirv::IdRef xId(getNewId()); + const spirv::IdRef yId(getNewId()); + const spirv::IdRef zId(getNewId()); + const spirv::IdRef wId(getNewId()); + const spirv::IdRef rotatedPositionId(getNewId()); - writeAccessChain(positionPointerId, mVec4OutTypePointerId, mOutputPerVertexId, mInt0Id); - writeLoad(positionId, mVec4Id, positionPointerId); + spirv::WriteAccessChain(mSpirvBlobOut, mVec4OutTypePointerId, positionPointerId, + mOutputPerVertexId, {mInt0Id}); + spirv::WriteLoad(mSpirvBlobOut, mVec4Id, positionId, positionPointerId, nullptr); - if (mOptions.isTransformFeedbackStage && mTransformFeedbackExtensionPositionId != 0) + if (mOptions.isTransformFeedbackStage && mTransformFeedbackExtensionPositionId.valid()) { writeTransformFeedbackExtensionOutput(positionId); } - writeCompositeExtract(xId, mFloatId, positionId, 0); - writeCompositeExtract(yId, mFloatId, positionId, 1); - writeCompositeExtract(zId, mFloatId, positionId, 2); - writeCompositeExtract(wId, mFloatId, positionId, 3); + spirv::WriteCompositeExtract(mSpirvBlobOut, mFloatId, xId, positionId, + {spirv::LiteralInteger{0}}); + spirv::WriteCompositeExtract(mSpirvBlobOut, mFloatId, yId, positionId, + {spirv::LiteralInteger{1}}); + spirv::WriteCompositeExtract(mSpirvBlobOut, mFloatId, zId, positionId, + {spirv::LiteralInteger{2}}); + spirv::WriteCompositeExtract(mSpirvBlobOut, mFloatId, wId, positionId, + {spirv::LiteralInteger{3}}); - uint32_t rotatedXId = 0; - uint32_t rotatedYId = 0; + spirv::IdRef rotatedXId; + spirv::IdRef rotatedYId; preRotateXY(xId, yId, &rotatedXId, &rotatedYId); - uint32_t correctedZId = 0; + spirv::IdRef correctedZId; transformZToVulkanClipSpace(zId, wId, &correctedZId); - writeCompositeConstruct(rotatedPositionId, mVec4Id, - {rotatedXId, rotatedYId, correctedZId, wId}); - writeStore(positionPointerId, rotatedPositionId); + spirv::WriteCompositeConstruct(mSpirvBlobOut, mVec4Id, rotatedPositionId, + {rotatedXId, rotatedYId, correctedZId, wId}); + spirv::WriteStore(mSpirvBlobOut, positionPointerId, rotatedPositionId, nullptr); } -void SpirvTransformer::preRotateXY(uint32_t xId, - uint32_t yId, - uint32_t *rotatedXIdOut, - uint32_t *rotatedYIdOut) +void SpirvTransformer::preRotateXY(spirv::IdRef xId, + spirv::IdRef yId, + spirv::IdRef *rotatedXIdOut, + spirv::IdRef *rotatedYIdOut) { switch (mOptions.preRotation) { @@ -2182,7 +1760,7 @@ void SpirvTransformer::preRotateXY(uint32_t xId, // [-1 0] * [y] *rotatedXIdOut = yId; *rotatedYIdOut = getNewId(); - writeFNegate(*rotatedYIdOut, mFloatId, xId); + spirv::WriteFNegate(mSpirvBlobOut, mFloatId, *rotatedYIdOut, xId); break; case SurfaceRotation::Rotated180Degrees: case SurfaceRotation::FlippedRotated180Degrees: @@ -2190,8 +1768,8 @@ void SpirvTransformer::preRotateXY(uint32_t xId, // [ 0 -1] * [y] *rotatedXIdOut = getNewId(); *rotatedYIdOut = getNewId(); - writeFNegate(*rotatedXIdOut, mFloatId, xId); - writeFNegate(*rotatedYIdOut, mFloatId, yId); + spirv::WriteFNegate(mSpirvBlobOut, mFloatId, *rotatedXIdOut, xId); + spirv::WriteFNegate(mSpirvBlobOut, mFloatId, *rotatedYIdOut, yId); break; case SurfaceRotation::Rotated270Degrees: case SurfaceRotation::FlippedRotated270Degrees: @@ -2199,16 +1777,16 @@ void SpirvTransformer::preRotateXY(uint32_t xId, // [ 1 0] * [y] *rotatedXIdOut = getNewId(); *rotatedYIdOut = xId; - writeFNegate(*rotatedXIdOut, mFloatId, yId); + spirv::WriteFNegate(mSpirvBlobOut, mFloatId, *rotatedXIdOut, yId); break; default: UNREACHABLE(); } } -void SpirvTransformer::transformZToVulkanClipSpace(uint32_t zId, - uint32_t wId, - uint32_t *correctedZIdOut) +void SpirvTransformer::transformZToVulkanClipSpace(spirv::IdRef zId, + spirv::IdRef wId, + spirv::IdRef *correctedZIdOut) { if (!mOptions.transformPositionToVulkanClipSpace) { @@ -2216,29 +1794,26 @@ void SpirvTransformer::transformZToVulkanClipSpace(uint32_t zId, return; } - const uint32_t zPlusWId = getNewId(); - *correctedZIdOut = getNewId(); + const spirv::IdRef zPlusWId(getNewId()); + *correctedZIdOut = getNewId(); // %zPlusW = OpFAdd %mFloatId %z %w - writeFAdd(zPlusWId, mFloatId, zId, wId); + spirv::WriteFAdd(mSpirvBlobOut, mFloatId, zPlusWId, zId, wId); // %correctedZ = OpFMul %mFloatId %zPlusW %mFloatHalfId - writeFMul(*correctedZIdOut, mFloatId, zPlusWId, mFloatHalfId); + spirv::WriteFMul(mSpirvBlobOut, mFloatId, *correctedZIdOut, zPlusWId, mFloatHalfId); } -void SpirvTransformer::writeTransformFeedbackExtensionOutput(uint32_t positionId) +void SpirvTransformer::writeTransformFeedbackExtensionOutput(spirv::IdRef positionId) { - writeStore(mTransformFeedbackExtensionPositionId, positionId); + spirv::WriteStore(mSpirvBlobOut, mTransformFeedbackExtensionPositionId, positionId, nullptr); } void SpirvTransformer::visitDecorate(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpDecorate - constexpr size_t kIdIndex = 1; - constexpr size_t kDecorationIndex = 2; - - const uint32_t id = instruction[kIdIndex]; - uint32_t decoration = instruction[kDecorationIndex]; + spirv::IdRef id; + spv::Decoration decoration; + spirv::ParseDecorate(instruction, &id, &decoration, nullptr); if (decoration == spv::DecorationBlock) { @@ -2246,7 +1821,7 @@ void SpirvTransformer::visitDecorate(const uint32_t *instruction) // For I/O blocks, associate the type with the info, which is used to decorate its members // with transform feedback if any. - const char *name = mNamesById[id]; + spirv::LiteralString name = mNamesById[id]; ASSERT(name != nullptr); const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(mOptions.shaderType, name); @@ -2256,17 +1831,9 @@ void SpirvTransformer::visitDecorate(const uint32_t *instruction) void SpirvTransformer::visitName(const uint32_t *instruction) { - // We currently don't have any big-endian devices in the list of supported platforms. Literal - // strings in SPIR-V are stored little-endian (SPIR-V 1.0 Section 2.2.1, Literal String), so if - // a big-endian device is to be supported, the string matching here should be specialized. - ASSERT(IsLittleEndian()); - - // SPIR-V 1.0 Section 3.32 Instructions, OpName - constexpr size_t kIdIndex = 1; - constexpr size_t kNameIndex = 2; - - const uint32_t id = instruction[kIdIndex]; - const char *name = reinterpret_cast(&instruction[kNameIndex]); + spirv::IdRef id; + spirv::LiteralString name; + spirv::ParseName(instruction, &id, &name); // The names and ids are unique ASSERT(id < mNamesById.size()); @@ -2277,16 +1844,10 @@ void SpirvTransformer::visitName(const uint32_t *instruction) void SpirvTransformer::visitMemberName(const uint32_t *instruction) { - ASSERT(IsLittleEndian()); - - // SPIR-V 1.0 Section 3.32 Instructions, OpMemberName - constexpr size_t kIdIndex = 1; - constexpr size_t kMemberIndex = 2; - constexpr size_t kNameIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t member = instruction[kMemberIndex]; - const char *name = reinterpret_cast(&instruction[kNameIndex]); + spirv::IdRef id; + spirv::LiteralInteger member; + spirv::LiteralString name; + spirv::ParseMemberName(instruction, &id, &member, &name); // The names and ids are unique ASSERT(id < mNamesById.size()); @@ -2306,7 +1867,7 @@ void SpirvTransformer::visitMemberName(const uint32_t *instruction) // Assume output gl_PerVertex is encountered first. When the storage class of these types are // determined, the variables can be swapped if this assumption was incorrect. - if (mOutputPerVertex.typeId == 0 || id == mOutputPerVertex.typeId) + if (!mOutputPerVertex.typeId.valid() || id == mOutputPerVertex.typeId) { mOutputPerVertex.typeId = id; @@ -2316,7 +1877,7 @@ void SpirvTransformer::visitMemberName(const uint32_t *instruction) mOutputPerVertex.maxActiveMember = member; } } - else if (mInputPerVertex.typeId == 0 || id == mInputPerVertex.typeId) + else if (!mInputPerVertex.typeId.valid() || id == mInputPerVertex.typeId) { mInputPerVertex.typeId = id; @@ -2332,13 +1893,8 @@ void SpirvTransformer::visitMemberName(const uint32_t *instruction) } } -void SpirvTransformer::visitTypeHelper(const uint32_t *instruction, - const size_t idIndex, - const size_t typeIdIndex) +void SpirvTransformer::visitTypeHelper(spirv::IdResult id, spirv::IdRef typeId) { - const uint32_t id = instruction[idIndex]; - const uint32_t typeId = instruction[typeIdIndex]; - // Every type id is declared only once. ASSERT(id < mNamesById.size()); ASSERT(mNamesById[id] == nullptr); @@ -2360,61 +1916,51 @@ void SpirvTransformer::visitTypeHelper(const uint32_t *instruction, void SpirvTransformer::visitTypeArray(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeArray - constexpr size_t kIdIndex = 1; - constexpr size_t kElementTypeIdIndex = 2; + spirv::IdResult id; + spirv::IdRef elementType; + spirv::IdRef length; + spirv::ParseTypeArray(instruction, &id, &elementType, &length); - visitTypeHelper(instruction, kIdIndex, kElementTypeIdIndex); + visitTypeHelper(id, elementType); } void SpirvTransformer::visitTypeFloat(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeFloat - constexpr size_t kIdIndex = 1; - constexpr size_t kWidthIndex = 2; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t width = instruction[kWidthIndex]; + spirv::IdResult id; + spirv::LiteralInteger width; + spirv::ParseTypeFloat(instruction, &id, &width); // Only interested in OpTypeFloat 32. if (width == 32) { - ASSERT(mFloatId == 0); + ASSERT(!mFloatId.valid()); mFloatId = id; } } void SpirvTransformer::visitTypeInt(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeInt - constexpr size_t kIdIndex = 1; - constexpr size_t kWidthIndex = 2; - constexpr size_t kSignednessIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t width = instruction[kWidthIndex]; - const uint32_t signedness = instruction[kSignednessIndex]; + spirv::IdResult id; + spirv::LiteralInteger width; + spirv::LiteralInteger signedness; + spirv::ParseTypeInt(instruction, &id, &width, &signedness); // Only interested in OpTypeInt 32 1. if (width == 32 && signedness == 1) { - ASSERT(mIntId == 0); + ASSERT(!mIntId.valid()); mIntId = id; } } void SpirvTransformer::visitTypePointer(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypePointer - constexpr size_t kIdIndex = 1; - constexpr size_t kStorageClassIndex = 2; - constexpr size_t kTypeIdIndex = 3; + spirv::IdResult id; + spv::StorageClass storageClass; + spirv::IdRef typeId; + spirv::ParseTypePointer(instruction, &id, &storageClass, &typeId); - visitTypeHelper(instruction, kIdIndex, kTypeIdIndex); - - const uint32_t id = instruction[kIdIndex]; - const uint32_t typeId = instruction[kTypeIdIndex]; - const uint32_t storageClass = instruction[kStorageClassIndex]; + visitTypeHelper(id, typeId); // Verify that the ids associated with input and output gl_PerVertex are correct. if (typeId == mOutputPerVertex.typeId || typeId == mInputPerVertex.typeId) @@ -2444,34 +1990,25 @@ void SpirvTransformer::visitTypePointer(const uint32_t *instruction) void SpirvTransformer::visitTypeVector(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeVector - constexpr size_t kIdIndex = 1; - constexpr size_t kComponentIdIndex = 2; - constexpr size_t kComponentCountIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t componentId = instruction[kComponentIdIndex]; - const uint32_t componentCount = instruction[kComponentCountIndex]; + spirv::IdResult id; + spirv::IdRef componentId; + spirv::LiteralInteger componentCount; + spirv::ParseTypeVector(instruction, &id, &componentId, &componentCount); // Only interested in OpTypeVector %mFloatId 4 if (componentId == mFloatId && componentCount == 4) { - ASSERT(mVec4Id == 0); + ASSERT(!mVec4Id.valid()); mVec4Id = id; } } void SpirvTransformer::visitVariable(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpVariable - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kStorageClassIndex = 3; - - // All resources that take set/binding should be transformed. - const uint32_t typeId = instruction[kTypeIdIndex]; - const uint32_t id = instruction[kIdIndex]; - const uint32_t storageClass = instruction[kStorageClassIndex]; + spirv::IdResultType typeId; + spirv::IdResult id; + spv::StorageClass storageClass; + spirv::ParseVariable(instruction, &typeId, &id, &storageClass, nullptr); ASSERT(typeId < mNamesById.size()); ASSERT(id < mNamesById.size()); @@ -2495,8 +2032,8 @@ void SpirvTransformer::visitVariable(const uint32_t *instruction) // For interface block variables, the name that's used to associate info is the block name // rather than the variable name. - const bool isIOBlock = mIsIOBlockById[typeId]; - const char *name = mNamesById[isInterfaceBlockVariable || isIOBlock ? typeId : id]; + const bool isIOBlock = mIsIOBlockById[typeId]; + spirv::LiteralString name = mNamesById[isInterfaceBlockVariable || isIOBlock ? typeId : id]; ASSERT(name != nullptr); @@ -2530,7 +2067,7 @@ void SpirvTransformer::visitVariable(const uint32_t *instruction) mVariableInfoById[id] = &info; if (info.useRelaxedPrecision && info.activeStages[mOptions.shaderType] && - mFixedVaryingId[id] == 0) + !mFixedVaryingId[id].valid()) { mFixedVaryingId[id] = getNewId(); mFixedVaryingTypeId[id] = typeId; @@ -2553,15 +2090,12 @@ void SpirvTransformer::visitVariable(const uint32_t *instruction) } } -bool SpirvTransformer::transformDecorate(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformDecorate(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpDecorate - constexpr size_t kIdIndex = 1; - constexpr size_t kDecorationIndex = 2; - constexpr size_t kDecorationValueIndex = 3; - - uint32_t id = instruction[kIdIndex]; - uint32_t decoration = instruction[kDecorationIndex]; + spirv::IdRef id; + spv::Decoration decoration; + spirv::LiteralIntegerList decorationValues; + spirv::ParseDecorate(instruction, &id, &decoration, &decorationValues); ASSERT(id < mVariableInfoById.size()); const ShaderInterfaceVariableInfo *info = mVariableInfoById[id]; @@ -2579,10 +2113,17 @@ bool SpirvTransformer::transformDecorate(const uint32_t *instruction, size_t wor return true; } + // If using relaxed precision, generate instructions for the replacement id instead. + if (info->useRelaxedPrecision) + { + ASSERT(mFixedVaryingId[id].valid()); + id = mFixedVaryingId[id]; + } + // If this is the Block decoration of a shader I/O block, add the transform feedback decorations // to its members right away. - constexpr size_t kXfbDecorationCount = 3; - constexpr uint32_t kXfbDecorations[kXfbDecorationCount] = { + constexpr size_t kXfbDecorationCount = 3; + constexpr spv::Decoration kXfbDecorations[kXfbDecorationCount] = { spv::DecorationXfbBuffer, spv::DecorationXfbStride, spv::DecorationOffset, @@ -2616,7 +2157,9 @@ bool SpirvTransformer::transformDecorate(const uint32_t *instruction, size_t wor // OpMemberDecorate %id fieldIndex Offset xfb.offset for (size_t i = 0; i < kXfbDecorationCount; ++i) { - writeMemberDecorate(id, fieldIndex, kXfbDecorations[i], xfbDecorationValues[i]); + spirv::WriteMemberDecorate(mSpirvBlobOut, id, spirv::LiteralInteger(fieldIndex), + kXfbDecorations[i], + {spirv::LiteralInteger(xfbDecorationValues[i])}); } } @@ -2640,9 +2183,7 @@ bool SpirvTransformer::transformDecorate(const uint32_t *instruction, size_t wor if (info->useRelaxedPrecision) { // Change the id to replacement variable - ASSERT(mFixedVaryingId[id] != 0); - const size_t instructionOffset = copyInstruction(instruction, wordCount); - (*mSpirvBlobOut)[instructionOffset + kIdIndex] = mFixedVaryingId[id]; + spirv::WriteDecorate(mSpirvBlobOut, id, decoration, decorationValues); return true; } break; @@ -2656,9 +2197,10 @@ bool SpirvTransformer::transformDecorate(const uint32_t *instruction, size_t wor return false; } - // Copy the decoration declaration and modify it. - const size_t instructionOffset = copyInstruction(instruction, wordCount); - (*mSpirvBlobOut)[instructionOffset + kDecorationValueIndex] = newDecorationValue; + // Modify the decoration value. + ASSERT(decorationValues.size() == 1); + spirv::WriteDecorate(mSpirvBlobOut, id, decoration, + {spirv::LiteralInteger(newDecorationValue)}); // If there are decorations to be added, add them right after the Location decoration is // encountered. @@ -2667,31 +2209,18 @@ bool SpirvTransformer::transformDecorate(const uint32_t *instruction, size_t wor return true; } + // If any, the replacement variable is always reduced precision so add that decoration to + // fixedVaryingId. if (info->useRelaxedPrecision) { - // Change the id of the location decoration to replacement variable - ASSERT(mFixedVaryingId[id] != 0); - (*mSpirvBlobOut)[instructionOffset + kIdIndex] = mFixedVaryingId[id]; - - // The replacement variable is always reduced precision so add that decoration to - // fixedVaryingId - constexpr size_t kInstDecorateRelaxedPrecisionWordCount = 3; - uint32_t inst[kInstDecorateRelaxedPrecisionWordCount]; - SetSpirvInstructionLength(inst, kInstDecorateRelaxedPrecisionWordCount); - SetSpirvInstructionOp(inst, spv::OpDecorate); - inst[kIdIndex] = mFixedVaryingId[id]; - inst[kDecorationIndex] = spv::DecorationRelaxedPrecision; - copyInstruction(inst, kInstDecorateRelaxedPrecisionWordCount); + spirv::WriteDecorate(mSpirvBlobOut, id, spv::DecorationRelaxedPrecision, {}); } // Add component decoration, if any. if (info->component != ShaderInterfaceVariableInfo::kInvalid) { - // Copy the location decoration declaration and modify it to contain the Component - // decoration. - const size_t instOffset = copyInstruction(instruction, wordCount); - (*mSpirvBlobOut)[instOffset + kDecorationIndex] = spv::DecorationComponent; - (*mSpirvBlobOut)[instOffset + kDecorationValueIndex] = info->component; + spirv::WriteDecorate(mSpirvBlobOut, id, spv::DecorationComponent, + {spirv::LiteralInteger(info->component)}); } // Add Xfb decorations, if any. @@ -2711,30 +2240,20 @@ bool SpirvTransformer::transformDecorate(const uint32_t *instruction, size_t wor // XfbBuffer, XfbStride and Offset decorations. for (size_t i = 0; i < kXfbDecorationCount; ++i) { - const size_t xfbInstructionOffset = copyInstruction(instruction, wordCount); - if (info->useRelaxedPrecision) - { - // Change the id to replacement variable - (*mSpirvBlobOut)[xfbInstructionOffset + kIdIndex] = mFixedVaryingId[id]; - } - (*mSpirvBlobOut)[xfbInstructionOffset + kDecorationIndex] = kXfbDecorations[i]; - (*mSpirvBlobOut)[xfbInstructionOffset + kDecorationValueIndex] = xfbDecorationValues[i]; + spirv::WriteDecorate(mSpirvBlobOut, id, kXfbDecorations[i], + {spirv::LiteralInteger(xfbDecorationValues[i])}); } } return true; } -bool SpirvTransformer::transformMemberDecorate(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformMemberDecorate(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpMemberDecorate - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kMemberIndex = 2; - constexpr size_t kDecorationIndex = 3; - - uint32_t typeId = instruction[kTypeIdIndex]; - uint32_t member = instruction[kMemberIndex]; - uint32_t decoration = instruction[kDecorationIndex]; + spirv::IdRef typeId; + spirv::LiteralInteger member; + spv::Decoration decoration; + spirv::ParseMemberDecorate(instruction, &typeId, &member, &decoration, nullptr); // Transform only OpMemberDecorate %gl_PerVertex N BuiltIn B if ((typeId != mOutputPerVertex.typeId && typeId != mInputPerVertex.typeId) || @@ -2755,10 +2274,8 @@ bool SpirvTransformer::transformCapability(const uint32_t *instruction, size_t w return false; } - // SPIR-V 1.0 Section 3.32 Instructions, OpCapability - constexpr size_t kCapabilityIndex = 1; - - uint32_t capability = instruction[kCapabilityIndex]; + spv::Capability capability; + spirv::ParseCapability(instruction, &capability); // Transform feedback capability shouldn't have already been specified. ASSERT(capability != spv::CapabilityTransformFeedback); @@ -2774,23 +2291,13 @@ bool SpirvTransformer::transformCapability(const uint32_t *instruction, size_t w // Copy the original capability declaration. copyInstruction(instruction, wordCount); - // Create the TransformFeedback capability declaration. - - // SPIR-V 1.0 Section 3.32 Instructions, OpCapability - constexpr size_t kCapabilityInstructionLength = 2; - - std::array newCapabilityDeclaration = { - instruction[0], // length+opcode is identical - }; - // Fill the fields. - newCapabilityDeclaration[kCapabilityIndex] = spv::CapabilityTransformFeedback; - - copyInstruction(newCapabilityDeclaration.data(), kCapabilityInstructionLength); + // Write the TransformFeedback capability declaration. + spirv::WriteCapability(mSpirvBlobOut, spv::CapabilityTransformFeedback); return true; } -bool SpirvTransformer::transformDebugInfo(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformDebugInfo(const uint32_t *instruction, spv::Op op) { if (mOptions.removeDebugInfo) { @@ -2799,14 +2306,12 @@ bool SpirvTransformer::transformDebugInfo(const uint32_t *instruction, size_t wo } // In the case of OpMemberName, unconditionally remove stripped gl_PerVertex members. - if (GetSpirvInstructionOp(instruction) == spv::OpMemberName) + if (op == spv::OpMemberName) { - // SPIR-V 1.0 Section 3.32 Instructions, OpMemberName - constexpr size_t kIdIndex = 1; - constexpr size_t kMemberIndex = 2; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t member = instruction[kMemberIndex]; + spirv::IdRef id; + spirv::LiteralInteger member; + spirv::LiteralString name; + spirv::ParseMemberName(instruction, &id, &member, &name); // Remove the instruction if it's a stripped member of gl_PerVertex. return (id == mOutputPerVertex.typeId && member > mOutputPerVertex.maxActiveMember) || @@ -2815,11 +2320,13 @@ bool SpirvTransformer::transformDebugInfo(const uint32_t *instruction, size_t wo // In the case of ANGLEXfbN, unconditionally remove the variable names. If transform // feedback is not active, the corresponding variables will be removed. - if (GetSpirvInstructionOp(instruction) == spv::OpName) + if (op == spv::OpName) { + spirv::IdRef id; + spirv::LiteralString name; + spirv::ParseName(instruction, &id, &name); + // SPIR-V 1.0 Section 3.32 Instructions, OpName - constexpr size_t kNameIndex = 2; - const char *name = reinterpret_cast(&instruction[kNameIndex]); if (angle::BeginsWith(name, sh::vk::kXfbEmulationBufferName)) { return true; @@ -2829,7 +2336,7 @@ bool SpirvTransformer::transformDebugInfo(const uint32_t *instruction, size_t wo return false; } -bool SpirvTransformer::transformEmitVertex(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformEmitVertex(const uint32_t *instruction) { // This is only possible in geometry shaders. ASSERT(mOptions.shaderType == gl::ShaderType::Geometry); @@ -2840,35 +2347,22 @@ bool SpirvTransformer::transformEmitVertex(const uint32_t *instruction, size_t w return false; } -bool SpirvTransformer::transformEntryPoint(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformEntryPoint(const uint32_t *instruction) { - // Remove inactive varyings from the shader interface declaration. - - // SPIR-V 1.0 Section 3.32 Instructions, OpEntryPoint - constexpr size_t kEntryPointIdIndex = 2; - constexpr size_t kNameIndex = 3; - - // Calculate the length of entry point name in words. Note that endianness of the string - // doesn't matter, since we are looking for the '\0' character and rounding up to the word size. - // This calculates (strlen(name)+1+3) / 4, which is equal to strlen(name)/4+1. - const size_t nameLength = - strlen(reinterpret_cast(&instruction[kNameIndex])) / 4 + 1; - const uint32_t instructionLength = GetSpirvInstructionLength(instruction); - const size_t interfaceStart = kNameIndex + nameLength; - const size_t interfaceCount = instructionLength - interfaceStart; - // Should only have one EntryPoint - ASSERT(mEntryPointId == 0); - mEntryPointId = instruction[kEntryPointIdIndex]; + ASSERT(!mEntryPointId.valid()); - // Create a copy of the entry point for modification. - std::vector filteredEntryPoint(instruction, instruction + wordCount); + // Remove inactive varyings from the shader interface declaration. + spv::ExecutionModel executionModel; + spirv::LiteralString name; + spirv::IdRefList interfaceList; + spirv::ParseEntryPoint(instruction, &executionModel, &mEntryPointId, &name, &interfaceList); // Filter out inactive varyings from entry point interface declaration. - size_t writeIndex = interfaceStart; - for (size_t index = 0; index < interfaceCount; ++index) + size_t writeIndex = 0; + for (size_t index = 0; index < interfaceList.size(); ++index) { - uint32_t id = instruction[interfaceStart + index]; + spirv::IdRef id(interfaceList[index]); const ShaderInterfaceVariableInfo *info = mVariableInfoById[id]; ASSERT(info); @@ -2879,62 +2373,42 @@ bool SpirvTransformer::transformEntryPoint(const uint32_t *instruction, size_t w } // If ID is one we had to replace due to varying mismatch, use the fixed ID. - if (mFixedVaryingId[id] != 0) + if (mFixedVaryingId[id].valid()) { id = mFixedVaryingId[id]; } - filteredEntryPoint[writeIndex] = id; + interfaceList[writeIndex] = id; ++writeIndex; } - // Update the length of the instruction. - const size_t newLength = writeIndex; - SetSpirvInstructionLength(filteredEntryPoint.data(), newLength); + // Update the number of interface variables. + interfaceList.resize(writeIndex); - // Copy to output. - copyInstruction(filteredEntryPoint.data(), newLength); + // Write the entry point with the inactive interface variables removed. + spirv::WriteEntryPoint(mSpirvBlobOut, executionModel, mEntryPointId, name, interfaceList); // Add an OpExecutionMode Xfb instruction if necessary. - if (!mHasTransformFeedbackOutput) + if (mHasTransformFeedbackOutput) { - return true; + spirv::WriteExecutionMode(mSpirvBlobOut, mEntryPointId, spv::ExecutionModeXfb); } - // SPIR-V 1.0 Section 3.32 Instructions, OpExecutionMode - constexpr size_t kExecutionModeInstructionLength = 3; - constexpr size_t kExecutionModeIdIndex = 1; - constexpr size_t kExecutionModeExecutionModeIndex = 2; - - std::array newExecutionModeDeclaration = {}; - - // Fill the fields. - SetSpirvInstructionOp(newExecutionModeDeclaration.data(), spv::OpExecutionMode); - SetSpirvInstructionLength(newExecutionModeDeclaration.data(), kExecutionModeInstructionLength); - newExecutionModeDeclaration[kExecutionModeIdIndex] = instruction[kEntryPointIdIndex]; - newExecutionModeDeclaration[kExecutionModeExecutionModeIndex] = spv::ExecutionModeXfb; - - copyInstruction(newExecutionModeDeclaration.data(), kExecutionModeInstructionLength); - return true; } -bool SpirvTransformer::transformTypePointer(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformTypePointer(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypePointer - constexpr size_t kIdIndex = 1; - constexpr size_t kStorageClassIndex = 2; - constexpr size_t kTypeIdIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t storageClass = instruction[kStorageClassIndex]; - const uint32_t typeId = instruction[kTypeIdIndex]; + spirv::IdResult id; + spv::StorageClass storageClass; + spirv::IdRef typeId; + spirv::ParseTypePointer(instruction, &id, &storageClass, &typeId); // If the storage class is output, this may be used to create a variable corresponding to an // inactive varying, or if that varying is a struct, an Op*AccessChain retrieving a field of // that inactive varying. // // SPIR-V specifies the storage class both on the type and the variable declaration. Otherwise - // it would have been sufficient to modify the OpVariable instruction. For simplicity, copy + // it would have been sufficient to modify the OpVariable instruction. For simplicity, duplicate // every "OpTypePointer Output" and "OpTypePointer Input" instruction except with the Private // storage class, in case it may be necessary later. @@ -2952,29 +2426,25 @@ bool SpirvTransformer::transformTypePointer(const uint32_t *instruction, size_t return false; } - // Insert OpTypePointer definition for new PrivateType. - const size_t instructionOffset = copyInstruction(instruction, wordCount); + const spirv::IdRef newPrivateTypeId(getNewId()); - const uint32_t newPrivateTypeId = getNewId(); - (*mSpirvBlobOut)[instructionOffset + kIdIndex] = newPrivateTypeId; - (*mSpirvBlobOut)[instructionOffset + kStorageClassIndex] = spv::StorageClassPrivate; + // Write OpTypePointer for the new PrivateType. + spirv::WriteTypePointer(mSpirvBlobOut, newPrivateTypeId, spv::StorageClassPrivate, typeId); // Remember the id of the replacement. ASSERT(id < mTypePointerTransformedId.size()); mTypePointerTransformedId[id].privateID = newPrivateTypeId; // The original instruction should still be present as well. At this point, we don't know - // whether we will need the Output or Private type. + // whether we will need the original or Private type. return false; } -bool SpirvTransformer::transformTypeStruct(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformTypeStruct(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeStruct - constexpr size_t kIdIndex = 1; - constexpr size_t kTypeStructInstructionBaseLength = 2; - - const uint32_t id = instruction[kIdIndex]; + spirv::IdResult id; + spirv::IdRefList memberList; + ParseTypeStruct(instruction, &id, &memberList); if (id != mOutputPerVertex.typeId && id != mInputPerVertex.typeId) { @@ -2986,16 +2456,14 @@ bool SpirvTransformer::transformTypeStruct(const uint32_t *instruction, size_t w // Change the definition of the gl_PerVertex struct by stripping unused fields at the end. const uint32_t memberCount = maxMembers + 1; - const size_t newLength = kTypeStructInstructionBaseLength + memberCount; - ASSERT(wordCount >= newLength); + memberList.resize(memberCount); - const size_t instructionOffset = copyInstruction(instruction, newLength); - SetSpirvInstructionLength(&(*mSpirvBlobOut)[instructionOffset], newLength); + spirv::WriteTypeStruct(mSpirvBlobOut, id, memberList); return true; } -bool SpirvTransformer::transformReturn(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformReturn(const uint32_t *instruction) { if (mOpFunctionId != mEntryPointId) { @@ -3017,16 +2485,12 @@ bool SpirvTransformer::transformReturn(const uint32_t *instruction, size_t wordC return false; } -bool SpirvTransformer::transformVariable(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformVariable(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpVariable - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kStorageClassIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t typeId = instruction[kTypeIdIndex]; - const uint32_t storageClass = instruction[kStorageClassIndex]; + spirv::IdResultType typeId; + spirv::IdResult id; + spv::StorageClass storageClass; + spirv::ParseVariable(instruction, &typeId, &id, &storageClass, nullptr); const ShaderInterfaceVariableInfo *info = mVariableInfoById[id]; @@ -3047,14 +2511,13 @@ bool SpirvTransformer::transformVariable(const uint32_t *instruction, size_t wor (storageClass == spv::StorageClassOutput || storageClass == spv::StorageClassInput)) { // Change existing OpVariable to use fixedVaryingId - const size_t instructionOffset = copyInstruction(instruction, wordCount); - ASSERT(mFixedVaryingId[id] != 0); - (*mSpirvBlobOut)[instructionOffset + kIdIndex] = mFixedVaryingId[id]; + ASSERT(mFixedVaryingId[id].valid()); + spirv::WriteVariable(mSpirvBlobOut, typeId, mFixedVaryingId[id], storageClass, nullptr); // Make original variable a private global - ASSERT(mTypePointerTransformedId[typeId].privateID != 0); - writeVariable(id, mTypePointerTransformedId[typeId].privateID, - spv::StorageClassPrivate); + ASSERT(mTypePointerTransformedId[typeId].privateID.valid()); + spirv::WriteVariable(mSpirvBlobOut, mTypePointerTransformedId[typeId].privateID, id, + spv::StorageClassPrivate, nullptr); return true; } @@ -3074,33 +2537,26 @@ bool SpirvTransformer::transformVariable(const uint32_t *instruction, size_t wor return true; } - // Copy the declaration even though the variable is inactive for the separately compiled shader. ASSERT(storageClass == spv::StorageClassOutput || storageClass == spv::StorageClassInput); - // Copy the variable declaration for modification. Change its type to the corresponding type - // with the Private storage class, as well as changing the storage class respecified in this - // instruction. - const size_t instructionOffset = copyInstruction(instruction, wordCount); - + // The variable is inactive. Output a modified variable declaration, where the type is the + // corresponding type with the Private storage class. ASSERT(typeId < mTypePointerTransformedId.size()); - ASSERT(mTypePointerTransformedId[typeId].privateID != 0); + ASSERT(mTypePointerTransformedId[typeId].privateID.valid()); - (*mSpirvBlobOut)[instructionOffset + kTypeIdIndex] = - mTypePointerTransformedId[typeId].privateID; - (*mSpirvBlobOut)[instructionOffset + kStorageClassIndex] = spv::StorageClassPrivate; + spirv::WriteVariable(mSpirvBlobOut, mTypePointerTransformedId[typeId].privateID, id, + spv::StorageClassPrivate, nullptr); return true; } -bool SpirvTransformer::transformAccessChain(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformAccessChain(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpAccessChain, OpInBoundsAccessChain, OpPtrAccessChain, - // OpInBoundsPtrAccessChain - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kBaseIdIndex = 3; - - const uint32_t typeId = instruction[kTypeIdIndex]; - const uint32_t baseId = instruction[kBaseIdIndex]; + spirv::IdResultType typeId; + spirv::IdResult id; + spirv::IdRef baseId; + spirv::IdRefList indexList; + spirv::ParseAccessChain(instruction, &typeId, &id, &baseId, &indexList); // If not accessing an inactive output varying, nothing to do. const ShaderInterfaceVariableInfo *info = mVariableInfoById[baseId]; @@ -3113,28 +2569,27 @@ bool SpirvTransformer::transformAccessChain(const uint32_t *instruction, size_t { return false; } - // Copy the instruction for modification. - const size_t instructionOffset = copyInstruction(instruction, wordCount); + // Modifiy the instruction to use the private type. ASSERT(typeId < mTypePointerTransformedId.size()); - ASSERT(mTypePointerTransformedId[typeId].privateID != 0); + ASSERT(mTypePointerTransformedId[typeId].privateID.valid()); - (*mSpirvBlobOut)[instructionOffset + kTypeIdIndex] = - mTypePointerTransformedId[typeId].privateID; + spirv::WriteAccessChain(mSpirvBlobOut, mTypePointerTransformedId[typeId].privateID, id, baseId, + indexList); return true; } -bool SpirvTransformer::transformExecutionMode(const uint32_t *instruction, size_t wordCount) +bool SpirvTransformer::transformExecutionMode(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpExecutionMode - constexpr size_t kModeIndex = 2; - const uint32_t executionMode = instruction[kModeIndex]; + spirv::IdRef entryPoint; + spv::ExecutionMode mode; + spirv::ParseExecutionMode(instruction, &entryPoint, &mode); - if (executionMode == spv::ExecutionModeEarlyFragmentTests && + if (mode == spv::ExecutionModeEarlyFragmentTests && mOptions.removeEarlyFragmentTestsOptimization) { - // skip the copy + // Drop the instruction. return true; } return false; @@ -3144,10 +2599,10 @@ struct AliasingAttributeMap { // The SPIR-V id of the aliasing attribute with the most components. This attribute will be // used to read from this location instead of every aliasing one. - uint32_t attribute = 0; + spirv::IdRef attribute; // SPIR-V ids of aliasing attributes. - std::vector aliasingAttributes; + std::vector aliasingAttributes; }; void ValidateShaderInterfaceVariableIsAttribute(const ShaderInterfaceVariableInfo *info) @@ -3174,7 +2629,7 @@ class SpirvVertexAttributeAliasingTransformer final : public SpirvTransformerBas { public: SpirvVertexAttributeAliasingTransformer( - const std::vector &spirvBlobIn, + const SpirvBlob &spirvBlobIn, const ShaderInterfaceVariableInfoMap &variableInfoMap, std::vector &&variableInfoById, SpirvBlob *spirvBlobOut) @@ -3193,8 +2648,8 @@ class SpirvVertexAttributeAliasingTransformer final : public SpirvTransformerBas void transformInstruction(); // Helpers: - uint32_t getAliasingAttributeReplacementId(uint32_t aliasingId, uint32_t row) const; - bool isMatrixAttribute(uint32_t id) const; + spirv::IdRef getAliasingAttributeReplacementId(spirv::IdRef aliasingId, uint32_t offset) const; + bool isMatrixAttribute(spirv::IdRef id) const; // Instructions that are purely informational: void visitTypeFloat(const uint32_t *instruction); @@ -3204,18 +2659,16 @@ class SpirvVertexAttributeAliasingTransformer final : public SpirvTransformerBas // Instructions that potentially need transformation. They return true if the instruction is // transformed. If false is returned, the instruction should be copied as-is. - bool transformEntryPoint(const uint32_t *instruction, size_t wordCount); - bool transformName(const uint32_t *instruction, size_t wordCount); - bool transformDecorate(const uint32_t *instruction, size_t wordCount); - bool transformVariable(const uint32_t *instruction, size_t wordCount); - bool transformAccessChain(const uint32_t *instruction, size_t wordCount); - void transformLoadHelper(const uint32_t *instruction, - size_t wordCount, - uint32_t pointerId, - uint32_t typeId, - uint32_t replacementId, - uint32_t resultId); - bool transformLoad(const uint32_t *instruction, size_t wordCount); + bool transformEntryPoint(const uint32_t *instruction); + bool transformName(const uint32_t *instruction); + bool transformDecorate(const uint32_t *instruction); + bool transformVariable(const uint32_t *instruction); + bool transformAccessChain(const uint32_t *instruction); + void transformLoadHelper(spirv::IdRef pointerId, + spirv::IdRef typeId, + spirv::IdRef replacementId, + spirv::IdRef resultId); + bool transformLoad(const uint32_t *instruction); void declareExpandedMatrixVectors(); void writeExpandedMatrixInitialization(); @@ -3250,13 +2703,13 @@ class SpirvVertexAttributeAliasingTransformer final : public SpirvTransformerBas // For each id %matrix (which corresponds to a matrix attribute), this map contains %vec0. The // ids of the split vectors are consecutive, so %veci == %vec0 + i. %veciType is taken from // mInputTypePointers. - std::vector mExpandedMatrixFirstVectorIdById; + std::vector mExpandedMatrixFirstVectorIdById; // Whether the expanded matrix OpVariables are generated. bool mHaveMatricesExpanded = false; // Whether initialization of the matrix attributes should be written at the beginning of the // current function. bool mWriteExpandedMatrixInitialization = false; - uint32_t mEntryPointId = 0; + spirv::IdRef mEntryPointId; // Id of attribute types; float and veci. This array is one-based, and [0] is unused. // @@ -3264,22 +2717,22 @@ class SpirvVertexAttributeAliasingTransformer final : public SpirvTransformerBas // [N]: id of OpTypeVector %[1] N, N = {2, 3, 4} // // In other words, index of the array corresponds to the number of components in the type. - std::array mFloatTypes = {}; + std::array mFloatTypes; // Corresponding to mFloatTypes, [i]: id of OpMatrix %mFloatTypes[i] i. Note that only square // matrices are possible as attributes in GLSL ES 1.00. [0] and [1] are unused. - std::array mMatrixTypes = {}; + std::array mMatrixTypes; // Corresponding to mFloatTypes, [i]: id of OpTypePointer Input %mFloatTypes[i]. [0] is unused. - std::array mInputTypePointers = {}; + std::array mInputTypePointers; // Corresponding to mFloatTypes, [i]: id of OpTypePointer Private %mFloatTypes[i]. [0] is // unused. - std::array mPrivateFloatTypePointers = {}; + std::array mPrivateFloatTypePointers; // Corresponding to mMatrixTypes, [i]: id of OpTypePointer Private %mMatrixTypes[i]. [0] and // [1] are unused. - std::array mPrivateMatrixTypePointers = {}; + std::array mPrivateMatrixTypePointers; }; bool SpirvVertexAttributeAliasingTransformer::transform() @@ -3302,11 +2755,13 @@ void SpirvVertexAttributeAliasingTransformer::preprocessAliasingAttributes() mVariableInfoById.resize(indexBound, nullptr); mIsAliasingAttributeById.resize(indexBound, false); - mExpandedMatrixFirstVectorIdById.resize(indexBound, 0); + mExpandedMatrixFirstVectorIdById.resize(indexBound); // Go through attributes and find out which alias which. - for (size_t id = 0; id < indexBound; ++id) + for (size_t idIndex = 0; idIndex < indexBound; ++idIndex) { + const spirv::IdRef id(idIndex); + const ShaderInterfaceVariableInfo *info = mVariableInfoById[id]; // Ignore non attribute ids. @@ -3325,12 +2780,12 @@ void SpirvVertexAttributeAliasingTransformer::preprocessAliasingAttributes() uint32_t location = info->location + offset; ASSERT(location < mAliasingAttributeMap.size()); - uint32_t attributeId = id; + spirv::IdRef attributeId(id); // If this is a matrix attribute, expand it to vectors. if (isMatrixAttribute) { - uint32_t matrixId = id; + const spirv::IdRef matrixId(id); // Get a new id for this location and associate it with the matrix. attributeId = getNewId(); @@ -3349,7 +2804,7 @@ void SpirvVertexAttributeAliasingTransformer::preprocessAliasingAttributes() AliasingAttributeMap *aliasingMap = &mAliasingAttributeMap[location]; // If this is the first attribute in this location, remember it. - if (aliasingMap->attribute == 0) + if (!aliasingMap->attribute.valid()) { aliasingMap->attribute = attributeId; continue; @@ -3362,7 +2817,7 @@ void SpirvVertexAttributeAliasingTransformer::preprocessAliasingAttributes() mVariableInfoById[aliasingMap->attribute]; ASSERT(curMainAttribute != nullptr && curMainAttribute->attributeComponentCount > 0); - uint32_t aliasingId; + spirv::IdRef aliasingId; if (info->attributeComponentCount > curMainAttribute->attributeComponentCount) { aliasingId = aliasingMap->attribute; @@ -3374,7 +2829,7 @@ void SpirvVertexAttributeAliasingTransformer::preprocessAliasingAttributes() } aliasingMap->aliasingAttributes.push_back(aliasingId); - ASSERT(mIsAliasingAttributeById[aliasingId] == false); + ASSERT(!mIsAliasingAttributeById[aliasingId]); mIsAliasingAttributeById[aliasingId] = true; } } @@ -3383,7 +2838,7 @@ void SpirvVertexAttributeAliasingTransformer::preprocessAliasingAttributes() void SpirvVertexAttributeAliasingTransformer::transformInstruction() { uint32_t wordCount; - uint32_t opCode; + spv::Op opCode; const uint32_t *instruction = getCurrentInstruction(&opCode, &wordCount); if (opCode == spv::OpFunction) @@ -3402,10 +2857,11 @@ void SpirvVertexAttributeAliasingTransformer::transformInstruction() // they are initialized from the expanded (and potentially aliased) Input vectors. This is // done at the beginning of the entry point. - // SPIR-V 1.0 Section 3.32 Instructions, OpFunction - constexpr size_t kFunctionIdIndex = 2; - - const uint32_t functionId = instruction[kFunctionIdIndex]; + spirv::IdResultType id; + spirv::IdResult functionId; + spv::FunctionControlMask functionControl; + spirv::IdRef functionType; + spirv::ParseFunction(instruction, &id, &functionId, &functionControl, &functionType); mWriteExpandedMatrixInitialization = functionId == mEntryPointId; } @@ -3430,10 +2886,10 @@ void SpirvVertexAttributeAliasingTransformer::transformInstruction() { case spv::OpAccessChain: case spv::OpInBoundsAccessChain: - transformed = transformAccessChain(instruction, wordCount); + transformed = transformAccessChain(instruction); break; case spv::OpLoad: - transformed = transformLoad(instruction, wordCount); + transformed = transformLoad(instruction); break; default: break; @@ -3459,16 +2915,16 @@ void SpirvVertexAttributeAliasingTransformer::transformInstruction() break; // Instructions that may need transformation: case spv::OpEntryPoint: - transformed = transformEntryPoint(instruction, wordCount); + transformed = transformEntryPoint(instruction); break; case spv::OpName: - transformed = transformName(instruction, wordCount); + transformed = transformName(instruction); break; case spv::OpDecorate: - transformed = transformDecorate(instruction, wordCount); + transformed = transformDecorate(instruction); break; case spv::OpVariable: - transformed = transformVariable(instruction, wordCount); + transformed = transformVariable(instruction); break; default: break; @@ -3485,8 +2941,8 @@ void SpirvVertexAttributeAliasingTransformer::transformInstruction() mCurrentWord += wordCount; } -uint32_t SpirvVertexAttributeAliasingTransformer::getAliasingAttributeReplacementId( - uint32_t aliasingId, +spirv::IdRef SpirvVertexAttributeAliasingTransformer::getAliasingAttributeReplacementId( + spirv::IdRef aliasingId, uint32_t offset) const { // Get variable info corresponding to the aliasing attribute. @@ -3498,86 +2954,71 @@ uint32_t SpirvVertexAttributeAliasingTransformer::getAliasingAttributeReplacemen &mAliasingAttributeMap[aliasingInfo->location + offset]; ValidateIsAliasingAttribute(aliasingMap, aliasingId); - const uint32_t replacementId = aliasingMap->attribute; - ASSERT(replacementId != 0 && replacementId < mIsAliasingAttributeById.size()); + const spirv::IdRef replacementId(aliasingMap->attribute); + ASSERT(replacementId.valid() && replacementId < mIsAliasingAttributeById.size()); ASSERT(!mIsAliasingAttributeById[replacementId]); return replacementId; } -bool SpirvVertexAttributeAliasingTransformer::isMatrixAttribute(uint32_t id) const +bool SpirvVertexAttributeAliasingTransformer::isMatrixAttribute(spirv::IdRef id) const { - return mExpandedMatrixFirstVectorIdById[id] != 0; + return mExpandedMatrixFirstVectorIdById[id].valid(); } void SpirvVertexAttributeAliasingTransformer::visitTypeFloat(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeFloat - constexpr size_t kIdIndex = 1; - constexpr size_t kWidthIndex = 2; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t width = instruction[kWidthIndex]; + spirv::IdResult id; + spirv::LiteralInteger width; + spirv::ParseTypeFloat(instruction, &id, &width); // Only interested in OpTypeFloat 32. if (width == 32) { - ASSERT(mFloatTypes[1] == 0); + ASSERT(!mFloatTypes[1].valid()); mFloatTypes[1] = id; } } void SpirvVertexAttributeAliasingTransformer::visitTypeVector(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeVector - constexpr size_t kIdIndex = 1; - constexpr size_t kComponentIdIndex = 2; - constexpr size_t kComponentCountIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t componentId = instruction[kComponentIdIndex]; - const uint32_t componentCount = instruction[kComponentCountIndex]; + spirv::IdResult id; + spirv::IdRef componentId; + spirv::LiteralInteger componentCount; + spirv::ParseTypeVector(instruction, &id, &componentId, &componentCount); // Only interested in OpTypeVector %f32 N, where %f32 is the id of OpTypeFloat 32. if (componentId == mFloatTypes[1]) { ASSERT(componentCount >= 2 && componentCount <= 4); - ASSERT(mFloatTypes[componentCount] == 0); + ASSERT(!mFloatTypes[componentCount].valid()); mFloatTypes[componentCount] = id; } } void SpirvVertexAttributeAliasingTransformer::visitTypeMatrix(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypeMatrix - constexpr size_t kIdIndex = 1; - constexpr size_t kColumnTypeIndex = 2; - constexpr size_t kColumnCountIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t columnType = instruction[kColumnTypeIndex]; - const uint32_t columnCount = instruction[kColumnCountIndex]; + spirv::IdResult id; + spirv::IdRef columnType; + spirv::LiteralInteger columnCount; + spirv::ParseTypeMatrix(instruction, &id, &columnType, &columnCount); // Only interested in OpTypeMatrix %vecN, where %vecN is the id of OpTypeVector %f32 N. // This is only for square matN types (as allowed by GLSL ES 1.00), so columnCount is the same // as rowCount. if (columnType == mFloatTypes[columnCount]) { - ASSERT(mMatrixTypes[columnCount] == 0); + ASSERT(!mMatrixTypes[columnCount].valid()); mMatrixTypes[columnCount] = id; } } void SpirvVertexAttributeAliasingTransformer::visitTypePointer(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpTypePointer - constexpr size_t kIdIndex = 1; - constexpr size_t kStorageClassIndex = 2; - constexpr size_t kTypeIdIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t storageClass = instruction[kStorageClassIndex]; - const uint32_t typeId = instruction[kTypeIdIndex]; + spirv::IdResult id; + spv::StorageClass storageClass; + spirv::IdRef typeId; + spirv::ParseTypePointer(instruction, &id, &storageClass, &typeId); // Only interested in OpTypePointer Input %vecN, where %vecN is the id of OpTypeVector %f32 N, // as well as OpTypePointer Private %matN, where %matN is the id of OpTypeMatrix %vecN N. @@ -3588,7 +3029,7 @@ void SpirvVertexAttributeAliasingTransformer::visitTypePointer(const uint32_t *i { if (typeId == mFloatTypes[n]) { - ASSERT(mInputTypePointers[n] == 0); + ASSERT(!mInputTypePointers[n].valid()); mInputTypePointers[n] = id; break; } @@ -3615,34 +3056,24 @@ void SpirvVertexAttributeAliasingTransformer::visitTypePointer(const uint32_t *i } } -bool SpirvVertexAttributeAliasingTransformer::transformEntryPoint(const uint32_t *instruction, - size_t wordCount) +bool SpirvVertexAttributeAliasingTransformer::transformEntryPoint(const uint32_t *instruction) { - // Remove aliasing attributes from the shader interface declaration. - - // SPIR-V 1.0 Section 3.32 Instructions, OpEntryPoint - constexpr size_t kEntryPointIdIndex = 2; - constexpr size_t kNameIndex = 3; - - // See comment in SpirvTransformer::transformEntryPoint. - const size_t nameLength = - strlen(reinterpret_cast(&instruction[kNameIndex])) / 4 + 1; - const uint32_t instructionLength = GetSpirvInstructionLength(instruction); - const size_t interfaceStart = kNameIndex + nameLength; - // Should only have one EntryPoint - ASSERT(mEntryPointId == 0); - mEntryPointId = instruction[kEntryPointIdIndex]; + ASSERT(!mEntryPointId.valid()); - // Create a copy of the entry point for modification. - std::vector filteredEntryPoint(instruction, instruction + wordCount); + // Remove aliasing attributes from the shader interface declaration. + spv::ExecutionModel executionModel; + spirv::LiteralString name; + spirv::IdRefList interfaceList; + spirv::ParseEntryPoint(instruction, &executionModel, &mEntryPointId, &name, &interfaceList); // As a first pass, filter out matrix attributes and append their replacement vectors. - for (size_t index = interfaceStart; index < instructionLength; ++index) + size_t originalInterfaceListSize = interfaceList.size(); + for (size_t index = 0; index < originalInterfaceListSize; ++index) { - uint32_t matrixId = instruction[index]; + const spirv::IdRef matrixId(interfaceList[index]); - if (mExpandedMatrixFirstVectorIdById[matrixId] == 0) + if (!mExpandedMatrixFirstVectorIdById[matrixId].valid()) { continue; } @@ -3651,22 +3082,22 @@ bool SpirvVertexAttributeAliasingTransformer::transformEntryPoint(const uint32_t ValidateShaderInterfaceVariableIsAttribute(info); // Replace the matrix id with its first vector id. - uint32_t vec0Id = mExpandedMatrixFirstVectorIdById[matrixId]; - filteredEntryPoint[index] = vec0Id; + const spirv::IdRef vec0Id(mExpandedMatrixFirstVectorIdById[matrixId]); + interfaceList[index] = vec0Id; // Append the rest of the vectors to the entry point. for (uint32_t offset = 1; offset < info->attributeLocationCount; ++offset) { - uint32_t vecId = vec0Id + offset; - filteredEntryPoint.push_back(vecId); + const spirv::IdRef vecId(vec0Id + offset); + interfaceList.push_back(vecId); } } // Filter out aliasing attributes from entry point interface declaration. - size_t writeIndex = interfaceStart; - for (size_t index = interfaceStart; index < filteredEntryPoint.size(); ++index) + size_t writeIndex = 0; + for (size_t index = 0; index < interfaceList.size(); ++index) { - uint32_t id = filteredEntryPoint[index]; + const spirv::IdRef id(interfaceList[index]); // If this is an attribute that's aliasing another one in the same location, remove it. if (mIsAliasingAttributeById[id]) @@ -3684,27 +3115,24 @@ bool SpirvVertexAttributeAliasingTransformer::transformEntryPoint(const uint32_t continue; } - filteredEntryPoint[writeIndex] = id; + interfaceList[writeIndex] = id; ++writeIndex; } - // Update the length of the instruction. - const size_t newLength = writeIndex; - SetSpirvInstructionLength(filteredEntryPoint.data(), newLength); + // Update the number of interface variables. + interfaceList.resize(writeIndex); - // Copy to output. - copyInstruction(filteredEntryPoint.data(), newLength); + // Write the entry point with the aliasing attributes removed. + spirv::WriteEntryPoint(mSpirvBlobOut, executionModel, mEntryPointId, name, interfaceList); return true; } -bool SpirvVertexAttributeAliasingTransformer::transformName(const uint32_t *instruction, - size_t wordCount) +bool SpirvVertexAttributeAliasingTransformer::transformName(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpName - constexpr size_t kIdIndex = 1; - - uint32_t id = instruction[kIdIndex]; + spirv::IdRef id; + spirv::LiteralString name; + spirv::ParseName(instruction, &id, &name); // If id is not that of an aliasing attribute, there's nothing to do. ASSERT(id < mIsAliasingAttributeById.size()); @@ -3717,16 +3145,11 @@ bool SpirvVertexAttributeAliasingTransformer::transformName(const uint32_t *inst return true; } -bool SpirvVertexAttributeAliasingTransformer::transformDecorate(const uint32_t *instruction, - size_t wordCount) +bool SpirvVertexAttributeAliasingTransformer::transformDecorate(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpDecorate - constexpr size_t kIdIndex = 1; - constexpr size_t kDecorationIndex = 2; - constexpr size_t kDecorationValueIndex = 3; - - uint32_t id = instruction[kIdIndex]; - uint32_t decoration = instruction[kDecorationIndex]; + spirv::IdRef id; + spv::Decoration decoration; + spirv::ParseDecorate(instruction, &id, &decoration, nullptr); if (isMatrixAttribute(id)) { @@ -3742,20 +3165,19 @@ bool SpirvVertexAttributeAliasingTransformer::transformDecorate(const uint32_t * const ShaderInterfaceVariableInfo *info = mVariableInfoById[id]; ValidateShaderInterfaceVariableIsAttribute(info); - uint32_t vec0Id = mExpandedMatrixFirstVectorIdById[id]; - ASSERT(vec0Id != 0); + const spirv::IdRef vec0Id(mExpandedMatrixFirstVectorIdById[id]); + ASSERT(vec0Id.valid()); for (uint32_t offset = 0; offset < info->attributeLocationCount; ++offset) { - uint32_t vecId = vec0Id + offset; + const spirv::IdRef vecId(vec0Id + offset); if (mIsAliasingAttributeById[vecId]) { continue; } - const size_t instOffset = copyInstruction(instruction, wordCount); - (*mSpirvBlobOut)[instOffset + kIdIndex] = vecId; - (*mSpirvBlobOut)[instOffset + kDecorationValueIndex] = info->location + offset; + spirv::WriteDecorate(mSpirvBlobOut, vecId, decoration, + {spirv::LiteralInteger(info->location + offset)}); } } else @@ -3787,15 +3209,12 @@ bool SpirvVertexAttributeAliasingTransformer::transformDecorate(const uint32_t * return true; } -bool SpirvVertexAttributeAliasingTransformer::transformVariable(const uint32_t *instruction, - size_t wordCount) +bool SpirvVertexAttributeAliasingTransformer::transformVariable(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpVariable - constexpr size_t kIdIndex = 2; - constexpr size_t kStorageClassIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t storageClass = instruction[kStorageClassIndex]; + spirv::IdResultType typeId; + spirv::IdResult id; + spv::StorageClass storageClass; + spirv::ParseVariable(instruction, &typeId, &id, &storageClass, nullptr); if (!isMatrixAttribute(id)) { @@ -3814,28 +3233,22 @@ bool SpirvVertexAttributeAliasingTransformer::transformVariable(const uint32_t * return true; } -bool SpirvVertexAttributeAliasingTransformer::transformAccessChain(const uint32_t *instruction, - size_t wordCount) +bool SpirvVertexAttributeAliasingTransformer::transformAccessChain(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpAccessChain, OpInBoundsAccessChain - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kBaseIdIndex = 3; - - const uint32_t typeId = instruction[kTypeIdIndex]; - const uint32_t baseId = instruction[kBaseIdIndex]; + spirv::IdResultType typeId; + spirv::IdResult id; + spirv::IdRef baseId; + spirv::IdRefList indexList; + spirv::ParseAccessChain(instruction, &typeId, &id, &baseId, &indexList); if (isMatrixAttribute(baseId)) { - // Copy the OpAccessChain instruction for modification. Only modification is that the %type - // is replaced with the Private version of it. If there is one %index, that would be a - // vector type, and if there are two %index'es, it's a float type. + // Write a modified OpAccessChain instruction. Only modification is that the %type is + // replaced with the Private version of it. If there is one %index, that would be a vector + // type, and if there are two %index'es, it's a float type. + spirv::IdRef replacementTypeId; - const size_t instOffset = copyInstruction(instruction, wordCount); - - // SPIR-V 1.0 Section 3.32 Instructions, OpAccessChain, OpInBoundsAccessChain - constexpr size_t kAccessChainBaseLength = 4; - - if (wordCount == kAccessChainBaseLength + 1) + if (indexList.size() == 1) { // If indexed once, it uses a vector type. const ShaderInterfaceVariableInfo *info = mVariableInfoById[baseId]; @@ -3847,16 +3260,18 @@ bool SpirvVertexAttributeAliasingTransformer::transformAccessChain(const uint32_ ASSERT(typeId == mInputTypePointers[componentCount]); // Replace the type with the corresponding Private one. - (*mSpirvBlobOut)[instOffset + kTypeIdIndex] = mPrivateFloatTypePointers[componentCount]; + replacementTypeId = mPrivateFloatTypePointers[componentCount]; } else { // If indexed twice, it uses the float type. - ASSERT(wordCount == kAccessChainBaseLength + 2); + ASSERT(indexList.size() == 2); // Replace the type with the Private pointer to float32. - (*mSpirvBlobOut)[instOffset + kTypeIdIndex] = mPrivateFloatTypePointers[1]; + replacementTypeId = mPrivateFloatTypePointers[1]; } + + spirv::WriteAccessChain(mSpirvBlobOut, replacementTypeId, id, baseId, indexList); } else { @@ -3868,13 +3283,13 @@ bool SpirvVertexAttributeAliasingTransformer::transformAccessChain(const uint32_ } // Find the replacement attribute for the aliasing one. - const uint32_t replacementId = getAliasingAttributeReplacementId(baseId, 0); + const spirv::IdRef replacementId(getAliasingAttributeReplacementId(baseId, 0)); // Get variable info corresponding to the replacement attribute. const ShaderInterfaceVariableInfo *replacementInfo = mVariableInfoById[replacementId]; ValidateShaderInterfaceVariableIsAttribute(replacementInfo); - // Copy the OpAccessChain instruction for modification. Currently, the instruction is: + // Write a modified OpAccessChain instruction. Currently, the instruction is: // // %id = OpAccessChain %type %base %index // @@ -3885,30 +3300,22 @@ bool SpirvVertexAttributeAliasingTransformer::transformAccessChain(const uint32_ // Note that the replacement has at least as many components as the aliasing attribute, // and both attributes start at component 0 (GLSL ES restriction). So, indexing the // replacement attribute with the same index yields the same result and type. - const size_t instOffset = copyInstruction(instruction, wordCount); - (*mSpirvBlobOut)[instOffset + kBaseIdIndex] = replacementId; + spirv::WriteAccessChain(mSpirvBlobOut, typeId, id, replacementId, indexList); } return true; } -void SpirvVertexAttributeAliasingTransformer::transformLoadHelper(const uint32_t *instruction, - size_t wordCount, - uint32_t pointerId, - uint32_t typeId, - uint32_t replacementId, - uint32_t resultId) +void SpirvVertexAttributeAliasingTransformer::transformLoadHelper(spirv::IdRef pointerId, + spirv::IdRef typeId, + spirv::IdRef replacementId, + spirv::IdRef resultId) { - // SPIR-V 1.0 Section 3.32 Instructions, OpLoad - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kPointerIdIndex = 3; - // Get variable info corresponding to the replacement attribute. const ShaderInterfaceVariableInfo *replacementInfo = mVariableInfoById[replacementId]; ValidateShaderInterfaceVariableIsAttribute(replacementInfo); - // Copy the load instruction for modification. Currently, the instruction is: + // Currently, the instruction is: // // %id = OpLoad %type %pointer // @@ -3916,20 +3323,17 @@ void SpirvVertexAttributeAliasingTransformer::transformLoadHelper(const uint32_t // // %newId = OpLoad %replacementType %replacement // - const uint32_t loadResultId = getNewId(); - const uint32_t replacementTypeId = mFloatTypes[replacementInfo->attributeComponentCount]; - ASSERT(replacementTypeId != 0); + const spirv::IdRef loadResultId(getNewId()); + const spirv::IdRef replacementTypeId(mFloatTypes[replacementInfo->attributeComponentCount]); + ASSERT(replacementTypeId.valid()); - const size_t instOffset = copyInstruction(instruction, wordCount); - (*mSpirvBlobOut)[instOffset + kIdIndex] = loadResultId; - (*mSpirvBlobOut)[instOffset + kTypeIdIndex] = replacementTypeId; - (*mSpirvBlobOut)[instOffset + kPointerIdIndex] = replacementId; + spirv::WriteLoad(mSpirvBlobOut, replacementTypeId, loadResultId, replacementId, nullptr); // If swizzle is not necessary, assign %newId to %resultId. const ShaderInterfaceVariableInfo *aliasingInfo = mVariableInfoById[pointerId]; if (aliasingInfo->attributeComponentCount == replacementInfo->attributeComponentCount) { - writeCopyObject(resultId, typeId, loadResultId); + spirv::WriteCopyObject(mSpirvBlobOut, typeId, resultId, loadResultId); return; } @@ -3949,28 +3353,26 @@ void SpirvVertexAttributeAliasingTransformer::transformLoadHelper(const uint32_t if (aliasingInfo->attributeComponentCount == 1) { - writeCompositeExtract(resultId, typeId, loadResultId, 0); + spirv::WriteCompositeExtract(mSpirvBlobOut, typeId, resultId, loadResultId, + {spirv::LiteralInteger(0)}); } else { - angle::FixedVector swizzle = {0, 1, 2, 3}; + spirv::LiteralIntegerList swizzle = {spirv::LiteralInteger(0), spirv::LiteralInteger(1), + spirv::LiteralInteger(2), spirv::LiteralInteger(3)}; swizzle.resize(aliasingInfo->attributeComponentCount); - writeVectorShuffle(resultId, typeId, loadResultId, loadResultId, swizzle); + spirv::WriteVectorShuffle(mSpirvBlobOut, typeId, resultId, loadResultId, loadResultId, + swizzle); } } -bool SpirvVertexAttributeAliasingTransformer::transformLoad(const uint32_t *instruction, - size_t wordCount) +bool SpirvVertexAttributeAliasingTransformer::transformLoad(const uint32_t *instruction) { - // SPIR-V 1.0 Section 3.32 Instructions, OpLoad - constexpr size_t kTypeIdIndex = 1; - constexpr size_t kIdIndex = 2; - constexpr size_t kPointerIdIndex = 3; - - const uint32_t id = instruction[kIdIndex]; - const uint32_t typeId = instruction[kTypeIdIndex]; - const uint32_t pointerId = instruction[kPointerIdIndex]; + spirv::IdResultType typeId; + spirv::IdResult id; + spirv::IdRef pointerId; + ParseLoad(instruction, &typeId, &id, &pointerId, nullptr); // Currently, the instruction is: // @@ -3985,10 +3387,9 @@ bool SpirvVertexAttributeAliasingTransformer::transformLoad(const uint32_t *inst const ShaderInterfaceVariableInfo *info = mVariableInfoById[pointerId]; ValidateShaderInterfaceVariableIsAttribute(info); - const uint32_t replacementTypeId = mMatrixTypes[info->attributeLocationCount]; + const spirv::IdRef replacementTypeId(mMatrixTypes[info->attributeLocationCount]); - const size_t instOffset = copyInstruction(instruction, wordCount); - (*mSpirvBlobOut)[instOffset + kTypeIdIndex] = replacementTypeId; + spirv::WriteLoad(mSpirvBlobOut, replacementTypeId, id, pointerId, nullptr); } else { @@ -4000,10 +3401,10 @@ bool SpirvVertexAttributeAliasingTransformer::transformLoad(const uint32_t *inst } // Find the replacement attribute for the aliasing one. - const uint32_t replacementId = getAliasingAttributeReplacementId(pointerId, 0); + const spirv::IdRef replacementId(getAliasingAttributeReplacementId(pointerId, 0)); // Replace the load instruction by a load from the replacement id. - transformLoadHelper(instruction, wordCount, pointerId, typeId, replacementId, id); + transformLoadHelper(pointerId, typeId, replacementId, id); } return true; @@ -4012,10 +3413,12 @@ bool SpirvVertexAttributeAliasingTransformer::transformLoad(const uint32_t *inst void SpirvVertexAttributeAliasingTransformer::declareExpandedMatrixVectors() { // Go through matrix attributes and expand them. - for (size_t matrixId = 0; matrixId < mExpandedMatrixFirstVectorIdById.size(); ++matrixId) + for (uint32_t matrixIdIndex = 0; matrixIdIndex < mExpandedMatrixFirstVectorIdById.size(); + ++matrixIdIndex) { - uint32_t vec0Id = mExpandedMatrixFirstVectorIdById[matrixId]; - if (vec0Id == 0) + const spirv::IdRef matrixId(matrixIdIndex); + const spirv::IdRef vec0Id(mExpandedMatrixFirstVectorIdById[matrixId]); + if (!vec0Id.valid()) { continue; } @@ -4034,39 +3437,43 @@ void SpirvVertexAttributeAliasingTransformer::declareExpandedMatrixVectors() const uint32_t componentCount = info->attributeComponentCount; const uint32_t locationCount = info->attributeLocationCount; ASSERT(componentCount == locationCount); - ASSERT(mMatrixTypes[locationCount] != 0); + ASSERT(mMatrixTypes[locationCount].valid()); // OpTypePointer Private %matrixType - uint32_t privateType = mPrivateMatrixTypePointers[locationCount]; - if (privateType == 0) + spirv::IdRef privateType(mPrivateMatrixTypePointers[locationCount]); + if (!privateType.valid()) { privateType = getNewId(); mPrivateMatrixTypePointers[locationCount] = privateType; - writeTypePointer(privateType, spv::StorageClassPrivate, mMatrixTypes[locationCount]); + spirv::WriteTypePointer(mSpirvBlobOut, privateType, spv::StorageClassPrivate, + mMatrixTypes[locationCount]); } // OpVariable %privateType Private - writeVariable(matrixId, privateType, spv::StorageClassPrivate); + spirv::WriteVariable(mSpirvBlobOut, privateType, matrixId, spv::StorageClassPrivate, + nullptr); // If the OpTypePointer is not declared for the vector type corresponding to each location, // declare it now. // // %vecType = OpTypePointer %vecType Input - uint32_t inputType = mInputTypePointers[componentCount]; - if (inputType == 0) + spirv::IdRef inputType(mInputTypePointers[componentCount]); + if (!inputType.valid()) { inputType = getNewId(); mInputTypePointers[componentCount] = inputType; - writeTypePointer(inputType, spv::StorageClassInput, mFloatTypes[componentCount]); + spirv::WriteTypePointer(mSpirvBlobOut, inputType, spv::StorageClassInput, + mFloatTypes[componentCount]); } // Declare a vector for each column of the matrix. for (uint32_t offset = 0; offset < info->attributeLocationCount; ++offset) { - uint32_t vecId = vec0Id + offset; + const spirv::IdRef vecId(vec0Id + offset); if (!mIsAliasingAttributeById[vecId]) { - writeVariable(vecId, inputType, spv::StorageClassInput); + spirv::WriteVariable(mSpirvBlobOut, inputType, vecId, spv::StorageClassInput, + nullptr); } } } @@ -4075,31 +3482,26 @@ void SpirvVertexAttributeAliasingTransformer::declareExpandedMatrixVectors() // Op*AccessChain instructions, if any). for (size_t n = 1; n < mFloatTypes.size(); ++n) { - if (mFloatTypes[n] != 0 && mPrivateFloatTypePointers[n] == 0) + if (mFloatTypes[n].valid() && mPrivateFloatTypePointers[n] == 0) { - const uint32_t privateType = getNewId(); + const spirv::IdRef privateType(getNewId()); mPrivateFloatTypePointers[n] = privateType; - writeTypePointer(privateType, spv::StorageClassPrivate, mFloatTypes[n]); + spirv::WriteTypePointer(mSpirvBlobOut, privateType, spv::StorageClassPrivate, + mFloatTypes[n]); } } } void SpirvVertexAttributeAliasingTransformer::writeExpandedMatrixInitialization() { - // SPIR-V 1.0 Section 3.32 Instructions, OpLoad - constexpr size_t kLoadInstructionLength = 4; - - // A fake OpLoad instruction for transformLoadHelper to copy off of. - std::array loadInstruction = {}; - SetSpirvInstructionOp(loadInstruction.data(), spv::OpLoad); - SetSpirvInstructionLength(loadInstruction.data(), kLoadInstructionLength); - // Go through matrix attributes and initialize them. Note that their declaration is replaced // with a Private storage class, but otherwise has the same id. - for (size_t matrixId = 0; matrixId < mExpandedMatrixFirstVectorIdById.size(); ++matrixId) + for (uint32_t matrixIdIndex = 0; matrixIdIndex < mExpandedMatrixFirstVectorIdById.size(); + ++matrixIdIndex) { - uint32_t vec0Id = mExpandedMatrixFirstVectorIdById[matrixId]; - if (vec0Id == 0) + const spirv::IdRef matrixId(matrixIdIndex); + const spirv::IdRef vec0Id(mExpandedMatrixFirstVectorIdById[matrixId]); + if (!vec0Id.valid()) { continue; } @@ -4115,14 +3517,14 @@ void SpirvVertexAttributeAliasingTransformer::writeExpandedMatrixInitialization( const ShaderInterfaceVariableInfo *info = mVariableInfoById[matrixId]; ValidateShaderInterfaceVariableIsAttribute(info); - angle::FixedVector vecLoadIds; + spirv::IdRefList vecLoadIds; const uint32_t locationCount = info->attributeLocationCount; for (uint32_t offset = 0; offset < locationCount; ++offset) { - uint32_t vecId = vec0Id + offset; + const spirv::IdRef vecId(vec0Id + offset); // Load into temporary, potentially through an aliasing vector. - uint32_t replacementId = vecId; + spirv::IdRef replacementId(vecId); ASSERT(vecId < mIsAliasingAttributeById.size()); if (mIsAliasingAttributeById[vecId]) { @@ -4131,18 +3533,18 @@ void SpirvVertexAttributeAliasingTransformer::writeExpandedMatrixInitialization( // Write a load instruction from the replacement id. vecLoadIds.push_back(getNewId()); - transformLoadHelper(loadInstruction.data(), kLoadInstructionLength, matrixId, - mFloatTypes[info->attributeComponentCount], replacementId, + transformLoadHelper(matrixId, mFloatTypes[info->attributeComponentCount], replacementId, vecLoadIds.back()); } // Aggregate the vector loads into a matrix. - ASSERT(mMatrixTypes[locationCount] != 0); - const uint32_t compositeId = getNewId(); - writeCompositeConstruct(compositeId, mMatrixTypes[locationCount], vecLoadIds); + ASSERT(mMatrixTypes[locationCount].valid()); + const spirv::IdRef compositeId(getNewId()); + spirv::WriteCompositeConstruct(mSpirvBlobOut, mMatrixTypes[locationCount], compositeId, + vecLoadIds); // Store it in the private variable. - writeStore(matrixId, compositeId); + spirv::WriteStore(mSpirvBlobOut, matrixId, compositeId, nullptr); } }