diff --git a/SPIRV/CMakeLists.txt b/SPIRV/CMakeLists.txt index 2f9043b5..c3eda0aa 100644 --- a/SPIRV/CMakeLists.txt +++ b/SPIRV/CMakeLists.txt @@ -4,13 +4,17 @@ include_directories(.. ${CMAKE_CURRENT_BINARY_DIR}) set(SOURCES GlslangToSpv.cpp - SpvBuilder.cpp) + SpvBuilder.cpp + doc.cpp + disassemble.cpp) set(HEADERS spirv.h GlslangToSpv.h SpvBuilder.h - spvIR.h) + spvIR.h + doc.h + disassemble.h) add_library(SPIRV STATIC ${SOURCES} ${HEADERS}) diff --git a/SPIRV/disassemble.cpp b/SPIRV/disassemble.cpp new file mode 100644 index 00000000..ebc17f2a --- /dev/null +++ b/SPIRV/disassemble.cpp @@ -0,0 +1,485 @@ +// +//Copyright (C) 2014 LunarG, Inc. +// +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTAstreamITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIAstreamITY, WHETHER IN CONTRACT, STRICT +//LIAstreamITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIstreamITY OF SUCH DAMAGE. + +// +// Author: John Kessenich, LunarG +// + +// +// Disassembler for SPIR-V. +// + +#include +#include +#include +#include + +#include "GLSL450Lib.h" +extern const char* GlslStd450DebugNames[GLSL_STD_450::Count]; + +#include "disassemble.h" +#include "doc.h" + +namespace spv { + +void Kill(std::ostream& out, const char* message) +{ + out << std::endl << "Disassembly failed: " << message << std::endl; + exit(1); +} + +// Container class for a single instance of a SPIR-V stream, with methods for disassembly. +class SpirvStream { +public: + SpirvStream(std::ostream& out, const std::vector& stream) : out(out), stream(stream), word(0), nextNestedControl(0) { } + virtual ~SpirvStream() { } + + void validate(); + void processInstructions(); + +protected: + OpCode getOpCode(int id) const { return idInstruction[id] ? (OpCode)(stream[idInstruction[id]] & OpCodeMask) : OpNop; } + + // Output methods + void outputIndent(); + void formatId(Id id, std::stringstream&); + void outputResultId(Id id); + void outputTypeId(Id id); + void outputId(Id id); + void disassembleImmediates(int numOperands); + void disassembleIds(int numOperands); + void disassembleString(); + void disassembleInstruction(Id resultId, Id typeId, OpCode opCode, int numOperands); + + // Data + std::ostream& out; // where to write the disassembly + const std::vector& stream; // the actual word stream + int size; // the size of the word stream + int word; // the next word of the stream to read + + // map each to the instruction that created it + Id bound; + std::vector idInstruction; // the word offset into the stream where the instruction for result [id] starts; 0 if not yet seen (forward reference or function parameter) + + std::vector idDescriptor; // the best text string known for explaining the + + // schema + unsigned int schema; + + // stack of structured-merge points + std::stack nestedControl; + Id nextNestedControl; // need a slight delay for when we are nested +}; + +void SpirvStream::validate() +{ + size = (int)stream.size(); + if (size < 4) + Kill(out, "stream is too short"); + + // Magic number + if (stream[word++] != MagicNumber) { + out << "Bad magic number"; + return; + } + + // Version + out << "// Module Version " << stream[word++] << std::endl; + + // Generator's magic number + out << "// Generated by (magic number): " << std::setbase(16) << stream[word++] << std::setbase(10) << std::endl; + + // Result bound + bound = stream[word++]; + idInstruction.resize(bound); + idDescriptor.resize(bound); + out << "// Id's are bound by " << bound << std::endl; + out << std::endl; + + // Reserved schema, must be 0 for now + schema = stream[word++]; + if (schema != 0) + Kill(out, "bad schema, must be 0"); +} + +// Loop over all the instructions, in order, processing each. +// Boiler plate for each is handled here directly, the rest is dispatched. +void SpirvStream::processInstructions() +{ + // Instructions + while (word < size) { + int instructionStart = word; + + // Instruction wordCount and opcode + unsigned int firstWord = stream[word]; + unsigned wordCount = firstWord >> WordCountShift; + OpCode opCode = (OpCode)(firstWord & OpCodeMask); + int nextInst = word + wordCount; + ++word; + + // Presence of full instruction + if (nextInst > size) + Kill(out, "stream instruction terminated too early"); + + // Base for computing number of operands; will be updated as more is learned + unsigned numOperands = wordCount - 1; + + // Type + Id typeId = 0; + if (InstructionDesc[opCode].hasType()) { + typeId = stream[word++]; + --numOperands; + } + + // Result + Id resultId = 0; + if (InstructionDesc[opCode].hasResult()) { + resultId = stream[word++]; + --numOperands; + + // save instruction for future reference + idInstruction[resultId] = instructionStart; + } + + outputResultId(resultId); + outputTypeId(typeId); + outputIndent(); + + // Hand off the OpCode and all its operands + disassembleInstruction(resultId, typeId, opCode, numOperands); + if (word != nextInst) { + out << " ERROR, incorrect number of operands consumed. At " << word << " instead of " << nextInst << " instruction start was " << instructionStart; + word = nextInst; + } + out << std::endl; + } +} + +void SpirvStream::outputIndent() +{ + for (int i = 0; i < (int)nestedControl.size(); ++i) + out << " "; +} + +void SpirvStream::formatId(Id id, std::stringstream& idStream) +{ + if (id >= bound) + Kill(out, "Bad "); + + if (id != 0) { + idStream << id; + if (idDescriptor[id].size() > 0) + idStream << "(" << idDescriptor[id] << ")"; + } +} + +void SpirvStream::outputResultId(Id id) +{ + const int width = 16; + std::stringstream idStream; + formatId(id, idStream); + out << std::setw(width) << std::right << idStream.str(); + if (id != 0) + out << ":"; + else + out << " "; + + if (nestedControl.size() && id == nestedControl.top()) + nestedControl.pop(); +} + +void SpirvStream::outputTypeId(Id id) +{ + const int width = 12; + std::stringstream idStream; + formatId(id, idStream); + out << std::setw(width) << std::right << idStream.str() << " "; +} + +void SpirvStream::outputId(Id id) +{ + if (id >= bound) + Kill(out, "Bad "); + + out << id; + if (idDescriptor[id].size() > 0) + out << "(" << idDescriptor[id] << ")"; +} + +void SpirvStream::disassembleImmediates(int numOperands) +{ + for (int i = 0; i < numOperands; ++i) { + out << stream[word++]; + if (i < numOperands - 1) + out << " "; + } +} + +void SpirvStream::disassembleIds(int numOperands) +{ + for (int i = 0; i < numOperands; ++i) { + outputId(stream[word++]); + if (i < numOperands - 1) + out << " "; + } +} + +void SpirvStream::disassembleString() +{ + out << " \""; + + char* wordString; + bool done = false; + do { + unsigned int content = stream[word]; + wordString = (char*)&content; + for (int charCount = 0; charCount < 4; ++charCount) { + if (*wordString == 0) { + done = true; + break; + } + out << *(wordString++); + } + ++word; + } while (! done); + + out << "\""; +} + +void SpirvStream::disassembleInstruction(Id resultId, Id typeId, OpCode opCode, int numOperands) +{ + // Process the opcode + + if (opCode < 0 || opCode >= OpCount) + Kill(out, "Bad opcode"); + else + out << InstructionDesc[opCode].opName + 2; // Skip the "Op" + + if (opCode == OpLoopMerge || opCode == OpSelectionMerge) + nextNestedControl = stream[word]; + else if (opCode == OpBranchConditional || opCode == OpSwitch) { + if (nextNestedControl) { + nestedControl.push(nextNestedControl); + nextNestedControl = 0; + } + } else if (opCode == OpExtInstImport) + idDescriptor[resultId] = (char*)(&stream[word]); + else { + if (idDescriptor[resultId].size() == 0) { + switch (opCode) { + case OpTypeInt: + idDescriptor[resultId] = "int"; + break; + case OpTypeFloat: + idDescriptor[resultId] = "float"; + break; + case OpTypeBool: + idDescriptor[resultId] = "bool"; + break; + case OpTypeStruct: + idDescriptor[resultId] = "struct"; + break; + case OpTypePointer: + idDescriptor[resultId] = "ptr"; + break; + case OpTypeVector: + if (idDescriptor[stream[word]].size() > 0) + idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 1); + idDescriptor[resultId].append("vec"); + switch (stream[word + 1]) { + case 2: idDescriptor[resultId].append("2"); break; + case 3: idDescriptor[resultId].append("3"); break; + case 4: idDescriptor[resultId].append("4"); break; + case 8: idDescriptor[resultId].append("8"); break; + case 16: idDescriptor[resultId].append("16"); break; + case 32: idDescriptor[resultId].append("32"); break; + default: break; + } + break; + default: + break; + } + } + } + + // Process the operands. Note, a new context-dependent set could be + // swapped in mid-traversal. + + // Handle textures specially, so can put out helpful strings. + if (opCode == OpTypeSampler) { + disassembleIds(1); + out << " " << DimensionString((Dimensionality)stream[word++]); + switch (stream[word++]) { + case 0: out << " texture"; break; + case 1: out << " image"; break; + case 2: out << " filter+texture"; break; + } + out << (stream[word++] != 0 ? " array" : ""); + out << (stream[word++] != 0 ? " depth" : ""); + out << (stream[word++] != 0 ? " multi-sampled" : ""); + return; + } + + // Handle all the parameterized operands + for (int op = 0; op < InstructionDesc[opCode].operands.getNum(); ++op) { + out << " "; + switch (InstructionDesc[opCode].operands.getClass(op)) { + case OperandId: + disassembleIds(1); + // Get names for printing "(XXX)" for readability, *after* this id + if (opCode == OpName) + idDescriptor[stream[word - 1]] = (char*)(&stream[word]); + break; + case OperandOptionalId: + case OperandVariableIds: + disassembleIds(numOperands); + return; + case OperandVariableLiterals: + if (opCode == OpDecorate && stream[word - 1] == DecBuiltIn) { + out << BuiltInString(stream[word++]); + --numOperands; + ++op; + } + disassembleImmediates(numOperands); + return; + case OperandVariableLiteralId: + while (numOperands > 0) { + out << std::endl; + outputResultId(NoResult); + outputTypeId(NoType); + outputIndent(); + out << " case "; + disassembleImmediates(1); + out << ": "; + disassembleIds(1); + numOperands -= 2; + } + return; + case OperandLiteralNumber: + disassembleImmediates(1); + if (opCode == OpExtInst) { + unsigned entrypoint = stream[word - 1]; + if (entrypoint < GLSL_STD_450::Count) + out << "(" << GlslStd450DebugNames[entrypoint] << ")"; + } + break; + case OperandLiteralString: + disassembleString(); + return; + case OperandSource: + out << SourceString((SourceLanguage)stream[word++]); + break; + case OperandExecutionModel: + out << ExecutionModelString((ExecutionModel)stream[word++]); + break; + case OperandAddressing: + out << AddressingString((AddressingModel)stream[word++]); + break; + case OperandMemory: + out << MemoryString((MemoryModel)stream[word++]); + break; + case OperandExecutionMode: + out << ExecutionModeString((ExecutionMode)stream[word++]); + break; + case OperandStorage: + out << StorageClassString((StorageClass)stream[word++]); + break; + case OperandDimensionality: + out << DimensionString((Dimensionality)stream[word++]); + break; + case OperandDecoration: + out << DecorationString((Decoration)stream[word++]); + break; + case OperandBuiltIn: + out << BuiltInString((BuiltIn)stream[word++]); + break; + case OperandSelect: + out << SelectControlString((SelectControl)stream[word++]); + break; + case OperandLoop: + out << LoopControlString((LoopControl)stream[word++]); + break; + case OperandFunction: + { + unsigned int control = stream[word++]; + if (control == 0) + out << FunctionControlString(control); + else { + for (int m = 0; m < FunctionControlCount; ++m) { + if (control & (1 << m)) + out << FunctionControlString(m); + } + } + break; + } + case OperandMemorySemantics: + for (int shift = 0; shift < MemorySemanticsCount; ++shift) { + unsigned lit = (stream[word] & (1 << shift)); + if (lit) + out << MemorySemanticsString(lit) << " "; + } + word++; + break; + case OperandMemoryAccess: + out << MemoryAccessString(stream[word++]); + break; + case OperandExecutionScope: + out << ExecutionScopeString(stream[word++]); + break; + case OperandGroupOperation: + out << GroupOperationString(stream[word++]); + break; + case OperandKernelEnqueueFlags: + out << KernelEnqueueFlagsString(stream[word++]); + break; + case OperandKernelProfilingInfo: + out << KernelProfilingInfoString(stream[word++]); + break; + default: + break; + } + --numOperands; + } + + return; +} + +void Disassemble(std::ostream& out, const std::vector& stream) +{ + SpirvStream SpirvStream(out, stream); + SpirvStream.validate(); + SpirvStream.processInstructions(); +} + +}; // end namespace spv diff --git a/SPIRV/disassemble.h b/SPIRV/disassemble.h new file mode 100644 index 00000000..ca8bbb9c --- /dev/null +++ b/SPIRV/disassemble.h @@ -0,0 +1,56 @@ +// +//Copyright (C) 2014 LunarG, Inc. +// +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. + +// +// Author: John Kessenich, LunarG +// + +// +// Disassembler for SPIR-V. +// + +#pragma once +#ifndef disassembler_H +#define disassembler_H + +#include +#include + +namespace spv { + + void Disassemble(std::ostream& out, const std::vector&); + +}; // end namespace spv + +#endif // disassembler_H diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp new file mode 100644 index 00000000..d6fe37ba --- /dev/null +++ b/SPIRV/doc.cpp @@ -0,0 +1,1469 @@ +// +//Copyright (C) 2014 LunarG, Inc. +// +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. + +// +// Author: John Kessenich, LunarG +// + +// +// Programmatically fill in instruction/operand information. +// + +#include "spirv.h" + +#include "doc.h" + +#include +#include +#include + +#define LINE_BREAK " +\n" +#define GAP " +\n +\n" +#define NOTE GAP "*Note:* " + +namespace spv { + +// The set of objects that hold all the instruction/operand +// parameterization information. +InstructionParameters InstructionDesc[spv::OpCount]; + +// Set up all the parameterizing descriptions of the opcodes, operands, etc. +void Parameterize() +{ + // Exceptions to having a result and a resulting type . + // (Everything is initialized to have both). + + InstructionDesc[OpNop] .setResultAndType(false, false); + InstructionDesc[OpSource] .setResultAndType(false, false); + InstructionDesc[OpSourceExtension].setResultAndType(false, false); + InstructionDesc[OpExtension] .setResultAndType(false, false); + InstructionDesc[OpExtInstImport] .setResultAndType(true, false); + InstructionDesc[OpMemoryModel] .setResultAndType(false, false); + InstructionDesc[OpEntryPoint] .setResultAndType(false, false); + InstructionDesc[OpExecutionMode] .setResultAndType(false, false); + + InstructionDesc[OpTypeVoid] .setResultAndType(true, false); + InstructionDesc[OpTypeBool] .setResultAndType(true, false); + InstructionDesc[OpTypeInt] .setResultAndType(true, false); + InstructionDesc[OpTypeFloat] .setResultAndType(true, false); + InstructionDesc[OpTypeVector] .setResultAndType(true, false); + InstructionDesc[OpTypeMatrix] .setResultAndType(true, false); + InstructionDesc[OpTypeSampler] .setResultAndType(true, false); + InstructionDesc[OpTypeFilter] .setResultAndType(true, false); + InstructionDesc[OpTypeArray] .setResultAndType(true, false); + InstructionDesc[OpTypeRuntimeArray].setResultAndType(true, false); + InstructionDesc[OpTypeStruct] .setResultAndType(true, false); + InstructionDesc[OpTypeOpaque] .setResultAndType(true, false); + InstructionDesc[OpTypePointer] .setResultAndType(true, false); + InstructionDesc[OpTypeFunction] .setResultAndType(true, false); + + InstructionDesc[OpTypeEvent] .setResultAndType(true, false); + InstructionDesc[OpTypeDeviceEvent] .setResultAndType(true, false); + InstructionDesc[OpTypeReserveId] .setResultAndType(true, false); + InstructionDesc[OpTypeQueue] .setResultAndType(true, false); + InstructionDesc[OpTypePipe] .setResultAndType(true, false); + InstructionDesc[OpFunctionEnd] .setResultAndType(false, false); + InstructionDesc[OpStore] .setResultAndType(false, false); + InstructionDesc[OpDecorationGroup] .setResultAndType(true, false); + InstructionDesc[OpDecorate] .setResultAndType(false, false); + InstructionDesc[OpMemberDecorate] .setResultAndType(false, false); + InstructionDesc[OpGroupDecorate] .setResultAndType(false, false); + InstructionDesc[OpGroupMemberDecorate].setResultAndType(false, false); + InstructionDesc[OpName] .setResultAndType(false, false); + InstructionDesc[OpMemberName] .setResultAndType(false, false); + InstructionDesc[OpString] .setResultAndType(true, false); + InstructionDesc[OpLine] .setResultAndType(false, false); + + InstructionDesc[OpCopyMemory] .setResultAndType(false, false); + InstructionDesc[OpCopyMemorySized].setResultAndType(false, false); + + InstructionDesc[OpEmitVertex] .setResultAndType(false, false); + InstructionDesc[OpEndPrimitive] .setResultAndType(false, false); + InstructionDesc[OpEmitStreamVertex] .setResultAndType(false, false); + InstructionDesc[OpEndStreamPrimitive].setResultAndType(false, false); + + InstructionDesc[OpControlBarrier].setResultAndType(false, false); + InstructionDesc[OpMemoryBarrier] .setResultAndType(false, false); + + InstructionDesc[OpAtomicInit].setResultAndType(false, false); + InstructionDesc[OpAtomicStore].setResultAndType(false, false); + + InstructionDesc[OpLoopMerge] .setResultAndType(false, false); + InstructionDesc[OpSelectionMerge] .setResultAndType(false, false); + InstructionDesc[OpLabel] .setResultAndType(true, false); + InstructionDesc[OpBranch] .setResultAndType(false, false); + InstructionDesc[OpBranchConditional].setResultAndType(false, false); + InstructionDesc[OpSwitch] .setResultAndType(false, false); + InstructionDesc[OpKill] .setResultAndType(false, false); + InstructionDesc[OpReturn] .setResultAndType(false, false); + InstructionDesc[OpReturnValue] .setResultAndType(false, false); + InstructionDesc[OpUnreachable] .setResultAndType(false, false); + + InstructionDesc[OpLifetimeStart] .setResultAndType(false, false); + InstructionDesc[OpLifetimeStop] .setResultAndType(false, false); + + InstructionDesc[OpCompileFlag] .setResultAndType(false, false); + InstructionDesc[OpCommitReadPipe] .setResultAndType(false, false); + InstructionDesc[OpCommitWritePipe].setResultAndType(false, false); + InstructionDesc[OpGroupCommitWritePipe].setResultAndType(false, false); + InstructionDesc[OpGroupCommitReadPipe].setResultAndType(false, false); + InstructionDesc[OpCaptureEventProfilingInfo].setResultAndType(false, false); + InstructionDesc[OpSetUserEventStatus].setResultAndType(false, false); + InstructionDesc[OpRetainEvent].setResultAndType(false, false); + InstructionDesc[OpReleaseEvent].setResultAndType(false, false); + + // set name of operator, an initial set of style operands, and the description + + #define SET_OPNAME(index) InstructionDesc[index].opName = #index; + + SET_OPNAME(OpNop); + SET_OPNAME(OpSource); + SET_OPNAME(OpSourceExtension); + SET_OPNAME(OpExtension); + SET_OPNAME(OpExtInstImport); + SET_OPNAME(OpMemoryModel); + SET_OPNAME(OpEntryPoint); + SET_OPNAME(OpExecutionMode); + + SET_OPNAME(OpTypeVoid); + SET_OPNAME(OpTypeInt); + SET_OPNAME(OpTypeBool); + SET_OPNAME(OpTypeFloat); + SET_OPNAME(OpTypeVector); + SET_OPNAME(OpTypeMatrix); + SET_OPNAME(OpTypeSampler); + SET_OPNAME(OpTypeFilter); + SET_OPNAME(OpTypeArray); + SET_OPNAME(OpTypeRuntimeArray); + SET_OPNAME(OpTypeStruct); + SET_OPNAME(OpTypeOpaque); + SET_OPNAME(OpTypePointer); + SET_OPNAME(OpTypeFunction); + + SET_OPNAME(OpTypeEvent); + SET_OPNAME(OpTypeDeviceEvent); + SET_OPNAME(OpTypeReserveId); + SET_OPNAME(OpTypeQueue); + SET_OPNAME(OpTypePipe); + + SET_OPNAME(OpConstantTrue); + SET_OPNAME(OpConstantFalse); + SET_OPNAME(OpConstant); + SET_OPNAME(OpConstantComposite); + SET_OPNAME(OpConstantNullPointer); + SET_OPNAME(OpConstantNullObject); + SET_OPNAME(OpConstantSampler); + + SET_OPNAME(OpSpecConstantTrue); + SET_OPNAME(OpSpecConstantFalse); + SET_OPNAME(OpSpecConstant); + SET_OPNAME(OpSpecConstantComposite); + + SET_OPNAME(OpVariable); + SET_OPNAME(OpVariableArray); + + SET_OPNAME(OpFunction); + SET_OPNAME(OpFunctionParameter); + SET_OPNAME(OpFunctionEnd); + SET_OPNAME(OpFunctionCall); + + SET_OPNAME(OpExtInst); + + SET_OPNAME(OpUndef); + SET_OPNAME(OpLoad); + SET_OPNAME(OpStore); + SET_OPNAME(OpPhi); + + SET_OPNAME(OpDecorationGroup); + SET_OPNAME(OpDecorate); + SET_OPNAME(OpMemberDecorate); + SET_OPNAME(OpGroupDecorate); + SET_OPNAME(OpGroupMemberDecorate); + SET_OPNAME(OpName); + SET_OPNAME(OpMemberName); + SET_OPNAME(OpString); + SET_OPNAME(OpLine); + + SET_OPNAME(OpVectorExtractDynamic); + SET_OPNAME(OpVectorInsertDynamic); + SET_OPNAME(OpVectorShuffle); + + SET_OPNAME(OpCompositeConstruct); + SET_OPNAME(OpCompositeExtract); + SET_OPNAME(OpCompositeInsert); + + SET_OPNAME(OpCopyObject); + SET_OPNAME(OpCopyMemory); + SET_OPNAME(OpCopyMemorySized); + + SET_OPNAME(OpSampler); + + SET_OPNAME(OpTextureSample); + SET_OPNAME(OpTextureSampleDref); + SET_OPNAME(OpTextureSampleLod); + SET_OPNAME(OpTextureSampleProj); + SET_OPNAME(OpTextureSampleGrad); + SET_OPNAME(OpTextureSampleOffset); + SET_OPNAME(OpTextureSampleProjLod); + SET_OPNAME(OpTextureSampleProjGrad); + SET_OPNAME(OpTextureSampleLodOffset); + SET_OPNAME(OpTextureSampleProjOffset); + SET_OPNAME(OpTextureSampleGradOffset); + SET_OPNAME(OpTextureSampleProjLodOffset); + SET_OPNAME(OpTextureSampleProjGradOffset); + SET_OPNAME(OpTextureFetchTexel); + SET_OPNAME(OpTextureFetchTexelOffset); + SET_OPNAME(OpTextureFetchSample); + SET_OPNAME(OpTextureFetchBuffer); + SET_OPNAME(OpTextureGather); + SET_OPNAME(OpTextureGatherOffset); + SET_OPNAME(OpTextureGatherOffsets); + SET_OPNAME(OpTextureQuerySizeLod); + SET_OPNAME(OpTextureQuerySize); + SET_OPNAME(OpTextureQueryLod); + SET_OPNAME(OpTextureQueryLevels); + SET_OPNAME(OpTextureQuerySamples); + + SET_OPNAME(OpAccessChain); + SET_OPNAME(OpInBoundsAccessChain); + + SET_OPNAME(OpSNegate); + SET_OPNAME(OpFNegate); + SET_OPNAME(OpNot); + SET_OPNAME(OpAny); + SET_OPNAME(OpAll); + + SET_OPNAME(OpConvertFToU); + SET_OPNAME(OpConvertFToS); + SET_OPNAME(OpConvertSToF); + SET_OPNAME(OpConvertUToF); + SET_OPNAME(OpFConvert); + SET_OPNAME(OpSConvert); + SET_OPNAME(OpUConvert); + SET_OPNAME(OpConvertPtrToU); + SET_OPNAME(OpConvertUToPtr); + SET_OPNAME(OpPtrCastToGeneric); + SET_OPNAME(OpGenericCastToPtr); + SET_OPNAME(OpGenericCastToPtrExplicit); + SET_OPNAME(OpGenericPtrMemSemantics); + SET_OPNAME(OpBitcast); + SET_OPNAME(OpTranspose); + + SET_OPNAME(OpIsNan); + SET_OPNAME(OpIsInf); + SET_OPNAME(OpIsFinite); + SET_OPNAME(OpIsNormal); + SET_OPNAME(OpSignBitSet); + SET_OPNAME(OpLessOrGreater); + SET_OPNAME(OpOrdered); + SET_OPNAME(OpUnordered); + + SET_OPNAME(OpArrayLength); + + SET_OPNAME(OpIAdd); + SET_OPNAME(OpFAdd); + SET_OPNAME(OpISub); + SET_OPNAME(OpFSub); + SET_OPNAME(OpIMul); + SET_OPNAME(OpFMul); + SET_OPNAME(OpUDiv); + SET_OPNAME(OpSDiv); + SET_OPNAME(OpFDiv); + SET_OPNAME(OpUMod); + SET_OPNAME(OpSRem); + SET_OPNAME(OpSMod); + SET_OPNAME(OpFRem); + SET_OPNAME(OpFMod); + + SET_OPNAME(OpVectorTimesScalar); + SET_OPNAME(OpMatrixTimesScalar); + SET_OPNAME(OpVectorTimesMatrix); + SET_OPNAME(OpMatrixTimesVector); + SET_OPNAME(OpMatrixTimesMatrix); + SET_OPNAME(OpOuterProduct); + SET_OPNAME(OpDot); + + SET_OPNAME(OpShiftRightLogical); + SET_OPNAME(OpShiftRightArithmetic); + SET_OPNAME(OpShiftLeftLogical); + SET_OPNAME(OpLogicalOr); + SET_OPNAME(OpLogicalXor); + SET_OPNAME(OpLogicalAnd); + + SET_OPNAME(OpBitwiseOr); + SET_OPNAME(OpBitwiseXor); + SET_OPNAME(OpBitwiseAnd); + + SET_OPNAME(OpSelect); + + SET_OPNAME(OpIEqual); + SET_OPNAME(OpFOrdEqual); + SET_OPNAME(OpFUnordEqual); + SET_OPNAME(OpINotEqual); + SET_OPNAME(OpFOrdNotEqual); + SET_OPNAME(OpFUnordNotEqual); + SET_OPNAME(OpULessThan); + SET_OPNAME(OpSLessThan); + SET_OPNAME(OpFOrdLessThan); + SET_OPNAME(OpFUnordLessThan); + SET_OPNAME(OpUGreaterThan); + SET_OPNAME(OpSGreaterThan); + SET_OPNAME(OpFOrdGreaterThan); + SET_OPNAME(OpFUnordGreaterThan); + SET_OPNAME(OpULessThanEqual); + SET_OPNAME(OpSLessThanEqual); + SET_OPNAME(OpFOrdLessThanEqual); + SET_OPNAME(OpFUnordLessThanEqual); + SET_OPNAME(OpUGreaterThanEqual); + SET_OPNAME(OpSGreaterThanEqual); + SET_OPNAME(OpFOrdGreaterThanEqual); + SET_OPNAME(OpFUnordGreaterThanEqual); + + SET_OPNAME(OpDPdx); + SET_OPNAME(OpDPdy); + SET_OPNAME(OpFwidth); + SET_OPNAME(OpDPdxFine); + SET_OPNAME(OpDPdyFine); + SET_OPNAME(OpFwidthFine); + SET_OPNAME(OpDPdxCoarse); + SET_OPNAME(OpDPdyCoarse); + SET_OPNAME(OpFwidthCoarse); + SET_OPNAME(OpEmitVertex); + SET_OPNAME(OpEndPrimitive); + SET_OPNAME(OpEmitStreamVertex); + SET_OPNAME(OpEndStreamPrimitive); + SET_OPNAME(OpControlBarrier); + SET_OPNAME(OpMemoryBarrier); + + SET_OPNAME(OpImagePointer); + + SET_OPNAME(OpAtomicInit); + SET_OPNAME(OpAtomicLoad); + SET_OPNAME(OpAtomicStore); + SET_OPNAME(OpAtomicExchange); + SET_OPNAME(OpAtomicCompareExchange); + SET_OPNAME(OpAtomicCompareExchangeWeak); + SET_OPNAME(OpAtomicIIncrement); + SET_OPNAME(OpAtomicIDecrement); + SET_OPNAME(OpAtomicIAdd); + SET_OPNAME(OpAtomicISub); + SET_OPNAME(OpAtomicUMin); + SET_OPNAME(OpAtomicUMax); + SET_OPNAME(OpAtomicAnd); + SET_OPNAME(OpAtomicOr); + SET_OPNAME(OpAtomicXor); + + SET_OPNAME(OpLoopMerge); + SET_OPNAME(OpSelectionMerge); + SET_OPNAME(OpLabel); + SET_OPNAME(OpBranch); + SET_OPNAME(OpBranchConditional); + SET_OPNAME(OpSwitch); + SET_OPNAME(OpKill); + SET_OPNAME(OpReturn); + SET_OPNAME(OpReturnValue); + SET_OPNAME(OpUnreachable); + + SET_OPNAME(OpLifetimeStart); + SET_OPNAME(OpLifetimeStop); + SET_OPNAME(OpCompileFlag); + + SET_OPNAME(OpAsyncGroupCopy); + SET_OPNAME(OpWaitGroupEvents); + + SET_OPNAME(OpGroupAll); + SET_OPNAME(OpGroupAny); + SET_OPNAME(OpGroupBroadcast); + SET_OPNAME(OpGroupIAdd); + SET_OPNAME(OpGroupFAdd); + SET_OPNAME(OpGroupFMin); + SET_OPNAME(OpGroupUMin); + SET_OPNAME(OpGroupSMin); + SET_OPNAME(OpGroupFMax); + SET_OPNAME(OpGroupUMax); + SET_OPNAME(OpGroupSMax); + + SET_OPNAME(OpReadPipe); + SET_OPNAME(OpWritePipe); + SET_OPNAME(OpReservedReadPipe); + SET_OPNAME(OpReservedWritePipe); + SET_OPNAME(OpReserveReadPipePackets); + SET_OPNAME(OpReserveWritePipePackets); + SET_OPNAME(OpCommitReadPipe); + SET_OPNAME(OpCommitWritePipe); + SET_OPNAME(OpIsValidReserveId); + SET_OPNAME(OpGetNumPipePackets); + SET_OPNAME(OpGetMaxPipePackets); + SET_OPNAME(OpGroupReserveReadPipePackets); + SET_OPNAME(OpGroupReserveWritePipePackets); + SET_OPNAME(OpGroupCommitReadPipe); + SET_OPNAME(OpGroupCommitWritePipe); + + // Device-side enqueueing of kernels + SET_OPNAME(OpBuildNDRange); + SET_OPNAME(OpGetDefaultQueue); + SET_OPNAME(OpCaptureEventProfilingInfo); + SET_OPNAME(OpSetUserEventStatus); + SET_OPNAME(OpIsValidEvent); + SET_OPNAME(OpCreateUserEvent); + SET_OPNAME(OpRetainEvent); + SET_OPNAME(OpReleaseEvent); + SET_OPNAME(OpGetKernelWorkGroupSize); + SET_OPNAME(OpGetKernelPreferredWorkGroupSizeMultiple); + SET_OPNAME(OpGetKernelNDrangeMaxSubGroupSize); + SET_OPNAME(OpGetKernelNDrangeSubGroupCount); + SET_OPNAME(OpEnqueueKernel); + SET_OPNAME(OpEnqueueMarker); + + InstructionDesc[OpSource].operands.push(OperandSource); + InstructionDesc[OpSource].operands.push(OperandLiteralNumber); + InstructionDesc[OpSourceExtension].operands.push(OperandLiteralString); + InstructionDesc[OpName].operands.push(OperandId); + InstructionDesc[OpName].operands.push(OperandLiteralString); + InstructionDesc[OpMemberName].operands.push(OperandId); + InstructionDesc[OpMemberName].operands.push(OperandLiteralNumber); + InstructionDesc[OpMemberName].operands.push(OperandLiteralString); + InstructionDesc[OpString].operands.push(OperandLiteralString); + InstructionDesc[OpLine].operands.push(OperandId); + InstructionDesc[OpLine].operands.push(OperandId); + InstructionDesc[OpLine].operands.push(OperandLiteralNumber); + InstructionDesc[OpLine].operands.push(OperandLiteralNumber); + InstructionDesc[OpExtension].operands.push(OperandLiteralString); + InstructionDesc[OpExtInstImport].operands.push(OperandLiteralString); + InstructionDesc[OpMemoryModel].operands.push(OperandAddressing); + InstructionDesc[OpMemoryModel].operands.push(OperandMemory); + InstructionDesc[OpEntryPoint].operands.push(OperandExecutionModel); + InstructionDesc[OpEntryPoint].operands.push(OperandId); + InstructionDesc[OpExecutionMode].operands.push(OperandId); + InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode); + InstructionDesc[OpExecutionMode].operands.push(OperandVariableLiterals); + InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber); + InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber); + InstructionDesc[OpTypeFloat].operands.push(OperandLiteralNumber); + InstructionDesc[OpTypeVector].operands.push(OperandId); + InstructionDesc[OpTypeVector].operands.push(OperandLiteralNumber); + InstructionDesc[OpTypeMatrix].operands.push(OperandId); + InstructionDesc[OpTypeMatrix].operands.push(OperandLiteralNumber); + InstructionDesc[OpTypeSampler].operands.push(OperandId); + InstructionDesc[OpTypeSampler].operands.push(OperandDimensionality); + InstructionDesc[OpTypeSampler].operands.push(OperandLiteralNumber); + InstructionDesc[OpTypeSampler].operands.push(OperandLiteralNumber); + InstructionDesc[OpTypeSampler].operands.push(OperandLiteralNumber); + InstructionDesc[OpTypeSampler].operands.push(OperandLiteralNumber); + InstructionDesc[OpTypeSampler].operands.push(OperandOptionalId); + InstructionDesc[OpTypeArray].operands.push(OperandId); + InstructionDesc[OpTypeArray].operands.push(OperandId); + InstructionDesc[OpTypeRuntimeArray].operands.push(OperandId); + InstructionDesc[OpTypeStruct].operands.push(OperandVariableIds); + InstructionDesc[OpTypeOpaque].operands.push(OperandLiteralString); + InstructionDesc[OpTypePointer].operands.push(OperandStorage); + InstructionDesc[OpTypePointer].operands.push(OperandId); + InstructionDesc[OpTypePipe].operands.push(OperandId); + InstructionDesc[OpTypePipe].operands.push(OperandAccessQualifier); + InstructionDesc[OpTypeFunction].operands.push(OperandId); + InstructionDesc[OpTypeFunction].operands.push(OperandVariableIds); + InstructionDesc[OpConstant].operands.push(OperandVariableLiterals); + InstructionDesc[OpConstantComposite].operands.push(OperandVariableIds); + InstructionDesc[OpConstantSampler].operands.push(OperandLiteralNumber); + InstructionDesc[OpConstantSampler].operands.push(OperandLiteralNumber); + InstructionDesc[OpConstantSampler].operands.push(OperandLiteralNumber); + InstructionDesc[OpSpecConstant].operands.push(OperandVariableLiterals); + InstructionDesc[OpSpecConstantComposite].operands.push(OperandVariableIds); + InstructionDesc[OpVariable].operands.push(OperandStorage); + InstructionDesc[OpVariable].operands.push(OperandOptionalId); + InstructionDesc[OpVariableArray].operands.push(OperandStorage); + InstructionDesc[OpVariableArray].operands.push(OperandId); + InstructionDesc[OpFunction].operands.push(OperandFunction); + InstructionDesc[OpFunction].operands.push(OperandId); + InstructionDesc[OpFunctionCall].operands.push(OperandId); + InstructionDesc[OpFunctionCall].operands.push(OperandVariableIds); + InstructionDesc[OpExtInst].operands.push(OperandId); + InstructionDesc[OpExtInst].operands.push(OperandLiteralNumber); + InstructionDesc[OpExtInst].operands.push(OperandVariableIds); + InstructionDesc[OpLoad].operands.push(OperandId); + InstructionDesc[OpLoad].operands.push(OperandVariableLiterals); + InstructionDesc[OpStore].operands.push(OperandId); + InstructionDesc[OpStore].operands.push(OperandId); + InstructionDesc[OpStore].operands.push(OperandVariableLiterals); + InstructionDesc[OpPhi].operands.push(OperandVariableIds); + InstructionDesc[OpDecorate].operands.push(OperandId); + InstructionDesc[OpDecorate].operands.push(OperandDecoration); + InstructionDesc[OpDecorate].operands.push(OperandVariableLiterals); + InstructionDesc[OpMemberDecorate].operands.push(OperandId); + InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber); + InstructionDesc[OpMemberDecorate].operands.push(OperandDecoration); + InstructionDesc[OpMemberDecorate].operands.push(OperandVariableLiterals); + InstructionDesc[OpGroupDecorate].operands.push(OperandId); + InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds); + InstructionDesc[OpGroupMemberDecorate].operands.push(OperandId); + InstructionDesc[OpGroupMemberDecorate].operands.push(OperandVariableIds); + InstructionDesc[OpVectorExtractDynamic].operands.push(OperandId); + InstructionDesc[OpVectorExtractDynamic].operands.push(OperandId); + InstructionDesc[OpVectorInsertDynamic].operands.push(OperandId); + InstructionDesc[OpVectorInsertDynamic].operands.push(OperandId); + InstructionDesc[OpVectorInsertDynamic].operands.push(OperandId); + InstructionDesc[OpVectorShuffle].operands.push(OperandId); + InstructionDesc[OpVectorShuffle].operands.push(OperandId); + InstructionDesc[OpVectorShuffle].operands.push(OperandVariableLiterals); + InstructionDesc[OpCompositeConstruct].operands.push(OperandVariableIds); + InstructionDesc[OpCompositeExtract].operands.push(OperandId); + InstructionDesc[OpCompositeExtract].operands.push(OperandVariableLiterals); + InstructionDesc[OpCompositeInsert].operands.push(OperandId); + InstructionDesc[OpCompositeInsert].operands.push(OperandId); + InstructionDesc[OpCompositeInsert].operands.push(OperandVariableLiterals); + InstructionDesc[OpCopyObject].operands.push(OperandId); + InstructionDesc[OpCopyMemory].operands.push(OperandId); + InstructionDesc[OpCopyMemory].operands.push(OperandId); + InstructionDesc[OpCopyMemory].operands.push(OperandVariableLiterals); + InstructionDesc[OpCopyMemorySized].operands.push(OperandId); + InstructionDesc[OpCopyMemorySized].operands.push(OperandId); + InstructionDesc[OpCopyMemorySized].operands.push(OperandId); + InstructionDesc[OpCopyMemorySized].operands.push(OperandVariableLiterals); + InstructionDesc[OpSampler].operands.push(OperandId); + InstructionDesc[OpSampler].operands.push(OperandId); + InstructionDesc[OpTextureSample].operands.push(OperandId); + InstructionDesc[OpTextureSample].operands.push(OperandId); + InstructionDesc[OpTextureSample].operands.push(OperandOptionalId); + InstructionDesc[OpTextureSampleDref].operands.push(OperandId); + InstructionDesc[OpTextureSampleDref].operands.push(OperandId); + InstructionDesc[OpTextureSampleDref].operands.push(OperandId); + InstructionDesc[OpTextureSampleLod].operands.push(OperandId); + InstructionDesc[OpTextureSampleLod].operands.push(OperandId); + InstructionDesc[OpTextureSampleLod].operands.push(OperandId); + InstructionDesc[OpTextureSampleProj].operands.push(OperandId); + InstructionDesc[OpTextureSampleProj].operands.push(OperandId); + InstructionDesc[OpTextureSampleProj].operands.push(OperandOptionalId); + InstructionDesc[OpTextureSampleGrad].operands.push(OperandId); + InstructionDesc[OpTextureSampleGrad].operands.push(OperandId); + InstructionDesc[OpTextureSampleGrad].operands.push(OperandId); + InstructionDesc[OpTextureSampleGrad].operands.push(OperandId); + InstructionDesc[OpTextureSampleOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleOffset].operands.push(OperandOptionalId); + InstructionDesc[OpTextureSampleProjLod].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjLod].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjLod].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjGrad].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjGrad].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjGrad].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjGrad].operands.push(OperandId); + InstructionDesc[OpTextureSampleLodOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleLodOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleLodOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleLodOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjOffset].operands.push(OperandOptionalId); + InstructionDesc[OpTextureSampleGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjLodOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjLodOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjLodOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjLodOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureSampleProjGradOffset].operands.push(OperandId); + InstructionDesc[OpTextureFetchTexel].operands.push(OperandId); + InstructionDesc[OpTextureFetchTexel].operands.push(OperandId); + InstructionDesc[OpTextureFetchTexel].operands.push(OperandId); + InstructionDesc[OpTextureFetchTexelOffset].operands.push(OperandId); + InstructionDesc[OpTextureFetchTexelOffset].operands.push(OperandId); + InstructionDesc[OpTextureFetchTexelOffset].operands.push(OperandId); + InstructionDesc[OpTextureFetchSample].operands.push(OperandId); + InstructionDesc[OpTextureFetchSample].operands.push(OperandId); + InstructionDesc[OpTextureFetchSample].operands.push(OperandId); + InstructionDesc[OpTextureFetchBuffer].operands.push(OperandId); + InstructionDesc[OpTextureFetchBuffer].operands.push(OperandId); + InstructionDesc[OpTextureGather].operands.push(OperandId); + InstructionDesc[OpTextureGather].operands.push(OperandId); + InstructionDesc[OpTextureGather].operands.push(OperandId); + InstructionDesc[OpTextureGatherOffset].operands.push(OperandId); + InstructionDesc[OpTextureGatherOffset].operands.push(OperandId); + InstructionDesc[OpTextureGatherOffset].operands.push(OperandId); + InstructionDesc[OpTextureGatherOffset].operands.push(OperandId); + InstructionDesc[OpTextureGatherOffsets].operands.push(OperandId); + InstructionDesc[OpTextureGatherOffsets].operands.push(OperandId); + InstructionDesc[OpTextureGatherOffsets].operands.push(OperandId); + InstructionDesc[OpTextureGatherOffsets].operands.push(OperandId); + InstructionDesc[OpTextureQuerySizeLod].operands.push(OperandId); + InstructionDesc[OpTextureQuerySizeLod].operands.push(OperandId); + InstructionDesc[OpTextureQuerySize].operands.push(OperandId); + InstructionDesc[OpTextureQueryLod].operands.push(OperandId); + InstructionDesc[OpTextureQueryLod].operands.push(OperandId); + InstructionDesc[OpTextureQueryLevels].operands.push(OperandId); + InstructionDesc[OpTextureQuerySamples].operands.push(OperandId); + InstructionDesc[OpAccessChain].operands.push(OperandId); + InstructionDesc[OpAccessChain].operands.push(OperandVariableIds); + InstructionDesc[OpInBoundsAccessChain].operands.push(OperandId); + InstructionDesc[OpInBoundsAccessChain].operands.push(OperandVariableIds); + InstructionDesc[OpSNegate].operands.push(OperandId); + InstructionDesc[OpFNegate].operands.push(OperandId); + InstructionDesc[OpNot].operands.push(OperandId); + InstructionDesc[OpAny].operands.push(OperandId); + InstructionDesc[OpAll].operands.push(OperandId); + InstructionDesc[OpConvertFToU].operands.push(OperandId); + InstructionDesc[OpConvertFToS].operands.push(OperandId); + InstructionDesc[OpConvertSToF].operands.push(OperandId); + InstructionDesc[OpConvertUToF].operands.push(OperandId); + InstructionDesc[OpUConvert].operands.push(OperandId); + InstructionDesc[OpSConvert].operands.push(OperandId); + InstructionDesc[OpFConvert].operands.push(OperandId); + InstructionDesc[OpConvertPtrToU].operands.push(OperandId); + InstructionDesc[OpConvertUToPtr].operands.push(OperandId); + InstructionDesc[OpPtrCastToGeneric].operands.push(OperandId); + InstructionDesc[OpGenericCastToPtr].operands.push(OperandId); + InstructionDesc[OpGenericCastToPtrExplicit].operands.push(OperandId); + InstructionDesc[OpGenericCastToPtrExplicit].operands.push(OperandStorage); + InstructionDesc[OpGenericPtrMemSemantics].operands.push(OperandId); + InstructionDesc[OpBitcast].operands.push(OperandId); + InstructionDesc[OpTranspose].operands.push(OperandId); + InstructionDesc[OpIsNan].operands.push(OperandId); + InstructionDesc[OpIsInf].operands.push(OperandId); + InstructionDesc[OpIsFinite].operands.push(OperandId); + InstructionDesc[OpIsNormal].operands.push(OperandId); + InstructionDesc[OpSignBitSet].operands.push(OperandId); + InstructionDesc[OpLessOrGreater].operands.push(OperandId); + InstructionDesc[OpLessOrGreater].operands.push(OperandId); + InstructionDesc[OpOrdered].operands.push(OperandId); + InstructionDesc[OpOrdered].operands.push(OperandId); + InstructionDesc[OpUnordered].operands.push(OperandId); + InstructionDesc[OpUnordered].operands.push(OperandId); + InstructionDesc[OpArrayLength].operands.push(OperandId); + InstructionDesc[OpArrayLength].operands.push(OperandLiteralNumber); + InstructionDesc[OpIAdd].operands.push(OperandId); + InstructionDesc[OpIAdd].operands.push(OperandId); + InstructionDesc[OpFAdd].operands.push(OperandId); + InstructionDesc[OpFAdd].operands.push(OperandId); + InstructionDesc[OpISub].operands.push(OperandId); + InstructionDesc[OpISub].operands.push(OperandId); + InstructionDesc[OpFSub].operands.push(OperandId); + InstructionDesc[OpFSub].operands.push(OperandId); + InstructionDesc[OpIMul].operands.push(OperandId); + InstructionDesc[OpIMul].operands.push(OperandId); + InstructionDesc[OpFMul].operands.push(OperandId); + InstructionDesc[OpFMul].operands.push(OperandId); + InstructionDesc[OpUDiv].operands.push(OperandId); + InstructionDesc[OpUDiv].operands.push(OperandId); + InstructionDesc[OpSDiv].operands.push(OperandId); + InstructionDesc[OpSDiv].operands.push(OperandId); + InstructionDesc[OpFDiv].operands.push(OperandId); + InstructionDesc[OpFDiv].operands.push(OperandId); + InstructionDesc[OpUMod].operands.push(OperandId); + InstructionDesc[OpUMod].operands.push(OperandId); + InstructionDesc[OpSRem].operands.push(OperandId); + InstructionDesc[OpSRem].operands.push(OperandId); + InstructionDesc[OpSMod].operands.push(OperandId); + InstructionDesc[OpSMod].operands.push(OperandId); + InstructionDesc[OpFRem].operands.push(OperandId); + InstructionDesc[OpFRem].operands.push(OperandId); + InstructionDesc[OpFMod].operands.push(OperandId); + InstructionDesc[OpFMod].operands.push(OperandId); + InstructionDesc[OpVectorTimesScalar].operands.push(OperandId); + InstructionDesc[OpVectorTimesScalar].operands.push(OperandId); + InstructionDesc[OpMatrixTimesScalar].operands.push(OperandId); + InstructionDesc[OpMatrixTimesScalar].operands.push(OperandId); + InstructionDesc[OpVectorTimesMatrix].operands.push(OperandId); + InstructionDesc[OpVectorTimesMatrix].operands.push(OperandId); + InstructionDesc[OpMatrixTimesVector].operands.push(OperandId); + InstructionDesc[OpMatrixTimesVector].operands.push(OperandId); + InstructionDesc[OpMatrixTimesMatrix].operands.push(OperandId); + InstructionDesc[OpMatrixTimesMatrix].operands.push(OperandId); + InstructionDesc[OpOuterProduct].operands.push(OperandId); + InstructionDesc[OpOuterProduct].operands.push(OperandId); + InstructionDesc[OpDot].operands.push(OperandId); + InstructionDesc[OpDot].operands.push(OperandId); + InstructionDesc[OpShiftRightLogical].operands.push(OperandId); + InstructionDesc[OpShiftRightLogical].operands.push(OperandId); + InstructionDesc[OpShiftRightArithmetic].operands.push(OperandId); + InstructionDesc[OpShiftRightArithmetic].operands.push(OperandId); + InstructionDesc[OpShiftLeftLogical].operands.push(OperandId); + InstructionDesc[OpShiftLeftLogical].operands.push(OperandId); + InstructionDesc[OpLogicalOr].operands.push(OperandId); + InstructionDesc[OpLogicalOr].operands.push(OperandId); + InstructionDesc[OpLogicalXor].operands.push(OperandId); + InstructionDesc[OpLogicalXor].operands.push(OperandId); + InstructionDesc[OpLogicalAnd].operands.push(OperandId); + InstructionDesc[OpLogicalAnd].operands.push(OperandId); + InstructionDesc[OpBitwiseOr].operands.push(OperandId); + InstructionDesc[OpBitwiseOr].operands.push(OperandId); + InstructionDesc[OpBitwiseXor].operands.push(OperandId); + InstructionDesc[OpBitwiseXor].operands.push(OperandId); + InstructionDesc[OpBitwiseAnd].operands.push(OperandId); + InstructionDesc[OpBitwiseAnd].operands.push(OperandId); + InstructionDesc[OpSelect].operands.push(OperandId); + InstructionDesc[OpSelect].operands.push(OperandId); + InstructionDesc[OpSelect].operands.push(OperandId); + InstructionDesc[OpIEqual].operands.push(OperandId); + InstructionDesc[OpIEqual].operands.push(OperandId); + InstructionDesc[OpFOrdEqual].operands.push(OperandId); + InstructionDesc[OpFOrdEqual].operands.push(OperandId); + InstructionDesc[OpFUnordEqual].operands.push(OperandId); + InstructionDesc[OpFUnordEqual].operands.push(OperandId); + InstructionDesc[OpINotEqual].operands.push(OperandId); + InstructionDesc[OpINotEqual].operands.push(OperandId); + InstructionDesc[OpFOrdNotEqual].operands.push(OperandId); + InstructionDesc[OpFOrdNotEqual].operands.push(OperandId); + InstructionDesc[OpFUnordNotEqual].operands.push(OperandId); + InstructionDesc[OpFUnordNotEqual].operands.push(OperandId); + InstructionDesc[OpULessThan].operands.push(OperandId); + InstructionDesc[OpULessThan].operands.push(OperandId); + InstructionDesc[OpSLessThan].operands.push(OperandId); + InstructionDesc[OpSLessThan].operands.push(OperandId); + InstructionDesc[OpFOrdLessThan].operands.push(OperandId); + InstructionDesc[OpFOrdLessThan].operands.push(OperandId); + InstructionDesc[OpFUnordLessThan].operands.push(OperandId); + InstructionDesc[OpFUnordLessThan].operands.push(OperandId); + InstructionDesc[OpUGreaterThan].operands.push(OperandId); + InstructionDesc[OpUGreaterThan].operands.push(OperandId); + InstructionDesc[OpSGreaterThan].operands.push(OperandId); + InstructionDesc[OpSGreaterThan].operands.push(OperandId); + InstructionDesc[OpFOrdGreaterThan].operands.push(OperandId); + InstructionDesc[OpFOrdGreaterThan].operands.push(OperandId); + InstructionDesc[OpFUnordGreaterThan].operands.push(OperandId); + InstructionDesc[OpFUnordGreaterThan].operands.push(OperandId); + InstructionDesc[OpULessThanEqual].operands.push(OperandId); + InstructionDesc[OpULessThanEqual].operands.push(OperandId); + InstructionDesc[OpSLessThanEqual].operands.push(OperandId); + InstructionDesc[OpSLessThanEqual].operands.push(OperandId); + InstructionDesc[OpFOrdLessThanEqual].operands.push(OperandId); + InstructionDesc[OpFOrdLessThanEqual].operands.push(OperandId); + InstructionDesc[OpFUnordLessThanEqual].operands.push(OperandId); + InstructionDesc[OpFUnordLessThanEqual].operands.push(OperandId); + InstructionDesc[OpUGreaterThanEqual].operands.push(OperandId); + InstructionDesc[OpUGreaterThanEqual].operands.push(OperandId); + InstructionDesc[OpSGreaterThanEqual].operands.push(OperandId); + InstructionDesc[OpSGreaterThanEqual].operands.push(OperandId); + InstructionDesc[OpFOrdGreaterThanEqual].operands.push(OperandId); + InstructionDesc[OpFOrdGreaterThanEqual].operands.push(OperandId); + InstructionDesc[OpFUnordGreaterThanEqual].operands.push(OperandId); + InstructionDesc[OpFUnordGreaterThanEqual].operands.push(OperandId); + InstructionDesc[OpDPdx].operands.push(OperandId); + InstructionDesc[OpDPdy].operands.push(OperandId); + InstructionDesc[OpFwidth].operands.push(OperandId); + InstructionDesc[OpDPdxFine].operands.push(OperandId); + InstructionDesc[OpDPdyFine].operands.push(OperandId); + InstructionDesc[OpFwidthFine].operands.push(OperandId); + InstructionDesc[OpDPdxCoarse].operands.push(OperandId); + InstructionDesc[OpDPdyCoarse].operands.push(OperandId); + InstructionDesc[OpFwidthCoarse].operands.push(OperandId); + InstructionDesc[OpEmitStreamVertex].operands.push(OperandId); + InstructionDesc[OpEndStreamPrimitive].operands.push(OperandId); + InstructionDesc[OpControlBarrier].operands.push(OperandExecutionScope); + InstructionDesc[OpMemoryBarrier].operands.push(OperandExecutionScope); + InstructionDesc[OpMemoryBarrier].operands.push(OperandMemorySemantics); + InstructionDesc[OpImagePointer].operands.push(OperandId); + InstructionDesc[OpImagePointer].operands.push(OperandId); + InstructionDesc[OpImagePointer].operands.push(OperandId); + InstructionDesc[OpAtomicInit].operands.push(OperandId); + InstructionDesc[OpAtomicInit].operands.push(OperandId); + InstructionDesc[OpAtomicLoad].operands.push(OperandId); + InstructionDesc[OpAtomicLoad].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicLoad].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicStore].operands.push(OperandId); + InstructionDesc[OpAtomicStore].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicStore].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicStore].operands.push(OperandId); + InstructionDesc[OpAtomicExchange].operands.push(OperandId); + InstructionDesc[OpAtomicExchange].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicExchange].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicExchange].operands.push(OperandId); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandId); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandId); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandId); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId); + InstructionDesc[OpAtomicIIncrement].operands.push(OperandId); + InstructionDesc[OpAtomicIIncrement].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicIIncrement].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicIDecrement].operands.push(OperandId); + InstructionDesc[OpAtomicIDecrement].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicIDecrement].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicIAdd].operands.push(OperandId); + InstructionDesc[OpAtomicIAdd].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicIAdd].operands.push(OperandId); + InstructionDesc[OpAtomicISub].operands.push(OperandId); + InstructionDesc[OpAtomicISub].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicISub].operands.push(OperandId); + InstructionDesc[OpAtomicUMin].operands.push(OperandId); + InstructionDesc[OpAtomicUMin].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicUMin].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicUMin].operands.push(OperandId); + InstructionDesc[OpAtomicUMax].operands.push(OperandId); + InstructionDesc[OpAtomicUMax].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicUMax].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicUMax].operands.push(OperandId); + InstructionDesc[OpAtomicAnd].operands.push(OperandId); + InstructionDesc[OpAtomicAnd].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicAnd].operands.push(OperandId); + InstructionDesc[OpAtomicOr].operands.push(OperandId); + InstructionDesc[OpAtomicOr].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicOr].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicOr].operands.push(OperandId); + InstructionDesc[OpAtomicXor].operands.push(OperandId); + InstructionDesc[OpAtomicXor].operands.push(OperandExecutionScope); + InstructionDesc[OpAtomicXor].operands.push(OperandMemorySemantics); + InstructionDesc[OpAtomicXor].operands.push(OperandId); + InstructionDesc[OpLoopMerge].operands.push(OperandId); + InstructionDesc[OpLoopMerge].operands.push(OperandLoop); + InstructionDesc[OpSelectionMerge].operands.push(OperandId); + InstructionDesc[OpSelectionMerge].operands.push(OperandSelect); + InstructionDesc[OpBranch].operands.push(OperandId); + InstructionDesc[OpBranchConditional].operands.push(OperandId); + InstructionDesc[OpBranchConditional].operands.push(OperandId); + InstructionDesc[OpBranchConditional].operands.push(OperandId); + InstructionDesc[OpBranchConditional].operands.push(OperandVariableLiterals); + InstructionDesc[OpSwitch].operands.push(OperandId); + InstructionDesc[OpSwitch].operands.push(OperandId); + InstructionDesc[OpSwitch].operands.push(OperandVariableLiteralId); + InstructionDesc[OpReturnValue].operands.push(OperandId); + InstructionDesc[OpLifetimeStart].operands.push(OperandId); + InstructionDesc[OpLifetimeStart].operands.push(OperandLiteralNumber); + InstructionDesc[OpLifetimeStop].operands.push(OperandId); + InstructionDesc[OpLifetimeStop].operands.push(OperandLiteralNumber); + InstructionDesc[OpCompileFlag].operands.push(OperandLiteralString); + InstructionDesc[OpAsyncGroupCopy].operands.push(OperandExecutionScope); + InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId); + InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId); + InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId); + InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId); + InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId); + InstructionDesc[OpWaitGroupEvents].operands.push(OperandExecutionScope); + InstructionDesc[OpWaitGroupEvents].operands.push(OperandId); + InstructionDesc[OpWaitGroupEvents].operands.push(OperandId); + InstructionDesc[OpGroupAll].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupAll].operands.push(OperandId); + InstructionDesc[OpGroupAny].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupAny].operands.push(OperandId); + InstructionDesc[OpGroupBroadcast].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupBroadcast].operands.push(OperandId); + InstructionDesc[OpGroupBroadcast].operands.push(OperandId); + InstructionDesc[OpGroupIAdd].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupIAdd].operands.push(OperandGroupOperation); + InstructionDesc[OpGroupIAdd].operands.push(OperandId); + InstructionDesc[OpGroupFAdd].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupFAdd].operands.push(OperandGroupOperation); + InstructionDesc[OpGroupFAdd].operands.push(OperandId); + InstructionDesc[OpGroupUMin].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupUMin].operands.push(OperandGroupOperation); + InstructionDesc[OpGroupUMin].operands.push(OperandId); + InstructionDesc[OpGroupSMin].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupSMin].operands.push(OperandGroupOperation); + InstructionDesc[OpGroupSMin].operands.push(OperandId); + InstructionDesc[OpGroupFMin].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupFMin].operands.push(OperandGroupOperation); + InstructionDesc[OpGroupFMin].operands.push(OperandId); + InstructionDesc[OpGroupUMax].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupUMax].operands.push(OperandGroupOperation); + InstructionDesc[OpGroupUMax].operands.push(OperandId); + InstructionDesc[OpGroupSMax].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupSMax].operands.push(OperandGroupOperation); + InstructionDesc[OpGroupSMax].operands.push(OperandId); + InstructionDesc[OpGroupFMax].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupFMax].operands.push(OperandGroupOperation); + InstructionDesc[OpGroupFMax].operands.push(OperandId); + InstructionDesc[OpReadPipe].operands.push(OperandId); + InstructionDesc[OpReadPipe].operands.push(OperandId); + InstructionDesc[OpWritePipe].operands.push(OperandId); + InstructionDesc[OpWritePipe].operands.push(OperandId); + InstructionDesc[OpReservedReadPipe].operands.push(OperandId); + InstructionDesc[OpReservedReadPipe].operands.push(OperandId); + InstructionDesc[OpReservedReadPipe].operands.push(OperandId); + InstructionDesc[OpReservedReadPipe].operands.push(OperandId); + InstructionDesc[OpReservedWritePipe].operands.push(OperandId); + InstructionDesc[OpReservedWritePipe].operands.push(OperandId); + InstructionDesc[OpReservedWritePipe].operands.push(OperandId); + InstructionDesc[OpReservedWritePipe].operands.push(OperandId); + InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId); + InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId); + InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId); + InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId); + InstructionDesc[OpCommitReadPipe].operands.push(OperandId); + InstructionDesc[OpCommitReadPipe].operands.push(OperandId); + InstructionDesc[OpCommitWritePipe].operands.push(OperandId); + InstructionDesc[OpCommitWritePipe].operands.push(OperandId); + InstructionDesc[OpIsValidReserveId].operands.push(OperandId); + InstructionDesc[OpGetNumPipePackets].operands.push(OperandId); + InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId); + InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId); + InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId); + InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId); + InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId); + InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId); + InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId); + InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandExecutionScope); + InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId); + InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId); + InstructionDesc[OpBuildNDRange].operands.push(OperandId); + InstructionDesc[OpBuildNDRange].operands.push(OperandId); + InstructionDesc[OpBuildNDRange].operands.push(OperandId); + InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId); + InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandKernelProfilingInfo); + InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId); + InstructionDesc[OpSetUserEventStatus].operands.push(OperandId); + InstructionDesc[OpSetUserEventStatus].operands.push(OperandId); + InstructionDesc[OpIsValidEvent].operands.push(OperandId); + InstructionDesc[OpRetainEvent].operands.push(OperandId); + InstructionDesc[OpReleaseEvent].operands.push(OperandId); + InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId); + InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId); + InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId); + InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId); + InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId); + InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandKernelEnqueueFlags); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId); + InstructionDesc[OpEnqueueKernel].operands.push(OperandVariableIds); + InstructionDesc[OpEnqueueMarker].operands.push(OperandId); + InstructionDesc[OpEnqueueMarker].operands.push(OperandId); + InstructionDesc[OpEnqueueMarker].operands.push(OperandId); + InstructionDesc[OpEnqueueMarker].operands.push(OperandId); +} + +// +// A whole set of functions that translate enums to English. +// + +const char* CapabilityString(int cap) +{ + switch (cap) { + case CapMatrix: return "Matrix"; + case CapShader: return "Shader"; + case CapGeom: return "Geom"; + case CapTess: return "Tess"; + case CapAddr: return "Addr"; + case CapLink: return "Link"; + case CapKernel: return "Kernel"; + + default: return "unknown"; + + } +} + +const char* SourceString(int source) +{ + switch (source) { + case LangESSL: return "ESSL"; + case LangGLSL: return "GLSL"; + case LangOpenCL: return "OpenCL"; + + default: return "unknown"; + } +} + +const char* ExecutionModelString(int model) +{ + switch (model) { + case ModelVertex: return "Vertex"; + case ModelTessellationControl: return "TessellationControl"; + case ModelTessellationEvaluation: return "TessellationEvaluation"; + case ModelGeometry: return "Geometry"; + case ModelFragment: return "Fragment"; + case ModelGLCompute: return "GLCompute"; + case ModelKernel: return "Kernel"; + + default: return "BadModel"; + } +} + +const char* AddressingString(int addr) +{ + switch (addr) { + case AddressingLogical: return "Logical"; + case AddressingPhysical32: return "Physical32"; + case AddressingPhysical64: return "Physical64"; + + default: return "BadAddressModel"; + } +} + +const char* AddressingDesc(int addr) +{ + switch (addr) { + case AddressingLogical: return "No variables that are pointers or other physical pointers. No arithmetic or casting on pointers."; + case AddressingPhysical32: return ""; + case AddressingPhysical64: return ""; + + default: return "BadAddressModel"; + } +} + +const char* MemoryString(int mem) +{ + switch (mem) { + case MemorySimple: return "Simple"; + case MemoryGLSL450: return "GLSL450"; + case MemoryOCL12: return "OpenCL1.2"; + case MemoryOCL20: return "OpenCL2.0"; + case MemoryOCL21: return "OpenCL2.1"; + default: return "BadMemoryModel"; + } +} + +const char* ExecutionModeString(int mode) +{ + switch (mode) { + case ExecutionInvocations: return "Invocations"; + case ExecutionSpacingEqual: return "SpacingEqual"; + case ExecutionSpacingFractionalEven: return "SpacingFractionalEven"; + case ExecutionSpacingFractionalOdd: return "SpacingFractionalOdd"; + case ExecutionVertexOrderCw: return "VertexOrderCw"; + case ExecutionVertexOrderCcw: return "VertexOrderCcw"; + case ExecutionPixelCenterInteger: return "PixelCenterInteger"; + case ExecutionOriginUpperLeft: return "OriginUpperLeft"; + case ExecutionEarlyFragmentTests: return "EarlyFragmentTests"; + case ExecutionPointMode: return "PointMode"; + case ExecutionLocalSize: return "LocalSize"; + case ExecutionLocalSizeHint: return "LocalSizeHint"; + case ExecutionVecTypeHint: return "VecTypeHint"; + case ExecutionContractionOff: return "ContractionOff"; + case ExecutionXfb: return "Xfb"; + case ExecutionDepthReplacing: return "DepthReplacing"; + case ExecutionDepthAny: return "DepthAny"; + case ExecutionDepthGreater: return "DepthGreater"; + case ExecutionDepthLess: return "DepthLess"; + case ExecutionDepthUnchanged: return "DepthUnchanged"; + + case ExecutionInputPoints: return "InputPoints"; + case ExecutionInputLines: return "InputLines"; + case ExecutionInputLinesAdjacency: return "InputLinesAdjacency"; + case ExecutionInputTriangles: return "InputTriangles"; + case ExecutionInputTrianglesAdjacency: return "InputTrianglesAdjacency"; + case ExecutionInputQuads: return "InputQuads"; + case ExecutionInputIsolines: return "InputIsolines"; + + case ExecutionOutputVertices: return "OutputVertices"; + case ExecutionOutputPoints: return "OutputPoints"; + case ExecutionOutputLineStrip: return "OutputLineStrip"; + case ExecutionOutputTriangleStrip: return "OutputTriangleStrip"; + + default: return "BadMode"; + } +} + +const char* StorageClassString(int StorageClass) +{ + switch (StorageClass) { + //case StorageLowertime: return "Lowertime"; // TODO: finish removing when sure they are gone. + case StorageConstantUniform: return "UniformConstant"; + case StorageUniform: return "Uniform"; + case StorageInput: return "Input"; + case StorageOutput: return "Output"; + case StorageWorkgroupLocal: return "WorkgroupLocal"; + case StoragePrivateGlobal: return "PrivateGlobal"; + case StorageWorkgroupGlobal: return "WorkgroupGlobal"; + case StorageFunction: return "Function"; + case StoragePrivate: return "Private"; + case StorageAtomicCounter: return "AtomicCounter"; + case StorageGeneric: return "Generic"; + + default: return 0; + } +} + +const char* DecorationString(int decoration) +{ + switch (decoration) { + case DecPrecisionLow: return "PrecisionLow"; + case DecPrecisionMedium: return "PrecisionMedium"; + case DecPrecisionHigh: return "PrecisionHigh"; + case DecBlock: return "Block"; + case DecBufferBlock: return "BufferBlock"; + case DecRowMajor: return "RowMajor"; + case DecColMajor: return "ColMajor"; + case DecGLSLShared: return "GLSLShared"; + case DecGLSLStd140: return "GLSLStd140"; + case DecGLSLStd430: return "GLSLStd430"; + case DecGLSLPacked: return "GLSLPacked"; + case DecSmooth: return "Smooth"; + case DecNoperspective: return "Noperspective"; + case DecFlat: return "Flat"; + case DecPatch: return "Patch"; + case DecCentroid: return "Centroid"; + case DecSample: return "Sample"; + case DecInvariant: return "Invariant"; + case DecRestrict: return "Restrict"; + case DecAliased: return "Aliased"; + case DecVolatile: return "Volatile"; + case DecConstant: return "Constant"; + case DecCoherent: return "Coherent"; + case DecNonwritable: return "Nonwritable"; + case DecNonreadable: return "Nonreadable"; + case DecUniform: return "Uniform"; + case DecNoStaticUse: return "NoStaticUse"; + case DecCPacked: return "CPacked"; + case DecFuncParamAttr: return "FuncParamAttr"; + case DecFPSaturatedConv: return "FPSaturatedConversion"; + case DecFPRoundingMode: return "FP Rounding Mode"; + case DecFPFastMathMode: return "FP Fast Math Mode"; + case DecLinkageType: return "Linkage Type"; + case DecStream: return "Stream"; + case DecLocation: return "Location"; + case DecComponent: return "Component"; + case DecIndex: return "Index"; + case DecBinding: return "Binding"; + case DecDescriptorSet: return "DescriptorSet"; + case DecOffset: return "Offset"; + case DecAlignment: return "Alignment"; + case DecXfbBuffer: return "XfbBuffer"; + case DecStride: return "Stride"; + case DecBuiltIn: return "Built-In"; + case DecSpecId: return "SpecId"; + + default: return "BadDecoration"; + } +} + +const char* BuiltInString(int builtIn) +{ + switch (builtIn) { + case BuiltInPosition: return "Position"; + case BuiltInPointSize: return "PointSize"; + case BuiltInClipVertex: return "ClipVertex"; + case BuiltInClipDistance: return "ClipDistance"; + case BuiltInCullDistance: return "CullDistance"; + case BuiltInVertexId: return "VertexId"; + case BuiltInInstanceId: return "InstanceId"; + case BuiltInPrimitiveId: return "PrimitiveId"; + case BuiltInInvocationId: return "InvocationId"; + case BuiltInLayer: return "Layer"; + case BuiltInViewportIndex: return "ViewportIndex"; + case BuiltInTessLevelOuter: return "TessLevelOuter"; + case BuiltInTessLevelInner: return "TessLevelInner"; + case BuiltInTessCoord: return "TessCoord"; + case BuiltInPatchVertices: return "PatchVertices"; + case BuiltInFragCoord: return "FragCoord"; + case BuiltInPointCoord: return "PointCoord"; + case BuiltInFrontFacing: return "FrontFacing"; + case BuiltInSampleId: return "SampleId"; + case BuiltInSamplePosition: return "SamplePosition"; + case BuiltInSampleMask: return "SampleMask"; + case BuiltInFragColor: return "FragColor"; + case BuiltInFragDepth: return "FragDepth"; + case BuiltInHelperInvocation: return "HelperInvocation"; + case BuiltInNumWorkgroups: return "NumWorkgroups"; + case BuiltInWorkgroupSize: return "WorkgroupSize"; + case BuiltInWorkgroupId: return "WorkgroupId"; + case BuiltInLocalInvocationId: return "LocalInvocationId"; + case BuiltInGlobalInvocationId: return "GlobalInvocationId"; + case BuiltInLocalInvocationIndex: return "LocalInvocationIndex"; + case BuiltInWorkDim: return "WorkDim"; + case BuiltInGlobalSize: return "GlobalSize"; + case BuiltInEnqueuedWorkgroupSize: return "EnqueuedWorkgroupSize"; + case BuiltInGlobalOffset: return "GlobalOffset"; + case BuiltInGlobalLinearId: return "GlobalLinearId"; + case BuiltInWorkgroupLinearId: return "WorkgroupLinearId"; + case BuiltInSubgroupSize: return "SubgroupSize"; + case BuiltInSubgroupMaxSize: return "SubgroupMaxSize"; + case BuiltInNumSubgroups: return "NumSubgroups"; + case BuiltInNumEnqueuedSubgroups: return "NumEnqueuedSubgroups"; + case BuiltInSubgroupId: return "SubgroupId"; + case BuiltInSubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; + default: return "BadBuiltIn"; + } +} + +const char* DimensionString(int dim) +{ + switch (dim) { + case Dim1D: return "1D"; + case Dim2D: return "2D"; + case Dim3D: return "3D"; + case DimCube: return "Cube"; + case DimRect: return "Rect"; + case DimBuffer: return "Buffer"; + + default: return "BadDimensionality"; + } +} + +const char* SamplerAddressingModeString(int mode) +{ + switch (mode) { + case SamplerAddressingNone: return "None"; + case SamplerAddressingClampToEdge: return "ClampEdge"; + case SamplerAddressingClamp: return "Clamp"; + case SamplerAddressingRepeat: return "Repeat"; + case SamplerAddressingRepeatMirrored: return "RepeatMirrored"; + + default: return "BadSamplerAddrMode"; + } +} + +const char* SamplerFilterModeString(int mode) +{ + switch (mode) { + case SamplerFilterNearest: return "Nearest"; + case SamplerFilterLinear: return "Linear"; + + default: return "BadSamplerFilterMode"; + } +} + +const char* FPFastMathString(int mode) +{ + switch (mode) { + case FPFastMathNNan: return "NotNaN"; + case FPFastMathNInf: return "NotInf"; + case FPFastMathNSZ: return "NSZ"; + case FPFastMathARcp: return "AllowRecip"; + case FPFastMathFast: return "Fast"; + + default: return "BadFastMathMode"; + } +} + +const char* FPRoundingModeString(int mode) +{ + switch (mode) { + case FPRoundRTE: return "RTE"; + case FPRoundRTZ: return "RTZ"; + case FPRoundRTP: return "RTP"; + case FPRoundRTN: return "RTN"; + + default: return "BadFPRoundingMode"; + } +} + + +const char* LinkageTypeString(int type) +{ + switch (type) { + case LinkageExport: return "Export"; + case LinkageImport: return "Import"; + + default: return "BadLinkageType"; + } +} + +const char* FuncParamAttrString(int attr) +{ + switch (attr) { + case FuncParamAttrZext: return "Zext"; + case FuncParamAttrSext: return "Sext"; + case FuncParamAttrByval: return "ByVal"; + case FuncParamAttrSret: return "Sret"; + case FuncParamAttrNoAlias: return "NoAlias"; + case FuncParamAttrNoCapture: return "NoCapture"; + case FuncParamAttrSVM: return "SVM"; + case FuncParamAttrNoWrite: return "NoWrite"; + case FuncParamAttrNoReadWrite: return "NoReadWrite"; + + default: return "BadFunctionParameterAttribute"; + } +} + +const char* AccessQualifierString(int attr) +{ + switch (attr) { + case AccessQualReadOnly: return "ReadOnly"; + case AccessQualWriteOnly: return "WriteOnly"; + case AccessQualReadWrite: return "ReadWrite"; + + default: return "BadAccessQualifier"; + } +} + +const char* SelectControlString(int cont) +{ + switch (cont) { + case SelectControlNone: return "NoControl"; + case SelectControlFlatten: return "Flatten"; + case SelectControlDontFlatten: return "DontFlatten"; + + default: return "BadSelectControl"; + } +} + +const char* FunctionControlString(int cont) +{ + switch (cont) { + case FunctionControlNone: return "NoControl"; + case FunctionControlInline: return "InLine"; + case FunctionControlDontInline: return "DontInline"; + case FunctionControlPure: return "Pure"; + case FunctionControlConst: return "Const"; + + default: return "Bad-select-control"; + } +} + +const char* LoopControlString(int cont) +{ + switch (cont) { + case LoopControlNone: return "NoControl"; + case LoopControlUnroll: return "Unroll"; + case LoopControlDontUnroll: return "DontUnroll"; + + default: return "Bad-loop-control"; + } +} + +const char* MemorySemanticsString(int mem) +{ + switch (mem) { + case MemorySemanticsRelaxed: return "Relaxed"; + case MemorySemanticsSequentiallyConsistent: return "Sequentially-Consistent"; + case MemorySemanticsAcquire: return "Acquire"; + case MemorySemanticsRelease: return "Release"; + + case MemorySemanticsUniform: return "Uniform-memory"; + case MemorySemanticsSubgroup: return "Subgroup-memory"; + case MemorySemanticsWorkgroupLocal: return "Workgroup-local-memory"; + case MemorySemanticsWorkgroupGlobal: return "Workgroup-global-memory"; + case MemorySemanticsAtomicCounter: return "Atomic-counter-memory"; + case MemorySemanticsImage: return "Image-memory"; + + default: return "Bad-memory-semantic"; + } +} + +const char* MemoryAccessString(int mem) +{ + switch (mem) { + case MemoryAccessVolatile: return "Volatile"; + case MemoryAccessAligned: return "Aligned"; + + default: return "Bad-memory-access"; + } +} + +const char* ExecutionScopeString(int mem) +{ + switch (mem) { + case ExecutionScopeCrossDevice: return "CrossDevice"; + case ExecutionScopeDevice: return "Device"; + case ExecutionScopeWorkgroup: return "Workgroup"; + case ExecutionScopeSubgroup: return "Subgroup"; + + default: return "Bad-execution-scope"; + } +} + +const char* GroupOperationString(int gop) { + + switch (gop) + { + case GroupOpReduce: return "Reduce"; + case GroupOpInclusiveScan: return "InclusiveScan"; + case GroupOpExclusiveScan: return "ExclusiveScan"; + + default: return "Bad-execution-scope"; + } +} + +const char* KernelEnqueueFlagsString(int flag) { + switch (flag) + { + case spv::EnqFlagNoWait: return "NoWait"; + case spv::EnqFlagWaitKernel: return "WaitKernel"; + case spv::EnqFlagWaitWaitWorgGroup: return "WaitWorkGroup"; + + default: return "Bad-enqueue-flag"; + } +} + +const char* KernelProfilingInfoString(int info) { + switch (info) + { + case spv::ProfInfoCmdExecTime: return "CmdExecTime"; + default: return "Bad-profiling-info"; + } +} + +const char* GetOperandDesc(OperandClass operand) +{ + switch (operand) { + case OperandId: return ""; + case OperandOptionalId: return "Optional "; + case OperandVariableIds: return ", , ..."; + case OperandVariableLiterals: return "literal, literal, ..."; + case OperandVariableLiteralId: return "literal, label , +\nliteral, label , +\n..."; + case OperandLiteralNumber: return "Literal Number"; + case OperandLiteralString: return "Literal String"; + case OperandSource: return "Source Language"; + case OperandExecutionModel: return "Execution Model"; + case OperandAddressing: return "Addressing Model"; + case OperandMemory: return "Memory Model"; + case OperandExecutionMode: return "Execution Mode"; + case OperandStorage: return "Storage Class"; + case OperandDimensionality: return "Dim"; + case OperandDecoration: return "Decoration"; + case OperandBuiltIn: return "Built-In"; + case OperandSelect: return "Selection Control"; + case OperandLoop: return "Loop Control"; + case OperandFunction: return "Function Control Mask"; + case OperandSamplerAddressingMode: return "Sampler Addressing Mode"; + case OperandSamplerFilterMode: return "Sampler Filter Mode"; + case OperandFPFastMath: return "FP Fast Math Mode"; + case OperandFPRoundingMode: return "FP Rounding Mode"; + case OperandLinkageType: return "Linkage Type"; + case OperandFuncParamAttr: return "Function Parameter Attribute"; + case OperandAccessQualifier: return "Access Qualifier"; + case OperandMemorySemantics: return "Memory Semantics"; + case OperandMemoryAccess: return "Memory Access"; + case OperandExecutionScope: return "Execution Scope"; + case OperandGroupOperation: return "Group Operation"; + case OperandKernelEnqueueFlags: return "Kernel Enqueue Flags"; + case OperandKernelProfilingInfo: return "Kernel Profiling Info"; + default: return "Unknown"; + } +} + +}; // end spv namespace diff --git a/SPIRV/doc.h b/SPIRV/doc.h new file mode 100644 index 00000000..176ae918 --- /dev/null +++ b/SPIRV/doc.h @@ -0,0 +1,164 @@ +// +//Copyright (C) 2014 LunarG, Inc. +// +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. + +// +// Author: John Kessenich, LunarG +// + +// +// Return English versions of instruction/operand information. +// This can be used for disassembly, printing documentation, etc. +// + +#include "spirv.h" + +#include + +namespace spv { + +// Fill in all the parameters of the instruction set +void Parameterize(); + +// Return the English names of all the enums. +const char* SourceString(int); +const char* AddressingString(int); +const char* MemoryString(int); +const char* ExecutionModelString(int); +const char* ExecutionModeString(int); +const char* StorageClassString(int); +const char* DecorationString(int); +const char* BuiltInString(int); +const char* DimensionString(int); +const char* SelectControlString(int); +const char* LoopControlString(int); +const char* FunctionControlString(int); +const char* SamplerAddressingModeString(int); +const char* SamplerFilterModeString(int); +const char* FPFastMathString(int); +const char* FPRoundingModeString(int); +const char* LinkageTypeString(int); +const char* FuncParamAttrString(int); +const char* AccessQualifierString(int); +const char* MemorySemanticsString(int); +const char* MemoryAccessString(int); +const char* ExecutionScopeString(int); +const char* GroupOperationString(int); +const char* KernelEnqueueFlagsString(int); +const char* KernelProfilingInfoString(int); + +// For parameterizing operands. +enum OperandClass { + OperandNone, + OperandId, + OperandOptionalId, + OperandVariableIds, + OperandVariableLiterals, + OperandVariableLiteralId, + OperandLiteralNumber, + OperandLiteralString, + OperandSource, + OperandExecutionModel, + OperandAddressing, + OperandMemory, + OperandExecutionMode, + OperandStorage, + OperandDimensionality, + OperandSamplerAddressingMode, + OperandSamplerFilterMode, + OperandFPFastMath, + OperandFPRoundingMode, + OperandLinkageType, + OperandFuncParamAttr, + OperandDecoration, + OperandBuiltIn, + OperandSelect, + OperandLoop, + OperandFunction, + OperandAccessQualifier, + OperandMemorySemantics, + OperandMemoryAccess, + OperandExecutionScope, + OperandGroupOperation, + OperandKernelEnqueueFlags, + OperandKernelProfilingInfo, + OperandCount +}; + +// Parameterize a set of operands with their OperandClass(es) and descriptions. +class OperandParameters { +public: + OperandParameters() { } + void push(OperandClass oc) + { + opClass.push_back(oc); + } + OperandClass getClass(int op) const { return opClass[op]; } + int getNum() const { return (int)opClass.size(); } + +protected: + std::vector opClass; +}; + +// Parameterize an instruction's logical format, including its known set of operands, +// per OperandParameters above. +class InstructionParameters { +public: + InstructionParameters() : + typePresent(true), // most normal, only exceptions have to be spelled out + resultPresent(true), // most normal, only exceptions have to be spelled out + opName(0) + { } + + void setResultAndType(bool r, bool t) + { + resultPresent = r; + typePresent = t; + } + + bool hasResult() const { return resultPresent != 0; } + bool hasType() const { return typePresent != 0; } + + const char* opName; + OperandParameters operands; + +protected: + int typePresent : 1; + int resultPresent : 1; +}; + +// The set of objects that hold all the instruction/operand +// parameterization information. +extern InstructionParameters InstructionDesc[spv::OpCount]; + +}; // end namespace spv diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index c9f2da0f..4f385660 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -42,6 +42,8 @@ #include "./../glslang/Public/ShaderLang.h" #include "../SPIRV/GlslangToSpv.h" #include "../SPIRV/GLSL450Lib.h" +#include "../SPIRV/doc.h" +#include "../SPIRV/disassemble.h" #include #include #include @@ -54,20 +56,21 @@ extern "C" { // Command-line options enum TOptions { - EOptionNone = 0x000, - EOptionIntermediate = 0x001, - EOptionSuppressInfolog = 0x002, - EOptionMemoryLeakMode = 0x004, - EOptionRelaxedErrors = 0x008, - EOptionGiveWarnings = 0x010, - EOptionLinkProgram = 0x020, - EOptionMultiThreaded = 0x040, - EOptionDumpConfig = 0x080, - EOptionDumpReflection = 0x100, - EOptionSuppressWarnings = 0x200, - EOptionDumpVersions = 0x400, - EOptionSpv = 0x800, - EOptionDefaultDesktop = 0x1000, + EOptionNone = 0x0000, + EOptionIntermediate = 0x0001, + EOptionSuppressInfolog = 0x0002, + EOptionMemoryLeakMode = 0x0004, + EOptionRelaxedErrors = 0x0008, + EOptionGiveWarnings = 0x0010, + EOptionLinkProgram = 0x0020, + EOptionMultiThreaded = 0x0040, + EOptionDumpConfig = 0x0080, + EOptionDumpReflection = 0x0100, + EOptionSuppressWarnings = 0x0200, + EOptionDumpVersions = 0x0400, + EOptionSpv = 0x0800, + EOptionHumanReadableSpv = 0x1000, + EOptionDefaultDesktop = 0x2000, }; // @@ -479,6 +482,9 @@ bool ProcessArguments(int argc, char* argv[]) Work[argc] = 0; if (argv[0][0] == '-') { switch (argv[0][1]) { + case 'H': + Options |= EOptionHumanReadableSpv; + // fall through to -V case 'V': Options |= EOptionSpv; Options |= EOptionLinkProgram; @@ -570,6 +576,8 @@ CompileShaders(void*) return 0; } +const char* GlslStd450DebugNames[GLSL_STD_450::Count]; + // // For linking mode: Will independently parse each item in the worklist, but then put them // in the same program and link them together. @@ -653,6 +661,11 @@ void CompileAndLinkShaders() default: name = "unknown"; break; } glslang::OutputSpv(spirv, name); + if (Options & EOptionHumanReadableSpv) { + spv::Parameterize(); + GLSL_STD_450::GetDebugNames(GlslStd450DebugNames); + spv::Disassemble(std::cout, spirv); + } } } } @@ -854,6 +867,7 @@ void usage() "To get other information, use one of the following options:\n" "(Each option must be specified separately, but can go anywhere in the command line.)\n" " -V create SPIR-V in file .spv\n" + " -H print human readable form of SPIR-V; turns on -V\n" " -c configuration dump; use to create default configuration file (redirect to a .conf file)\n" " -d default to desktop (#version 110) when there is no version in the shader (default is ES version 100)\n" " -i intermediate tree (glslang AST) is printed out\n"