spirv-reflect-ffi (empty) → 0.1
raw patch · 9 files changed
+10651/−0 lines, 9 filesdep +basedep +bytestringdep +directory
Dependencies added: base, bytestring, directory, filepath, spirv-reflect-ffi, spirv-reflect-types, tasty, tasty-hunit, text, vector
Files
- ChangeLog.md +7/−0
- LICENSE +30/−0
- cbits/include/spirv/unified1/spirv.h +2542/−0
- cbits/spirv_reflect.c +5097/−0
- cbits/spirv_reflect.h +2292/−0
- lib/Data/SpirV/Reflect/FFI.hs +34/−0
- lib/Data/SpirV/Reflect/FFI/Internal.chs +494/−0
- spirv-reflect-ffi.cabal +99/−0
- test/Main.hs +56/−0
+ ChangeLog.md view
@@ -0,0 +1,7 @@+# Changelog for spirv-reflect-ffi++## [0.1] - 2022-09-04++* Initial release.++[0.1]: https://gitlab.com/dpwiz/spirv-reflect/-/tree/v0.1-ffi
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright IC Rainbow (c) 2022++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 Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ cbits/include/spirv/unified1/spirv.h view
@@ -0,0 +1,2542 @@+/*+** Copyright (c) 2014-2020 The Khronos Group Inc.+** +** Permission is hereby granted, free of charge, to any person obtaining a copy+** of this software and/or associated documentation files (the "Materials"),+** to deal in the Materials without restriction, including without limitation+** the rights to use, copy, modify, merge, publish, distribute, sublicense,+** and/or sell copies of the Materials, and to permit persons to whom the+** Materials are furnished to do so, subject to the following conditions:+** +** The above copyright notice and this permission notice shall be included in+** all copies or substantial portions of the Materials.+** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS+** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND+** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS+** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL+** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING+** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS+** IN THE MATERIALS.+*/++/*+** This header is automatically generated by the same tool that creates+** the Binary Section of the SPIR-V specification.+*/++/*+** Enumeration tokens for SPIR-V, in various styles:+** C, C++, C++11, JSON, Lua, Python, C#, D+** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL+** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL+** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL+** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL+** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']+** - C# will use enum classes in the Specification class located in the "Spv" namespace,+** e.g.: Spv.Specification.SourceLanguage.GLSL+** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL+** +** Some tokens act like mask values, which can be OR'd together,+** while others are mutually exclusive. The mask-like ones have+** "Mask" in their name, and a parallel enum that has the shift+** amount (1 << x) for each corresponding enumerant.+*/++#ifndef spirv_H+#define spirv_H++typedef unsigned int SpvId;++#define SPV_VERSION 0x10600+#define SPV_REVISION 1++static const unsigned int SpvMagicNumber = 0x07230203;+static const unsigned int SpvVersion = 0x00010600;+static const unsigned int SpvRevision = 1;+static const unsigned int SpvOpCodeMask = 0xffff;+static const unsigned int SpvWordCountShift = 16;++typedef enum SpvSourceLanguage_ {+ SpvSourceLanguageUnknown = 0,+ SpvSourceLanguageESSL = 1,+ SpvSourceLanguageGLSL = 2,+ SpvSourceLanguageOpenCL_C = 3,+ SpvSourceLanguageOpenCL_CPP = 4,+ SpvSourceLanguageHLSL = 5,+ SpvSourceLanguageCPP_for_OpenCL = 6,+ SpvSourceLanguageSYCL = 7,+ SpvSourceLanguageMax = 0x7fffffff,+} SpvSourceLanguage;++typedef enum SpvExecutionModel_ {+ SpvExecutionModelVertex = 0,+ SpvExecutionModelTessellationControl = 1,+ SpvExecutionModelTessellationEvaluation = 2,+ SpvExecutionModelGeometry = 3,+ SpvExecutionModelFragment = 4,+ SpvExecutionModelGLCompute = 5,+ SpvExecutionModelKernel = 6,+ SpvExecutionModelTaskNV = 5267,+ SpvExecutionModelMeshNV = 5268,+ SpvExecutionModelRayGenerationKHR = 5313,+ SpvExecutionModelRayGenerationNV = 5313,+ SpvExecutionModelIntersectionKHR = 5314,+ SpvExecutionModelIntersectionNV = 5314,+ SpvExecutionModelAnyHitKHR = 5315,+ SpvExecutionModelAnyHitNV = 5315,+ SpvExecutionModelClosestHitKHR = 5316,+ SpvExecutionModelClosestHitNV = 5316,+ SpvExecutionModelMissKHR = 5317,+ SpvExecutionModelMissNV = 5317,+ SpvExecutionModelCallableKHR = 5318,+ SpvExecutionModelCallableNV = 5318,+ SpvExecutionModelMax = 0x7fffffff,+} SpvExecutionModel;++typedef enum SpvAddressingModel_ {+ SpvAddressingModelLogical = 0,+ SpvAddressingModelPhysical32 = 1,+ SpvAddressingModelPhysical64 = 2,+ SpvAddressingModelPhysicalStorageBuffer64 = 5348,+ SpvAddressingModelPhysicalStorageBuffer64EXT = 5348,+ SpvAddressingModelMax = 0x7fffffff,+} SpvAddressingModel;++typedef enum SpvMemoryModel_ {+ SpvMemoryModelSimple = 0,+ SpvMemoryModelGLSL450 = 1,+ SpvMemoryModelOpenCL = 2,+ SpvMemoryModelVulkan = 3,+ SpvMemoryModelVulkanKHR = 3,+ SpvMemoryModelMax = 0x7fffffff,+} SpvMemoryModel;++typedef enum SpvExecutionMode_ {+ SpvExecutionModeInvocations = 0,+ SpvExecutionModeSpacingEqual = 1,+ SpvExecutionModeSpacingFractionalEven = 2,+ SpvExecutionModeSpacingFractionalOdd = 3,+ SpvExecutionModeVertexOrderCw = 4,+ SpvExecutionModeVertexOrderCcw = 5,+ SpvExecutionModePixelCenterInteger = 6,+ SpvExecutionModeOriginUpperLeft = 7,+ SpvExecutionModeOriginLowerLeft = 8,+ SpvExecutionModeEarlyFragmentTests = 9,+ SpvExecutionModePointMode = 10,+ SpvExecutionModeXfb = 11,+ SpvExecutionModeDepthReplacing = 12,+ SpvExecutionModeDepthGreater = 14,+ SpvExecutionModeDepthLess = 15,+ SpvExecutionModeDepthUnchanged = 16,+ SpvExecutionModeLocalSize = 17,+ SpvExecutionModeLocalSizeHint = 18,+ SpvExecutionModeInputPoints = 19,+ SpvExecutionModeInputLines = 20,+ SpvExecutionModeInputLinesAdjacency = 21,+ SpvExecutionModeTriangles = 22,+ SpvExecutionModeInputTrianglesAdjacency = 23,+ SpvExecutionModeQuads = 24,+ SpvExecutionModeIsolines = 25,+ SpvExecutionModeOutputVertices = 26,+ SpvExecutionModeOutputPoints = 27,+ SpvExecutionModeOutputLineStrip = 28,+ SpvExecutionModeOutputTriangleStrip = 29,+ SpvExecutionModeVecTypeHint = 30,+ SpvExecutionModeContractionOff = 31,+ SpvExecutionModeInitializer = 33,+ SpvExecutionModeFinalizer = 34,+ SpvExecutionModeSubgroupSize = 35,+ SpvExecutionModeSubgroupsPerWorkgroup = 36,+ SpvExecutionModeSubgroupsPerWorkgroupId = 37,+ SpvExecutionModeLocalSizeId = 38,+ SpvExecutionModeLocalSizeHintId = 39,+ SpvExecutionModeSubgroupUniformControlFlowKHR = 4421,+ SpvExecutionModePostDepthCoverage = 4446,+ SpvExecutionModeDenormPreserve = 4459,+ SpvExecutionModeDenormFlushToZero = 4460,+ SpvExecutionModeSignedZeroInfNanPreserve = 4461,+ SpvExecutionModeRoundingModeRTE = 4462,+ SpvExecutionModeRoundingModeRTZ = 4463,+ SpvExecutionModeStencilRefReplacingEXT = 5027,+ SpvExecutionModeOutputLinesNV = 5269,+ SpvExecutionModeOutputPrimitivesNV = 5270,+ SpvExecutionModeDerivativeGroupQuadsNV = 5289,+ SpvExecutionModeDerivativeGroupLinearNV = 5290,+ SpvExecutionModeOutputTrianglesNV = 5298,+ SpvExecutionModePixelInterlockOrderedEXT = 5366,+ SpvExecutionModePixelInterlockUnorderedEXT = 5367,+ SpvExecutionModeSampleInterlockOrderedEXT = 5368,+ SpvExecutionModeSampleInterlockUnorderedEXT = 5369,+ SpvExecutionModeShadingRateInterlockOrderedEXT = 5370,+ SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371,+ SpvExecutionModeSharedLocalMemorySizeINTEL = 5618,+ SpvExecutionModeRoundingModeRTPINTEL = 5620,+ SpvExecutionModeRoundingModeRTNINTEL = 5621,+ SpvExecutionModeFloatingPointModeALTINTEL = 5622,+ SpvExecutionModeFloatingPointModeIEEEINTEL = 5623,+ SpvExecutionModeMaxWorkgroupSizeINTEL = 5893,+ SpvExecutionModeMaxWorkDimINTEL = 5894,+ SpvExecutionModeNoGlobalOffsetINTEL = 5895,+ SpvExecutionModeNumSIMDWorkitemsINTEL = 5896,+ SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,+ SpvExecutionModeNamedBarrierCountINTEL = 6417,+ SpvExecutionModeMax = 0x7fffffff,+} SpvExecutionMode;++typedef enum SpvStorageClass_ {+ SpvStorageClassUniformConstant = 0,+ SpvStorageClassInput = 1,+ SpvStorageClassUniform = 2,+ SpvStorageClassOutput = 3,+ SpvStorageClassWorkgroup = 4,+ SpvStorageClassCrossWorkgroup = 5,+ SpvStorageClassPrivate = 6,+ SpvStorageClassFunction = 7,+ SpvStorageClassGeneric = 8,+ SpvStorageClassPushConstant = 9,+ SpvStorageClassAtomicCounter = 10,+ SpvStorageClassImage = 11,+ SpvStorageClassStorageBuffer = 12,+ SpvStorageClassCallableDataKHR = 5328,+ SpvStorageClassCallableDataNV = 5328,+ SpvStorageClassIncomingCallableDataKHR = 5329,+ SpvStorageClassIncomingCallableDataNV = 5329,+ SpvStorageClassRayPayloadKHR = 5338,+ SpvStorageClassRayPayloadNV = 5338,+ SpvStorageClassHitAttributeKHR = 5339,+ SpvStorageClassHitAttributeNV = 5339,+ SpvStorageClassIncomingRayPayloadKHR = 5342,+ SpvStorageClassIncomingRayPayloadNV = 5342,+ SpvStorageClassShaderRecordBufferKHR = 5343,+ SpvStorageClassShaderRecordBufferNV = 5343,+ SpvStorageClassPhysicalStorageBuffer = 5349,+ SpvStorageClassPhysicalStorageBufferEXT = 5349,+ SpvStorageClassCodeSectionINTEL = 5605,+ SpvStorageClassDeviceOnlyINTEL = 5936,+ SpvStorageClassHostOnlyINTEL = 5937,+ SpvStorageClassMax = 0x7fffffff,+} SpvStorageClass;++typedef enum SpvDim_ {+ SpvDim1D = 0,+ SpvDim2D = 1,+ SpvDim3D = 2,+ SpvDimCube = 3,+ SpvDimRect = 4,+ SpvDimBuffer = 5,+ SpvDimSubpassData = 6,+ SpvDimMax = 0x7fffffff,+} SpvDim;++typedef enum SpvSamplerAddressingMode_ {+ SpvSamplerAddressingModeNone = 0,+ SpvSamplerAddressingModeClampToEdge = 1,+ SpvSamplerAddressingModeClamp = 2,+ SpvSamplerAddressingModeRepeat = 3,+ SpvSamplerAddressingModeRepeatMirrored = 4,+ SpvSamplerAddressingModeMax = 0x7fffffff,+} SpvSamplerAddressingMode;++typedef enum SpvSamplerFilterMode_ {+ SpvSamplerFilterModeNearest = 0,+ SpvSamplerFilterModeLinear = 1,+ SpvSamplerFilterModeMax = 0x7fffffff,+} SpvSamplerFilterMode;++typedef enum SpvImageFormat_ {+ SpvImageFormatUnknown = 0,+ SpvImageFormatRgba32f = 1,+ SpvImageFormatRgba16f = 2,+ SpvImageFormatR32f = 3,+ SpvImageFormatRgba8 = 4,+ SpvImageFormatRgba8Snorm = 5,+ SpvImageFormatRg32f = 6,+ SpvImageFormatRg16f = 7,+ SpvImageFormatR11fG11fB10f = 8,+ SpvImageFormatR16f = 9,+ SpvImageFormatRgba16 = 10,+ SpvImageFormatRgb10A2 = 11,+ SpvImageFormatRg16 = 12,+ SpvImageFormatRg8 = 13,+ SpvImageFormatR16 = 14,+ SpvImageFormatR8 = 15,+ SpvImageFormatRgba16Snorm = 16,+ SpvImageFormatRg16Snorm = 17,+ SpvImageFormatRg8Snorm = 18,+ SpvImageFormatR16Snorm = 19,+ SpvImageFormatR8Snorm = 20,+ SpvImageFormatRgba32i = 21,+ SpvImageFormatRgba16i = 22,+ SpvImageFormatRgba8i = 23,+ SpvImageFormatR32i = 24,+ SpvImageFormatRg32i = 25,+ SpvImageFormatRg16i = 26,+ SpvImageFormatRg8i = 27,+ SpvImageFormatR16i = 28,+ SpvImageFormatR8i = 29,+ SpvImageFormatRgba32ui = 30,+ SpvImageFormatRgba16ui = 31,+ SpvImageFormatRgba8ui = 32,+ SpvImageFormatR32ui = 33,+ SpvImageFormatRgb10a2ui = 34,+ SpvImageFormatRg32ui = 35,+ SpvImageFormatRg16ui = 36,+ SpvImageFormatRg8ui = 37,+ SpvImageFormatR16ui = 38,+ SpvImageFormatR8ui = 39,+ SpvImageFormatR64ui = 40,+ SpvImageFormatR64i = 41,+ SpvImageFormatMax = 0x7fffffff,+} SpvImageFormat;++typedef enum SpvImageChannelOrder_ {+ SpvImageChannelOrderR = 0,+ SpvImageChannelOrderA = 1,+ SpvImageChannelOrderRG = 2,+ SpvImageChannelOrderRA = 3,+ SpvImageChannelOrderRGB = 4,+ SpvImageChannelOrderRGBA = 5,+ SpvImageChannelOrderBGRA = 6,+ SpvImageChannelOrderARGB = 7,+ SpvImageChannelOrderIntensity = 8,+ SpvImageChannelOrderLuminance = 9,+ SpvImageChannelOrderRx = 10,+ SpvImageChannelOrderRGx = 11,+ SpvImageChannelOrderRGBx = 12,+ SpvImageChannelOrderDepth = 13,+ SpvImageChannelOrderDepthStencil = 14,+ SpvImageChannelOrdersRGB = 15,+ SpvImageChannelOrdersRGBx = 16,+ SpvImageChannelOrdersRGBA = 17,+ SpvImageChannelOrdersBGRA = 18,+ SpvImageChannelOrderABGR = 19,+ SpvImageChannelOrderMax = 0x7fffffff,+} SpvImageChannelOrder;++typedef enum SpvImageChannelDataType_ {+ SpvImageChannelDataTypeSnormInt8 = 0,+ SpvImageChannelDataTypeSnormInt16 = 1,+ SpvImageChannelDataTypeUnormInt8 = 2,+ SpvImageChannelDataTypeUnormInt16 = 3,+ SpvImageChannelDataTypeUnormShort565 = 4,+ SpvImageChannelDataTypeUnormShort555 = 5,+ SpvImageChannelDataTypeUnormInt101010 = 6,+ SpvImageChannelDataTypeSignedInt8 = 7,+ SpvImageChannelDataTypeSignedInt16 = 8,+ SpvImageChannelDataTypeSignedInt32 = 9,+ SpvImageChannelDataTypeUnsignedInt8 = 10,+ SpvImageChannelDataTypeUnsignedInt16 = 11,+ SpvImageChannelDataTypeUnsignedInt32 = 12,+ SpvImageChannelDataTypeHalfFloat = 13,+ SpvImageChannelDataTypeFloat = 14,+ SpvImageChannelDataTypeUnormInt24 = 15,+ SpvImageChannelDataTypeUnormInt101010_2 = 16,+ SpvImageChannelDataTypeMax = 0x7fffffff,+} SpvImageChannelDataType;++typedef enum SpvImageOperandsShift_ {+ SpvImageOperandsBiasShift = 0,+ SpvImageOperandsLodShift = 1,+ SpvImageOperandsGradShift = 2,+ SpvImageOperandsConstOffsetShift = 3,+ SpvImageOperandsOffsetShift = 4,+ SpvImageOperandsConstOffsetsShift = 5,+ SpvImageOperandsSampleShift = 6,+ SpvImageOperandsMinLodShift = 7,+ SpvImageOperandsMakeTexelAvailableShift = 8,+ SpvImageOperandsMakeTexelAvailableKHRShift = 8,+ SpvImageOperandsMakeTexelVisibleShift = 9,+ SpvImageOperandsMakeTexelVisibleKHRShift = 9,+ SpvImageOperandsNonPrivateTexelShift = 10,+ SpvImageOperandsNonPrivateTexelKHRShift = 10,+ SpvImageOperandsVolatileTexelShift = 11,+ SpvImageOperandsVolatileTexelKHRShift = 11,+ SpvImageOperandsSignExtendShift = 12,+ SpvImageOperandsZeroExtendShift = 13,+ SpvImageOperandsNontemporalShift = 14,+ SpvImageOperandsOffsetsShift = 16,+ SpvImageOperandsMax = 0x7fffffff,+} SpvImageOperandsShift;++typedef enum SpvImageOperandsMask_ {+ SpvImageOperandsMaskNone = 0,+ SpvImageOperandsBiasMask = 0x00000001,+ SpvImageOperandsLodMask = 0x00000002,+ SpvImageOperandsGradMask = 0x00000004,+ SpvImageOperandsConstOffsetMask = 0x00000008,+ SpvImageOperandsOffsetMask = 0x00000010,+ SpvImageOperandsConstOffsetsMask = 0x00000020,+ SpvImageOperandsSampleMask = 0x00000040,+ SpvImageOperandsMinLodMask = 0x00000080,+ SpvImageOperandsMakeTexelAvailableMask = 0x00000100,+ SpvImageOperandsMakeTexelAvailableKHRMask = 0x00000100,+ SpvImageOperandsMakeTexelVisibleMask = 0x00000200,+ SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200,+ SpvImageOperandsNonPrivateTexelMask = 0x00000400,+ SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400,+ SpvImageOperandsVolatileTexelMask = 0x00000800,+ SpvImageOperandsVolatileTexelKHRMask = 0x00000800,+ SpvImageOperandsSignExtendMask = 0x00001000,+ SpvImageOperandsZeroExtendMask = 0x00002000,+ SpvImageOperandsNontemporalMask = 0x00004000,+ SpvImageOperandsOffsetsMask = 0x00010000,+} SpvImageOperandsMask;++typedef enum SpvFPFastMathModeShift_ {+ SpvFPFastMathModeNotNaNShift = 0,+ SpvFPFastMathModeNotInfShift = 1,+ SpvFPFastMathModeNSZShift = 2,+ SpvFPFastMathModeAllowRecipShift = 3,+ SpvFPFastMathModeFastShift = 4,+ SpvFPFastMathModeAllowContractFastINTELShift = 16,+ SpvFPFastMathModeAllowReassocINTELShift = 17,+ SpvFPFastMathModeMax = 0x7fffffff,+} SpvFPFastMathModeShift;++typedef enum SpvFPFastMathModeMask_ {+ SpvFPFastMathModeMaskNone = 0,+ SpvFPFastMathModeNotNaNMask = 0x00000001,+ SpvFPFastMathModeNotInfMask = 0x00000002,+ SpvFPFastMathModeNSZMask = 0x00000004,+ SpvFPFastMathModeAllowRecipMask = 0x00000008,+ SpvFPFastMathModeFastMask = 0x00000010,+ SpvFPFastMathModeAllowContractFastINTELMask = 0x00010000,+ SpvFPFastMathModeAllowReassocINTELMask = 0x00020000,+} SpvFPFastMathModeMask;++typedef enum SpvFPRoundingMode_ {+ SpvFPRoundingModeRTE = 0,+ SpvFPRoundingModeRTZ = 1,+ SpvFPRoundingModeRTP = 2,+ SpvFPRoundingModeRTN = 3,+ SpvFPRoundingModeMax = 0x7fffffff,+} SpvFPRoundingMode;++typedef enum SpvLinkageType_ {+ SpvLinkageTypeExport = 0,+ SpvLinkageTypeImport = 1,+ SpvLinkageTypeLinkOnceODR = 2,+ SpvLinkageTypeMax = 0x7fffffff,+} SpvLinkageType;++typedef enum SpvAccessQualifier_ {+ SpvAccessQualifierReadOnly = 0,+ SpvAccessQualifierWriteOnly = 1,+ SpvAccessQualifierReadWrite = 2,+ SpvAccessQualifierMax = 0x7fffffff,+} SpvAccessQualifier;++typedef enum SpvFunctionParameterAttribute_ {+ SpvFunctionParameterAttributeZext = 0,+ SpvFunctionParameterAttributeSext = 1,+ SpvFunctionParameterAttributeByVal = 2,+ SpvFunctionParameterAttributeSret = 3,+ SpvFunctionParameterAttributeNoAlias = 4,+ SpvFunctionParameterAttributeNoCapture = 5,+ SpvFunctionParameterAttributeNoWrite = 6,+ SpvFunctionParameterAttributeNoReadWrite = 7,+ SpvFunctionParameterAttributeMax = 0x7fffffff,+} SpvFunctionParameterAttribute;++typedef enum SpvDecoration_ {+ SpvDecorationRelaxedPrecision = 0,+ SpvDecorationSpecId = 1,+ SpvDecorationBlock = 2,+ SpvDecorationBufferBlock = 3,+ SpvDecorationRowMajor = 4,+ SpvDecorationColMajor = 5,+ SpvDecorationArrayStride = 6,+ SpvDecorationMatrixStride = 7,+ SpvDecorationGLSLShared = 8,+ SpvDecorationGLSLPacked = 9,+ SpvDecorationCPacked = 10,+ SpvDecorationBuiltIn = 11,+ SpvDecorationNoPerspective = 13,+ SpvDecorationFlat = 14,+ SpvDecorationPatch = 15,+ SpvDecorationCentroid = 16,+ SpvDecorationSample = 17,+ SpvDecorationInvariant = 18,+ SpvDecorationRestrict = 19,+ SpvDecorationAliased = 20,+ SpvDecorationVolatile = 21,+ SpvDecorationConstant = 22,+ SpvDecorationCoherent = 23,+ SpvDecorationNonWritable = 24,+ SpvDecorationNonReadable = 25,+ SpvDecorationUniform = 26,+ SpvDecorationUniformId = 27,+ SpvDecorationSaturatedConversion = 28,+ SpvDecorationStream = 29,+ SpvDecorationLocation = 30,+ SpvDecorationComponent = 31,+ SpvDecorationIndex = 32,+ SpvDecorationBinding = 33,+ SpvDecorationDescriptorSet = 34,+ SpvDecorationOffset = 35,+ SpvDecorationXfbBuffer = 36,+ SpvDecorationXfbStride = 37,+ SpvDecorationFuncParamAttr = 38,+ SpvDecorationFPRoundingMode = 39,+ SpvDecorationFPFastMathMode = 40,+ SpvDecorationLinkageAttributes = 41,+ SpvDecorationNoContraction = 42,+ SpvDecorationInputAttachmentIndex = 43,+ SpvDecorationAlignment = 44,+ SpvDecorationMaxByteOffset = 45,+ SpvDecorationAlignmentId = 46,+ SpvDecorationMaxByteOffsetId = 47,+ SpvDecorationNoSignedWrap = 4469,+ SpvDecorationNoUnsignedWrap = 4470,+ SpvDecorationExplicitInterpAMD = 4999,+ SpvDecorationOverrideCoverageNV = 5248,+ SpvDecorationPassthroughNV = 5250,+ SpvDecorationViewportRelativeNV = 5252,+ SpvDecorationSecondaryViewportRelativeNV = 5256,+ SpvDecorationPerPrimitiveNV = 5271,+ SpvDecorationPerViewNV = 5272,+ SpvDecorationPerTaskNV = 5273,+ SpvDecorationPerVertexKHR = 5285,+ SpvDecorationPerVertexNV = 5285,+ SpvDecorationNonUniform = 5300,+ SpvDecorationNonUniformEXT = 5300,+ SpvDecorationRestrictPointer = 5355,+ SpvDecorationRestrictPointerEXT = 5355,+ SpvDecorationAliasedPointer = 5356,+ SpvDecorationAliasedPointerEXT = 5356,+ SpvDecorationBindlessSamplerNV = 5398,+ SpvDecorationBindlessImageNV = 5399,+ SpvDecorationBoundSamplerNV = 5400,+ SpvDecorationBoundImageNV = 5401,+ SpvDecorationSIMTCallINTEL = 5599,+ SpvDecorationReferencedIndirectlyINTEL = 5602,+ SpvDecorationClobberINTEL = 5607,+ SpvDecorationSideEffectsINTEL = 5608,+ SpvDecorationVectorComputeVariableINTEL = 5624,+ SpvDecorationFuncParamIOKindINTEL = 5625,+ SpvDecorationVectorComputeFunctionINTEL = 5626,+ SpvDecorationStackCallINTEL = 5627,+ SpvDecorationGlobalVariableOffsetINTEL = 5628,+ SpvDecorationCounterBuffer = 5634,+ SpvDecorationHlslCounterBufferGOOGLE = 5634,+ SpvDecorationHlslSemanticGOOGLE = 5635,+ SpvDecorationUserSemantic = 5635,+ SpvDecorationUserTypeGOOGLE = 5636,+ SpvDecorationFunctionRoundingModeINTEL = 5822,+ SpvDecorationFunctionDenormModeINTEL = 5823,+ SpvDecorationRegisterINTEL = 5825,+ SpvDecorationMemoryINTEL = 5826,+ SpvDecorationNumbanksINTEL = 5827,+ SpvDecorationBankwidthINTEL = 5828,+ SpvDecorationMaxPrivateCopiesINTEL = 5829,+ SpvDecorationSinglepumpINTEL = 5830,+ SpvDecorationDoublepumpINTEL = 5831,+ SpvDecorationMaxReplicatesINTEL = 5832,+ SpvDecorationSimpleDualPortINTEL = 5833,+ SpvDecorationMergeINTEL = 5834,+ SpvDecorationBankBitsINTEL = 5835,+ SpvDecorationForcePow2DepthINTEL = 5836,+ SpvDecorationBurstCoalesceINTEL = 5899,+ SpvDecorationCacheSizeINTEL = 5900,+ SpvDecorationDontStaticallyCoalesceINTEL = 5901,+ SpvDecorationPrefetchINTEL = 5902,+ SpvDecorationStallEnableINTEL = 5905,+ SpvDecorationFuseLoopsInFunctionINTEL = 5907,+ SpvDecorationAliasScopeINTEL = 5914,+ SpvDecorationNoAliasINTEL = 5915,+ SpvDecorationBufferLocationINTEL = 5921,+ SpvDecorationIOPipeStorageINTEL = 5944,+ SpvDecorationFunctionFloatingPointModeINTEL = 6080,+ SpvDecorationSingleElementVectorINTEL = 6085,+ SpvDecorationVectorComputeCallableFunctionINTEL = 6087,+ SpvDecorationMediaBlockIOINTEL = 6140,+ SpvDecorationMax = 0x7fffffff,+} SpvDecoration;++typedef enum SpvBuiltIn_ {+ SpvBuiltInPosition = 0,+ SpvBuiltInPointSize = 1,+ SpvBuiltInClipDistance = 3,+ SpvBuiltInCullDistance = 4,+ SpvBuiltInVertexId = 5,+ SpvBuiltInInstanceId = 6,+ SpvBuiltInPrimitiveId = 7,+ SpvBuiltInInvocationId = 8,+ SpvBuiltInLayer = 9,+ SpvBuiltInViewportIndex = 10,+ SpvBuiltInTessLevelOuter = 11,+ SpvBuiltInTessLevelInner = 12,+ SpvBuiltInTessCoord = 13,+ SpvBuiltInPatchVertices = 14,+ SpvBuiltInFragCoord = 15,+ SpvBuiltInPointCoord = 16,+ SpvBuiltInFrontFacing = 17,+ SpvBuiltInSampleId = 18,+ SpvBuiltInSamplePosition = 19,+ SpvBuiltInSampleMask = 20,+ SpvBuiltInFragDepth = 22,+ SpvBuiltInHelperInvocation = 23,+ SpvBuiltInNumWorkgroups = 24,+ SpvBuiltInWorkgroupSize = 25,+ SpvBuiltInWorkgroupId = 26,+ SpvBuiltInLocalInvocationId = 27,+ SpvBuiltInGlobalInvocationId = 28,+ SpvBuiltInLocalInvocationIndex = 29,+ SpvBuiltInWorkDim = 30,+ SpvBuiltInGlobalSize = 31,+ SpvBuiltInEnqueuedWorkgroupSize = 32,+ SpvBuiltInGlobalOffset = 33,+ SpvBuiltInGlobalLinearId = 34,+ SpvBuiltInSubgroupSize = 36,+ SpvBuiltInSubgroupMaxSize = 37,+ SpvBuiltInNumSubgroups = 38,+ SpvBuiltInNumEnqueuedSubgroups = 39,+ SpvBuiltInSubgroupId = 40,+ SpvBuiltInSubgroupLocalInvocationId = 41,+ SpvBuiltInVertexIndex = 42,+ SpvBuiltInInstanceIndex = 43,+ SpvBuiltInSubgroupEqMask = 4416,+ SpvBuiltInSubgroupEqMaskKHR = 4416,+ SpvBuiltInSubgroupGeMask = 4417,+ SpvBuiltInSubgroupGeMaskKHR = 4417,+ SpvBuiltInSubgroupGtMask = 4418,+ SpvBuiltInSubgroupGtMaskKHR = 4418,+ SpvBuiltInSubgroupLeMask = 4419,+ SpvBuiltInSubgroupLeMaskKHR = 4419,+ SpvBuiltInSubgroupLtMask = 4420,+ SpvBuiltInSubgroupLtMaskKHR = 4420,+ SpvBuiltInBaseVertex = 4424,+ SpvBuiltInBaseInstance = 4425,+ SpvBuiltInDrawIndex = 4426,+ SpvBuiltInPrimitiveShadingRateKHR = 4432,+ SpvBuiltInDeviceIndex = 4438,+ SpvBuiltInViewIndex = 4440,+ SpvBuiltInShadingRateKHR = 4444,+ SpvBuiltInBaryCoordNoPerspAMD = 4992,+ SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993,+ SpvBuiltInBaryCoordNoPerspSampleAMD = 4994,+ SpvBuiltInBaryCoordSmoothAMD = 4995,+ SpvBuiltInBaryCoordSmoothCentroidAMD = 4996,+ SpvBuiltInBaryCoordSmoothSampleAMD = 4997,+ SpvBuiltInBaryCoordPullModelAMD = 4998,+ SpvBuiltInFragStencilRefEXT = 5014,+ SpvBuiltInViewportMaskNV = 5253,+ SpvBuiltInSecondaryPositionNV = 5257,+ SpvBuiltInSecondaryViewportMaskNV = 5258,+ SpvBuiltInPositionPerViewNV = 5261,+ SpvBuiltInViewportMaskPerViewNV = 5262,+ SpvBuiltInFullyCoveredEXT = 5264,+ SpvBuiltInTaskCountNV = 5274,+ SpvBuiltInPrimitiveCountNV = 5275,+ SpvBuiltInPrimitiveIndicesNV = 5276,+ SpvBuiltInClipDistancePerViewNV = 5277,+ SpvBuiltInCullDistancePerViewNV = 5278,+ SpvBuiltInLayerPerViewNV = 5279,+ SpvBuiltInMeshViewCountNV = 5280,+ SpvBuiltInMeshViewIndicesNV = 5281,+ SpvBuiltInBaryCoordKHR = 5286,+ SpvBuiltInBaryCoordNV = 5286,+ SpvBuiltInBaryCoordNoPerspKHR = 5287,+ SpvBuiltInBaryCoordNoPerspNV = 5287,+ SpvBuiltInFragSizeEXT = 5292,+ SpvBuiltInFragmentSizeNV = 5292,+ SpvBuiltInFragInvocationCountEXT = 5293,+ SpvBuiltInInvocationsPerPixelNV = 5293,+ SpvBuiltInLaunchIdKHR = 5319,+ SpvBuiltInLaunchIdNV = 5319,+ SpvBuiltInLaunchSizeKHR = 5320,+ SpvBuiltInLaunchSizeNV = 5320,+ SpvBuiltInWorldRayOriginKHR = 5321,+ SpvBuiltInWorldRayOriginNV = 5321,+ SpvBuiltInWorldRayDirectionKHR = 5322,+ SpvBuiltInWorldRayDirectionNV = 5322,+ SpvBuiltInObjectRayOriginKHR = 5323,+ SpvBuiltInObjectRayOriginNV = 5323,+ SpvBuiltInObjectRayDirectionKHR = 5324,+ SpvBuiltInObjectRayDirectionNV = 5324,+ SpvBuiltInRayTminKHR = 5325,+ SpvBuiltInRayTminNV = 5325,+ SpvBuiltInRayTmaxKHR = 5326,+ SpvBuiltInRayTmaxNV = 5326,+ SpvBuiltInInstanceCustomIndexKHR = 5327,+ SpvBuiltInInstanceCustomIndexNV = 5327,+ SpvBuiltInObjectToWorldKHR = 5330,+ SpvBuiltInObjectToWorldNV = 5330,+ SpvBuiltInWorldToObjectKHR = 5331,+ SpvBuiltInWorldToObjectNV = 5331,+ SpvBuiltInHitTNV = 5332,+ SpvBuiltInHitKindKHR = 5333,+ SpvBuiltInHitKindNV = 5333,+ SpvBuiltInCurrentRayTimeNV = 5334,+ SpvBuiltInIncomingRayFlagsKHR = 5351,+ SpvBuiltInIncomingRayFlagsNV = 5351,+ SpvBuiltInRayGeometryIndexKHR = 5352,+ SpvBuiltInWarpsPerSMNV = 5374,+ SpvBuiltInSMCountNV = 5375,+ SpvBuiltInWarpIDNV = 5376,+ SpvBuiltInSMIDNV = 5377,+ SpvBuiltInCullMaskKHR = 6021,+ SpvBuiltInMax = 0x7fffffff,+} SpvBuiltIn;++typedef enum SpvSelectionControlShift_ {+ SpvSelectionControlFlattenShift = 0,+ SpvSelectionControlDontFlattenShift = 1,+ SpvSelectionControlMax = 0x7fffffff,+} SpvSelectionControlShift;++typedef enum SpvSelectionControlMask_ {+ SpvSelectionControlMaskNone = 0,+ SpvSelectionControlFlattenMask = 0x00000001,+ SpvSelectionControlDontFlattenMask = 0x00000002,+} SpvSelectionControlMask;++typedef enum SpvLoopControlShift_ {+ SpvLoopControlUnrollShift = 0,+ SpvLoopControlDontUnrollShift = 1,+ SpvLoopControlDependencyInfiniteShift = 2,+ SpvLoopControlDependencyLengthShift = 3,+ SpvLoopControlMinIterationsShift = 4,+ SpvLoopControlMaxIterationsShift = 5,+ SpvLoopControlIterationMultipleShift = 6,+ SpvLoopControlPeelCountShift = 7,+ SpvLoopControlPartialCountShift = 8,+ SpvLoopControlInitiationIntervalINTELShift = 16,+ SpvLoopControlMaxConcurrencyINTELShift = 17,+ SpvLoopControlDependencyArrayINTELShift = 18,+ SpvLoopControlPipelineEnableINTELShift = 19,+ SpvLoopControlLoopCoalesceINTELShift = 20,+ SpvLoopControlMaxInterleavingINTELShift = 21,+ SpvLoopControlSpeculatedIterationsINTELShift = 22,+ SpvLoopControlNoFusionINTELShift = 23,+ SpvLoopControlMax = 0x7fffffff,+} SpvLoopControlShift;++typedef enum SpvLoopControlMask_ {+ SpvLoopControlMaskNone = 0,+ SpvLoopControlUnrollMask = 0x00000001,+ SpvLoopControlDontUnrollMask = 0x00000002,+ SpvLoopControlDependencyInfiniteMask = 0x00000004,+ SpvLoopControlDependencyLengthMask = 0x00000008,+ SpvLoopControlMinIterationsMask = 0x00000010,+ SpvLoopControlMaxIterationsMask = 0x00000020,+ SpvLoopControlIterationMultipleMask = 0x00000040,+ SpvLoopControlPeelCountMask = 0x00000080,+ SpvLoopControlPartialCountMask = 0x00000100,+ SpvLoopControlInitiationIntervalINTELMask = 0x00010000,+ SpvLoopControlMaxConcurrencyINTELMask = 0x00020000,+ SpvLoopControlDependencyArrayINTELMask = 0x00040000,+ SpvLoopControlPipelineEnableINTELMask = 0x00080000,+ SpvLoopControlLoopCoalesceINTELMask = 0x00100000,+ SpvLoopControlMaxInterleavingINTELMask = 0x00200000,+ SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000,+ SpvLoopControlNoFusionINTELMask = 0x00800000,+} SpvLoopControlMask;++typedef enum SpvFunctionControlShift_ {+ SpvFunctionControlInlineShift = 0,+ SpvFunctionControlDontInlineShift = 1,+ SpvFunctionControlPureShift = 2,+ SpvFunctionControlConstShift = 3,+ SpvFunctionControlOptNoneINTELShift = 16,+ SpvFunctionControlMax = 0x7fffffff,+} SpvFunctionControlShift;++typedef enum SpvFunctionControlMask_ {+ SpvFunctionControlMaskNone = 0,+ SpvFunctionControlInlineMask = 0x00000001,+ SpvFunctionControlDontInlineMask = 0x00000002,+ SpvFunctionControlPureMask = 0x00000004,+ SpvFunctionControlConstMask = 0x00000008,+ SpvFunctionControlOptNoneINTELMask = 0x00010000,+} SpvFunctionControlMask;++typedef enum SpvMemorySemanticsShift_ {+ SpvMemorySemanticsAcquireShift = 1,+ SpvMemorySemanticsReleaseShift = 2,+ SpvMemorySemanticsAcquireReleaseShift = 3,+ SpvMemorySemanticsSequentiallyConsistentShift = 4,+ SpvMemorySemanticsUniformMemoryShift = 6,+ SpvMemorySemanticsSubgroupMemoryShift = 7,+ SpvMemorySemanticsWorkgroupMemoryShift = 8,+ SpvMemorySemanticsCrossWorkgroupMemoryShift = 9,+ SpvMemorySemanticsAtomicCounterMemoryShift = 10,+ SpvMemorySemanticsImageMemoryShift = 11,+ SpvMemorySemanticsOutputMemoryShift = 12,+ SpvMemorySemanticsOutputMemoryKHRShift = 12,+ SpvMemorySemanticsMakeAvailableShift = 13,+ SpvMemorySemanticsMakeAvailableKHRShift = 13,+ SpvMemorySemanticsMakeVisibleShift = 14,+ SpvMemorySemanticsMakeVisibleKHRShift = 14,+ SpvMemorySemanticsVolatileShift = 15,+ SpvMemorySemanticsMax = 0x7fffffff,+} SpvMemorySemanticsShift;++typedef enum SpvMemorySemanticsMask_ {+ SpvMemorySemanticsMaskNone = 0,+ SpvMemorySemanticsAcquireMask = 0x00000002,+ SpvMemorySemanticsReleaseMask = 0x00000004,+ SpvMemorySemanticsAcquireReleaseMask = 0x00000008,+ SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010,+ SpvMemorySemanticsUniformMemoryMask = 0x00000040,+ SpvMemorySemanticsSubgroupMemoryMask = 0x00000080,+ SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100,+ SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,+ SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400,+ SpvMemorySemanticsImageMemoryMask = 0x00000800,+ SpvMemorySemanticsOutputMemoryMask = 0x00001000,+ SpvMemorySemanticsOutputMemoryKHRMask = 0x00001000,+ SpvMemorySemanticsMakeAvailableMask = 0x00002000,+ SpvMemorySemanticsMakeAvailableKHRMask = 0x00002000,+ SpvMemorySemanticsMakeVisibleMask = 0x00004000,+ SpvMemorySemanticsMakeVisibleKHRMask = 0x00004000,+ SpvMemorySemanticsVolatileMask = 0x00008000,+} SpvMemorySemanticsMask;++typedef enum SpvMemoryAccessShift_ {+ SpvMemoryAccessVolatileShift = 0,+ SpvMemoryAccessAlignedShift = 1,+ SpvMemoryAccessNontemporalShift = 2,+ SpvMemoryAccessMakePointerAvailableShift = 3,+ SpvMemoryAccessMakePointerAvailableKHRShift = 3,+ SpvMemoryAccessMakePointerVisibleShift = 4,+ SpvMemoryAccessMakePointerVisibleKHRShift = 4,+ SpvMemoryAccessNonPrivatePointerShift = 5,+ SpvMemoryAccessNonPrivatePointerKHRShift = 5,+ SpvMemoryAccessAliasScopeINTELMaskShift = 16,+ SpvMemoryAccessNoAliasINTELMaskShift = 17,+ SpvMemoryAccessMax = 0x7fffffff,+} SpvMemoryAccessShift;++typedef enum SpvMemoryAccessMask_ {+ SpvMemoryAccessMaskNone = 0,+ SpvMemoryAccessVolatileMask = 0x00000001,+ SpvMemoryAccessAlignedMask = 0x00000002,+ SpvMemoryAccessNontemporalMask = 0x00000004,+ SpvMemoryAccessMakePointerAvailableMask = 0x00000008,+ SpvMemoryAccessMakePointerAvailableKHRMask = 0x00000008,+ SpvMemoryAccessMakePointerVisibleMask = 0x00000010,+ SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010,+ SpvMemoryAccessNonPrivatePointerMask = 0x00000020,+ SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020,+ SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000,+ SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000,+} SpvMemoryAccessMask;++typedef enum SpvScope_ {+ SpvScopeCrossDevice = 0,+ SpvScopeDevice = 1,+ SpvScopeWorkgroup = 2,+ SpvScopeSubgroup = 3,+ SpvScopeInvocation = 4,+ SpvScopeQueueFamily = 5,+ SpvScopeQueueFamilyKHR = 5,+ SpvScopeShaderCallKHR = 6,+ SpvScopeMax = 0x7fffffff,+} SpvScope;++typedef enum SpvGroupOperation_ {+ SpvGroupOperationReduce = 0,+ SpvGroupOperationInclusiveScan = 1,+ SpvGroupOperationExclusiveScan = 2,+ SpvGroupOperationClusteredReduce = 3,+ SpvGroupOperationPartitionedReduceNV = 6,+ SpvGroupOperationPartitionedInclusiveScanNV = 7,+ SpvGroupOperationPartitionedExclusiveScanNV = 8,+ SpvGroupOperationMax = 0x7fffffff,+} SpvGroupOperation;++typedef enum SpvKernelEnqueueFlags_ {+ SpvKernelEnqueueFlagsNoWait = 0,+ SpvKernelEnqueueFlagsWaitKernel = 1,+ SpvKernelEnqueueFlagsWaitWorkGroup = 2,+ SpvKernelEnqueueFlagsMax = 0x7fffffff,+} SpvKernelEnqueueFlags;++typedef enum SpvKernelProfilingInfoShift_ {+ SpvKernelProfilingInfoCmdExecTimeShift = 0,+ SpvKernelProfilingInfoMax = 0x7fffffff,+} SpvKernelProfilingInfoShift;++typedef enum SpvKernelProfilingInfoMask_ {+ SpvKernelProfilingInfoMaskNone = 0,+ SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001,+} SpvKernelProfilingInfoMask;++typedef enum SpvCapability_ {+ SpvCapabilityMatrix = 0,+ SpvCapabilityShader = 1,+ SpvCapabilityGeometry = 2,+ SpvCapabilityTessellation = 3,+ SpvCapabilityAddresses = 4,+ SpvCapabilityLinkage = 5,+ SpvCapabilityKernel = 6,+ SpvCapabilityVector16 = 7,+ SpvCapabilityFloat16Buffer = 8,+ SpvCapabilityFloat16 = 9,+ SpvCapabilityFloat64 = 10,+ SpvCapabilityInt64 = 11,+ SpvCapabilityInt64Atomics = 12,+ SpvCapabilityImageBasic = 13,+ SpvCapabilityImageReadWrite = 14,+ SpvCapabilityImageMipmap = 15,+ SpvCapabilityPipes = 17,+ SpvCapabilityGroups = 18,+ SpvCapabilityDeviceEnqueue = 19,+ SpvCapabilityLiteralSampler = 20,+ SpvCapabilityAtomicStorage = 21,+ SpvCapabilityInt16 = 22,+ SpvCapabilityTessellationPointSize = 23,+ SpvCapabilityGeometryPointSize = 24,+ SpvCapabilityImageGatherExtended = 25,+ SpvCapabilityStorageImageMultisample = 27,+ SpvCapabilityUniformBufferArrayDynamicIndexing = 28,+ SpvCapabilitySampledImageArrayDynamicIndexing = 29,+ SpvCapabilityStorageBufferArrayDynamicIndexing = 30,+ SpvCapabilityStorageImageArrayDynamicIndexing = 31,+ SpvCapabilityClipDistance = 32,+ SpvCapabilityCullDistance = 33,+ SpvCapabilityImageCubeArray = 34,+ SpvCapabilitySampleRateShading = 35,+ SpvCapabilityImageRect = 36,+ SpvCapabilitySampledRect = 37,+ SpvCapabilityGenericPointer = 38,+ SpvCapabilityInt8 = 39,+ SpvCapabilityInputAttachment = 40,+ SpvCapabilitySparseResidency = 41,+ SpvCapabilityMinLod = 42,+ SpvCapabilitySampled1D = 43,+ SpvCapabilityImage1D = 44,+ SpvCapabilitySampledCubeArray = 45,+ SpvCapabilitySampledBuffer = 46,+ SpvCapabilityImageBuffer = 47,+ SpvCapabilityImageMSArray = 48,+ SpvCapabilityStorageImageExtendedFormats = 49,+ SpvCapabilityImageQuery = 50,+ SpvCapabilityDerivativeControl = 51,+ SpvCapabilityInterpolationFunction = 52,+ SpvCapabilityTransformFeedback = 53,+ SpvCapabilityGeometryStreams = 54,+ SpvCapabilityStorageImageReadWithoutFormat = 55,+ SpvCapabilityStorageImageWriteWithoutFormat = 56,+ SpvCapabilityMultiViewport = 57,+ SpvCapabilitySubgroupDispatch = 58,+ SpvCapabilityNamedBarrier = 59,+ SpvCapabilityPipeStorage = 60,+ SpvCapabilityGroupNonUniform = 61,+ SpvCapabilityGroupNonUniformVote = 62,+ SpvCapabilityGroupNonUniformArithmetic = 63,+ SpvCapabilityGroupNonUniformBallot = 64,+ SpvCapabilityGroupNonUniformShuffle = 65,+ SpvCapabilityGroupNonUniformShuffleRelative = 66,+ SpvCapabilityGroupNonUniformClustered = 67,+ SpvCapabilityGroupNonUniformQuad = 68,+ SpvCapabilityShaderLayer = 69,+ SpvCapabilityShaderViewportIndex = 70,+ SpvCapabilityUniformDecoration = 71,+ SpvCapabilityFragmentShadingRateKHR = 4422,+ SpvCapabilitySubgroupBallotKHR = 4423,+ SpvCapabilityDrawParameters = 4427,+ SpvCapabilityWorkgroupMemoryExplicitLayoutKHR = 4428,+ SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429,+ SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430,+ SpvCapabilitySubgroupVoteKHR = 4431,+ SpvCapabilityStorageBuffer16BitAccess = 4433,+ SpvCapabilityStorageUniformBufferBlock16 = 4433,+ SpvCapabilityStorageUniform16 = 4434,+ SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434,+ SpvCapabilityStoragePushConstant16 = 4435,+ SpvCapabilityStorageInputOutput16 = 4436,+ SpvCapabilityDeviceGroup = 4437,+ SpvCapabilityMultiView = 4439,+ SpvCapabilityVariablePointersStorageBuffer = 4441,+ SpvCapabilityVariablePointers = 4442,+ SpvCapabilityAtomicStorageOps = 4445,+ SpvCapabilitySampleMaskPostDepthCoverage = 4447,+ SpvCapabilityStorageBuffer8BitAccess = 4448,+ SpvCapabilityUniformAndStorageBuffer8BitAccess = 4449,+ SpvCapabilityStoragePushConstant8 = 4450,+ SpvCapabilityDenormPreserve = 4464,+ SpvCapabilityDenormFlushToZero = 4465,+ SpvCapabilitySignedZeroInfNanPreserve = 4466,+ SpvCapabilityRoundingModeRTE = 4467,+ SpvCapabilityRoundingModeRTZ = 4468,+ SpvCapabilityRayQueryProvisionalKHR = 4471,+ SpvCapabilityRayQueryKHR = 4472,+ SpvCapabilityRayTraversalPrimitiveCullingKHR = 4478,+ SpvCapabilityRayTracingKHR = 4479,+ SpvCapabilityFloat16ImageAMD = 5008,+ SpvCapabilityImageGatherBiasLodAMD = 5009,+ SpvCapabilityFragmentMaskAMD = 5010,+ SpvCapabilityStencilExportEXT = 5013,+ SpvCapabilityImageReadWriteLodAMD = 5015,+ SpvCapabilityInt64ImageEXT = 5016,+ SpvCapabilityShaderClockKHR = 5055,+ SpvCapabilitySampleMaskOverrideCoverageNV = 5249,+ SpvCapabilityGeometryShaderPassthroughNV = 5251,+ SpvCapabilityShaderViewportIndexLayerEXT = 5254,+ SpvCapabilityShaderViewportIndexLayerNV = 5254,+ SpvCapabilityShaderViewportMaskNV = 5255,+ SpvCapabilityShaderStereoViewNV = 5259,+ SpvCapabilityPerViewAttributesNV = 5260,+ SpvCapabilityFragmentFullyCoveredEXT = 5265,+ SpvCapabilityMeshShadingNV = 5266,+ SpvCapabilityImageFootprintNV = 5282,+ SpvCapabilityFragmentBarycentricKHR = 5284,+ SpvCapabilityFragmentBarycentricNV = 5284,+ SpvCapabilityComputeDerivativeGroupQuadsNV = 5288,+ SpvCapabilityFragmentDensityEXT = 5291,+ SpvCapabilityShadingRateNV = 5291,+ SpvCapabilityGroupNonUniformPartitionedNV = 5297,+ SpvCapabilityShaderNonUniform = 5301,+ SpvCapabilityShaderNonUniformEXT = 5301,+ SpvCapabilityRuntimeDescriptorArray = 5302,+ SpvCapabilityRuntimeDescriptorArrayEXT = 5302,+ SpvCapabilityInputAttachmentArrayDynamicIndexing = 5303,+ SpvCapabilityInputAttachmentArrayDynamicIndexingEXT = 5303,+ SpvCapabilityUniformTexelBufferArrayDynamicIndexing = 5304,+ SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304,+ SpvCapabilityStorageTexelBufferArrayDynamicIndexing = 5305,+ SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305,+ SpvCapabilityUniformBufferArrayNonUniformIndexing = 5306,+ SpvCapabilityUniformBufferArrayNonUniformIndexingEXT = 5306,+ SpvCapabilitySampledImageArrayNonUniformIndexing = 5307,+ SpvCapabilitySampledImageArrayNonUniformIndexingEXT = 5307,+ SpvCapabilityStorageBufferArrayNonUniformIndexing = 5308,+ SpvCapabilityStorageBufferArrayNonUniformIndexingEXT = 5308,+ SpvCapabilityStorageImageArrayNonUniformIndexing = 5309,+ SpvCapabilityStorageImageArrayNonUniformIndexingEXT = 5309,+ SpvCapabilityInputAttachmentArrayNonUniformIndexing = 5310,+ SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,+ SpvCapabilityUniformTexelBufferArrayNonUniformIndexing = 5311,+ SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,+ SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,+ SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,+ SpvCapabilityRayTracingNV = 5340,+ SpvCapabilityRayTracingMotionBlurNV = 5341,+ SpvCapabilityVulkanMemoryModel = 5345,+ SpvCapabilityVulkanMemoryModelKHR = 5345,+ SpvCapabilityVulkanMemoryModelDeviceScope = 5346,+ SpvCapabilityVulkanMemoryModelDeviceScopeKHR = 5346,+ SpvCapabilityPhysicalStorageBufferAddresses = 5347,+ SpvCapabilityPhysicalStorageBufferAddressesEXT = 5347,+ SpvCapabilityComputeDerivativeGroupLinearNV = 5350,+ SpvCapabilityRayTracingProvisionalKHR = 5353,+ SpvCapabilityCooperativeMatrixNV = 5357,+ SpvCapabilityFragmentShaderSampleInterlockEXT = 5363,+ SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372,+ SpvCapabilityShaderSMBuiltinsNV = 5373,+ SpvCapabilityFragmentShaderPixelInterlockEXT = 5378,+ SpvCapabilityDemoteToHelperInvocation = 5379,+ SpvCapabilityDemoteToHelperInvocationEXT = 5379,+ SpvCapabilityBindlessTextureNV = 5390,+ SpvCapabilitySubgroupShuffleINTEL = 5568,+ SpvCapabilitySubgroupBufferBlockIOINTEL = 5569,+ SpvCapabilitySubgroupImageBlockIOINTEL = 5570,+ SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579,+ SpvCapabilityRoundToInfinityINTEL = 5582,+ SpvCapabilityFloatingPointModeINTEL = 5583,+ SpvCapabilityIntegerFunctions2INTEL = 5584,+ SpvCapabilityFunctionPointersINTEL = 5603,+ SpvCapabilityIndirectReferencesINTEL = 5604,+ SpvCapabilityAsmINTEL = 5606,+ SpvCapabilityAtomicFloat32MinMaxEXT = 5612,+ SpvCapabilityAtomicFloat64MinMaxEXT = 5613,+ SpvCapabilityAtomicFloat16MinMaxEXT = 5616,+ SpvCapabilityVectorComputeINTEL = 5617,+ SpvCapabilityVectorAnyINTEL = 5619,+ SpvCapabilityExpectAssumeKHR = 5629,+ SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696,+ SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,+ SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,+ SpvCapabilityVariableLengthArrayINTEL = 5817,+ SpvCapabilityFunctionFloatControlINTEL = 5821,+ SpvCapabilityFPGAMemoryAttributesINTEL = 5824,+ SpvCapabilityFPFastMathModeINTEL = 5837,+ SpvCapabilityArbitraryPrecisionIntegersINTEL = 5844,+ SpvCapabilityArbitraryPrecisionFloatingPointINTEL = 5845,+ SpvCapabilityUnstructuredLoopControlsINTEL = 5886,+ SpvCapabilityFPGALoopControlsINTEL = 5888,+ SpvCapabilityKernelAttributesINTEL = 5892,+ SpvCapabilityFPGAKernelAttributesINTEL = 5897,+ SpvCapabilityFPGAMemoryAccessesINTEL = 5898,+ SpvCapabilityFPGAClusterAttributesINTEL = 5904,+ SpvCapabilityLoopFuseINTEL = 5906,+ SpvCapabilityMemoryAccessAliasingINTEL = 5910,+ SpvCapabilityFPGABufferLocationINTEL = 5920,+ SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922,+ SpvCapabilityUSMStorageClassesINTEL = 5935,+ SpvCapabilityIOPipesINTEL = 5943,+ SpvCapabilityBlockingPipesINTEL = 5945,+ SpvCapabilityFPGARegINTEL = 5948,+ SpvCapabilityDotProductInputAll = 6016,+ SpvCapabilityDotProductInputAllKHR = 6016,+ SpvCapabilityDotProductInput4x8Bit = 6017,+ SpvCapabilityDotProductInput4x8BitKHR = 6017,+ SpvCapabilityDotProductInput4x8BitPacked = 6018,+ SpvCapabilityDotProductInput4x8BitPackedKHR = 6018,+ SpvCapabilityDotProduct = 6019,+ SpvCapabilityDotProductKHR = 6019,+ SpvCapabilityRayCullMaskKHR = 6020,+ SpvCapabilityBitInstructions = 6025,+ SpvCapabilityGroupNonUniformRotateKHR = 6026,+ SpvCapabilityAtomicFloat32AddEXT = 6033,+ SpvCapabilityAtomicFloat64AddEXT = 6034,+ SpvCapabilityLongConstantCompositeINTEL = 6089,+ SpvCapabilityOptNoneINTEL = 6094,+ SpvCapabilityAtomicFloat16AddEXT = 6095,+ SpvCapabilityDebugInfoModuleINTEL = 6114,+ SpvCapabilitySplitBarrierINTEL = 6141,+ SpvCapabilityGroupUniformArithmeticKHR = 6400,+ SpvCapabilityMax = 0x7fffffff,+} SpvCapability;++typedef enum SpvRayFlagsShift_ {+ SpvRayFlagsOpaqueKHRShift = 0,+ SpvRayFlagsNoOpaqueKHRShift = 1,+ SpvRayFlagsTerminateOnFirstHitKHRShift = 2,+ SpvRayFlagsSkipClosestHitShaderKHRShift = 3,+ SpvRayFlagsCullBackFacingTrianglesKHRShift = 4,+ SpvRayFlagsCullFrontFacingTrianglesKHRShift = 5,+ SpvRayFlagsCullOpaqueKHRShift = 6,+ SpvRayFlagsCullNoOpaqueKHRShift = 7,+ SpvRayFlagsSkipTrianglesKHRShift = 8,+ SpvRayFlagsSkipAABBsKHRShift = 9,+ SpvRayFlagsMax = 0x7fffffff,+} SpvRayFlagsShift;++typedef enum SpvRayFlagsMask_ {+ SpvRayFlagsMaskNone = 0,+ SpvRayFlagsOpaqueKHRMask = 0x00000001,+ SpvRayFlagsNoOpaqueKHRMask = 0x00000002,+ SpvRayFlagsTerminateOnFirstHitKHRMask = 0x00000004,+ SpvRayFlagsSkipClosestHitShaderKHRMask = 0x00000008,+ SpvRayFlagsCullBackFacingTrianglesKHRMask = 0x00000010,+ SpvRayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020,+ SpvRayFlagsCullOpaqueKHRMask = 0x00000040,+ SpvRayFlagsCullNoOpaqueKHRMask = 0x00000080,+ SpvRayFlagsSkipTrianglesKHRMask = 0x00000100,+ SpvRayFlagsSkipAABBsKHRMask = 0x00000200,+} SpvRayFlagsMask;++typedef enum SpvRayQueryIntersection_ {+ SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR = 0,+ SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR = 1,+ SpvRayQueryIntersectionMax = 0x7fffffff,+} SpvRayQueryIntersection;++typedef enum SpvRayQueryCommittedIntersectionType_ {+ SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0,+ SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1,+ SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2,+ SpvRayQueryCommittedIntersectionTypeMax = 0x7fffffff,+} SpvRayQueryCommittedIntersectionType;++typedef enum SpvRayQueryCandidateIntersectionType_ {+ SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0,+ SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1,+ SpvRayQueryCandidateIntersectionTypeMax = 0x7fffffff,+} SpvRayQueryCandidateIntersectionType;++typedef enum SpvFragmentShadingRateShift_ {+ SpvFragmentShadingRateVertical2PixelsShift = 0,+ SpvFragmentShadingRateVertical4PixelsShift = 1,+ SpvFragmentShadingRateHorizontal2PixelsShift = 2,+ SpvFragmentShadingRateHorizontal4PixelsShift = 3,+ SpvFragmentShadingRateMax = 0x7fffffff,+} SpvFragmentShadingRateShift;++typedef enum SpvFragmentShadingRateMask_ {+ SpvFragmentShadingRateMaskNone = 0,+ SpvFragmentShadingRateVertical2PixelsMask = 0x00000001,+ SpvFragmentShadingRateVertical4PixelsMask = 0x00000002,+ SpvFragmentShadingRateHorizontal2PixelsMask = 0x00000004,+ SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008,+} SpvFragmentShadingRateMask;++typedef enum SpvFPDenormMode_ {+ SpvFPDenormModePreserve = 0,+ SpvFPDenormModeFlushToZero = 1,+ SpvFPDenormModeMax = 0x7fffffff,+} SpvFPDenormMode;++typedef enum SpvFPOperationMode_ {+ SpvFPOperationModeIEEE = 0,+ SpvFPOperationModeALT = 1,+ SpvFPOperationModeMax = 0x7fffffff,+} SpvFPOperationMode;++typedef enum SpvQuantizationModes_ {+ SpvQuantizationModesTRN = 0,+ SpvQuantizationModesTRN_ZERO = 1,+ SpvQuantizationModesRND = 2,+ SpvQuantizationModesRND_ZERO = 3,+ SpvQuantizationModesRND_INF = 4,+ SpvQuantizationModesRND_MIN_INF = 5,+ SpvQuantizationModesRND_CONV = 6,+ SpvQuantizationModesRND_CONV_ODD = 7,+ SpvQuantizationModesMax = 0x7fffffff,+} SpvQuantizationModes;++typedef enum SpvOverflowModes_ {+ SpvOverflowModesWRAP = 0,+ SpvOverflowModesSAT = 1,+ SpvOverflowModesSAT_ZERO = 2,+ SpvOverflowModesSAT_SYM = 3,+ SpvOverflowModesMax = 0x7fffffff,+} SpvOverflowModes;++typedef enum SpvPackedVectorFormat_ {+ SpvPackedVectorFormatPackedVectorFormat4x8Bit = 0,+ SpvPackedVectorFormatPackedVectorFormat4x8BitKHR = 0,+ SpvPackedVectorFormatMax = 0x7fffffff,+} SpvPackedVectorFormat;++typedef enum SpvOp_ {+ SpvOpNop = 0,+ SpvOpUndef = 1,+ SpvOpSourceContinued = 2,+ SpvOpSource = 3,+ SpvOpSourceExtension = 4,+ SpvOpName = 5,+ SpvOpMemberName = 6,+ SpvOpString = 7,+ SpvOpLine = 8,+ SpvOpExtension = 10,+ SpvOpExtInstImport = 11,+ SpvOpExtInst = 12,+ SpvOpMemoryModel = 14,+ SpvOpEntryPoint = 15,+ SpvOpExecutionMode = 16,+ SpvOpCapability = 17,+ SpvOpTypeVoid = 19,+ SpvOpTypeBool = 20,+ SpvOpTypeInt = 21,+ SpvOpTypeFloat = 22,+ SpvOpTypeVector = 23,+ SpvOpTypeMatrix = 24,+ SpvOpTypeImage = 25,+ SpvOpTypeSampler = 26,+ SpvOpTypeSampledImage = 27,+ SpvOpTypeArray = 28,+ SpvOpTypeRuntimeArray = 29,+ SpvOpTypeStruct = 30,+ SpvOpTypeOpaque = 31,+ SpvOpTypePointer = 32,+ SpvOpTypeFunction = 33,+ SpvOpTypeEvent = 34,+ SpvOpTypeDeviceEvent = 35,+ SpvOpTypeReserveId = 36,+ SpvOpTypeQueue = 37,+ SpvOpTypePipe = 38,+ SpvOpTypeForwardPointer = 39,+ SpvOpConstantTrue = 41,+ SpvOpConstantFalse = 42,+ SpvOpConstant = 43,+ SpvOpConstantComposite = 44,+ SpvOpConstantSampler = 45,+ SpvOpConstantNull = 46,+ SpvOpSpecConstantTrue = 48,+ SpvOpSpecConstantFalse = 49,+ SpvOpSpecConstant = 50,+ SpvOpSpecConstantComposite = 51,+ SpvOpSpecConstantOp = 52,+ SpvOpFunction = 54,+ SpvOpFunctionParameter = 55,+ SpvOpFunctionEnd = 56,+ SpvOpFunctionCall = 57,+ SpvOpVariable = 59,+ SpvOpImageTexelPointer = 60,+ SpvOpLoad = 61,+ SpvOpStore = 62,+ SpvOpCopyMemory = 63,+ SpvOpCopyMemorySized = 64,+ SpvOpAccessChain = 65,+ SpvOpInBoundsAccessChain = 66,+ SpvOpPtrAccessChain = 67,+ SpvOpArrayLength = 68,+ SpvOpGenericPtrMemSemantics = 69,+ SpvOpInBoundsPtrAccessChain = 70,+ SpvOpDecorate = 71,+ SpvOpMemberDecorate = 72,+ SpvOpDecorationGroup = 73,+ SpvOpGroupDecorate = 74,+ SpvOpGroupMemberDecorate = 75,+ SpvOpVectorExtractDynamic = 77,+ SpvOpVectorInsertDynamic = 78,+ SpvOpVectorShuffle = 79,+ SpvOpCompositeConstruct = 80,+ SpvOpCompositeExtract = 81,+ SpvOpCompositeInsert = 82,+ SpvOpCopyObject = 83,+ SpvOpTranspose = 84,+ SpvOpSampledImage = 86,+ SpvOpImageSampleImplicitLod = 87,+ SpvOpImageSampleExplicitLod = 88,+ SpvOpImageSampleDrefImplicitLod = 89,+ SpvOpImageSampleDrefExplicitLod = 90,+ SpvOpImageSampleProjImplicitLod = 91,+ SpvOpImageSampleProjExplicitLod = 92,+ SpvOpImageSampleProjDrefImplicitLod = 93,+ SpvOpImageSampleProjDrefExplicitLod = 94,+ SpvOpImageFetch = 95,+ SpvOpImageGather = 96,+ SpvOpImageDrefGather = 97,+ SpvOpImageRead = 98,+ SpvOpImageWrite = 99,+ SpvOpImage = 100,+ SpvOpImageQueryFormat = 101,+ SpvOpImageQueryOrder = 102,+ SpvOpImageQuerySizeLod = 103,+ SpvOpImageQuerySize = 104,+ SpvOpImageQueryLod = 105,+ SpvOpImageQueryLevels = 106,+ SpvOpImageQuerySamples = 107,+ SpvOpConvertFToU = 109,+ SpvOpConvertFToS = 110,+ SpvOpConvertSToF = 111,+ SpvOpConvertUToF = 112,+ SpvOpUConvert = 113,+ SpvOpSConvert = 114,+ SpvOpFConvert = 115,+ SpvOpQuantizeToF16 = 116,+ SpvOpConvertPtrToU = 117,+ SpvOpSatConvertSToU = 118,+ SpvOpSatConvertUToS = 119,+ SpvOpConvertUToPtr = 120,+ SpvOpPtrCastToGeneric = 121,+ SpvOpGenericCastToPtr = 122,+ SpvOpGenericCastToPtrExplicit = 123,+ SpvOpBitcast = 124,+ SpvOpSNegate = 126,+ SpvOpFNegate = 127,+ SpvOpIAdd = 128,+ SpvOpFAdd = 129,+ SpvOpISub = 130,+ SpvOpFSub = 131,+ SpvOpIMul = 132,+ SpvOpFMul = 133,+ SpvOpUDiv = 134,+ SpvOpSDiv = 135,+ SpvOpFDiv = 136,+ SpvOpUMod = 137,+ SpvOpSRem = 138,+ SpvOpSMod = 139,+ SpvOpFRem = 140,+ SpvOpFMod = 141,+ SpvOpVectorTimesScalar = 142,+ SpvOpMatrixTimesScalar = 143,+ SpvOpVectorTimesMatrix = 144,+ SpvOpMatrixTimesVector = 145,+ SpvOpMatrixTimesMatrix = 146,+ SpvOpOuterProduct = 147,+ SpvOpDot = 148,+ SpvOpIAddCarry = 149,+ SpvOpISubBorrow = 150,+ SpvOpUMulExtended = 151,+ SpvOpSMulExtended = 152,+ SpvOpAny = 154,+ SpvOpAll = 155,+ SpvOpIsNan = 156,+ SpvOpIsInf = 157,+ SpvOpIsFinite = 158,+ SpvOpIsNormal = 159,+ SpvOpSignBitSet = 160,+ SpvOpLessOrGreater = 161,+ SpvOpOrdered = 162,+ SpvOpUnordered = 163,+ SpvOpLogicalEqual = 164,+ SpvOpLogicalNotEqual = 165,+ SpvOpLogicalOr = 166,+ SpvOpLogicalAnd = 167,+ SpvOpLogicalNot = 168,+ SpvOpSelect = 169,+ SpvOpIEqual = 170,+ SpvOpINotEqual = 171,+ SpvOpUGreaterThan = 172,+ SpvOpSGreaterThan = 173,+ SpvOpUGreaterThanEqual = 174,+ SpvOpSGreaterThanEqual = 175,+ SpvOpULessThan = 176,+ SpvOpSLessThan = 177,+ SpvOpULessThanEqual = 178,+ SpvOpSLessThanEqual = 179,+ SpvOpFOrdEqual = 180,+ SpvOpFUnordEqual = 181,+ SpvOpFOrdNotEqual = 182,+ SpvOpFUnordNotEqual = 183,+ SpvOpFOrdLessThan = 184,+ SpvOpFUnordLessThan = 185,+ SpvOpFOrdGreaterThan = 186,+ SpvOpFUnordGreaterThan = 187,+ SpvOpFOrdLessThanEqual = 188,+ SpvOpFUnordLessThanEqual = 189,+ SpvOpFOrdGreaterThanEqual = 190,+ SpvOpFUnordGreaterThanEqual = 191,+ SpvOpShiftRightLogical = 194,+ SpvOpShiftRightArithmetic = 195,+ SpvOpShiftLeftLogical = 196,+ SpvOpBitwiseOr = 197,+ SpvOpBitwiseXor = 198,+ SpvOpBitwiseAnd = 199,+ SpvOpNot = 200,+ SpvOpBitFieldInsert = 201,+ SpvOpBitFieldSExtract = 202,+ SpvOpBitFieldUExtract = 203,+ SpvOpBitReverse = 204,+ SpvOpBitCount = 205,+ SpvOpDPdx = 207,+ SpvOpDPdy = 208,+ SpvOpFwidth = 209,+ SpvOpDPdxFine = 210,+ SpvOpDPdyFine = 211,+ SpvOpFwidthFine = 212,+ SpvOpDPdxCoarse = 213,+ SpvOpDPdyCoarse = 214,+ SpvOpFwidthCoarse = 215,+ SpvOpEmitVertex = 218,+ SpvOpEndPrimitive = 219,+ SpvOpEmitStreamVertex = 220,+ SpvOpEndStreamPrimitive = 221,+ SpvOpControlBarrier = 224,+ SpvOpMemoryBarrier = 225,+ SpvOpAtomicLoad = 227,+ SpvOpAtomicStore = 228,+ SpvOpAtomicExchange = 229,+ SpvOpAtomicCompareExchange = 230,+ SpvOpAtomicCompareExchangeWeak = 231,+ SpvOpAtomicIIncrement = 232,+ SpvOpAtomicIDecrement = 233,+ SpvOpAtomicIAdd = 234,+ SpvOpAtomicISub = 235,+ SpvOpAtomicSMin = 236,+ SpvOpAtomicUMin = 237,+ SpvOpAtomicSMax = 238,+ SpvOpAtomicUMax = 239,+ SpvOpAtomicAnd = 240,+ SpvOpAtomicOr = 241,+ SpvOpAtomicXor = 242,+ SpvOpPhi = 245,+ SpvOpLoopMerge = 246,+ SpvOpSelectionMerge = 247,+ SpvOpLabel = 248,+ SpvOpBranch = 249,+ SpvOpBranchConditional = 250,+ SpvOpSwitch = 251,+ SpvOpKill = 252,+ SpvOpReturn = 253,+ SpvOpReturnValue = 254,+ SpvOpUnreachable = 255,+ SpvOpLifetimeStart = 256,+ SpvOpLifetimeStop = 257,+ SpvOpGroupAsyncCopy = 259,+ SpvOpGroupWaitEvents = 260,+ SpvOpGroupAll = 261,+ SpvOpGroupAny = 262,+ SpvOpGroupBroadcast = 263,+ SpvOpGroupIAdd = 264,+ SpvOpGroupFAdd = 265,+ SpvOpGroupFMin = 266,+ SpvOpGroupUMin = 267,+ SpvOpGroupSMin = 268,+ SpvOpGroupFMax = 269,+ SpvOpGroupUMax = 270,+ SpvOpGroupSMax = 271,+ SpvOpReadPipe = 274,+ SpvOpWritePipe = 275,+ SpvOpReservedReadPipe = 276,+ SpvOpReservedWritePipe = 277,+ SpvOpReserveReadPipePackets = 278,+ SpvOpReserveWritePipePackets = 279,+ SpvOpCommitReadPipe = 280,+ SpvOpCommitWritePipe = 281,+ SpvOpIsValidReserveId = 282,+ SpvOpGetNumPipePackets = 283,+ SpvOpGetMaxPipePackets = 284,+ SpvOpGroupReserveReadPipePackets = 285,+ SpvOpGroupReserveWritePipePackets = 286,+ SpvOpGroupCommitReadPipe = 287,+ SpvOpGroupCommitWritePipe = 288,+ SpvOpEnqueueMarker = 291,+ SpvOpEnqueueKernel = 292,+ SpvOpGetKernelNDrangeSubGroupCount = 293,+ SpvOpGetKernelNDrangeMaxSubGroupSize = 294,+ SpvOpGetKernelWorkGroupSize = 295,+ SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296,+ SpvOpRetainEvent = 297,+ SpvOpReleaseEvent = 298,+ SpvOpCreateUserEvent = 299,+ SpvOpIsValidEvent = 300,+ SpvOpSetUserEventStatus = 301,+ SpvOpCaptureEventProfilingInfo = 302,+ SpvOpGetDefaultQueue = 303,+ SpvOpBuildNDRange = 304,+ SpvOpImageSparseSampleImplicitLod = 305,+ SpvOpImageSparseSampleExplicitLod = 306,+ SpvOpImageSparseSampleDrefImplicitLod = 307,+ SpvOpImageSparseSampleDrefExplicitLod = 308,+ SpvOpImageSparseSampleProjImplicitLod = 309,+ SpvOpImageSparseSampleProjExplicitLod = 310,+ SpvOpImageSparseSampleProjDrefImplicitLod = 311,+ SpvOpImageSparseSampleProjDrefExplicitLod = 312,+ SpvOpImageSparseFetch = 313,+ SpvOpImageSparseGather = 314,+ SpvOpImageSparseDrefGather = 315,+ SpvOpImageSparseTexelsResident = 316,+ SpvOpNoLine = 317,+ SpvOpAtomicFlagTestAndSet = 318,+ SpvOpAtomicFlagClear = 319,+ SpvOpImageSparseRead = 320,+ SpvOpSizeOf = 321,+ SpvOpTypePipeStorage = 322,+ SpvOpConstantPipeStorage = 323,+ SpvOpCreatePipeFromPipeStorage = 324,+ SpvOpGetKernelLocalSizeForSubgroupCount = 325,+ SpvOpGetKernelMaxNumSubgroups = 326,+ SpvOpTypeNamedBarrier = 327,+ SpvOpNamedBarrierInitialize = 328,+ SpvOpMemoryNamedBarrier = 329,+ SpvOpModuleProcessed = 330,+ SpvOpExecutionModeId = 331,+ SpvOpDecorateId = 332,+ SpvOpGroupNonUniformElect = 333,+ SpvOpGroupNonUniformAll = 334,+ SpvOpGroupNonUniformAny = 335,+ SpvOpGroupNonUniformAllEqual = 336,+ SpvOpGroupNonUniformBroadcast = 337,+ SpvOpGroupNonUniformBroadcastFirst = 338,+ SpvOpGroupNonUniformBallot = 339,+ SpvOpGroupNonUniformInverseBallot = 340,+ SpvOpGroupNonUniformBallotBitExtract = 341,+ SpvOpGroupNonUniformBallotBitCount = 342,+ SpvOpGroupNonUniformBallotFindLSB = 343,+ SpvOpGroupNonUniformBallotFindMSB = 344,+ SpvOpGroupNonUniformShuffle = 345,+ SpvOpGroupNonUniformShuffleXor = 346,+ SpvOpGroupNonUniformShuffleUp = 347,+ SpvOpGroupNonUniformShuffleDown = 348,+ SpvOpGroupNonUniformIAdd = 349,+ SpvOpGroupNonUniformFAdd = 350,+ SpvOpGroupNonUniformIMul = 351,+ SpvOpGroupNonUniformFMul = 352,+ SpvOpGroupNonUniformSMin = 353,+ SpvOpGroupNonUniformUMin = 354,+ SpvOpGroupNonUniformFMin = 355,+ SpvOpGroupNonUniformSMax = 356,+ SpvOpGroupNonUniformUMax = 357,+ SpvOpGroupNonUniformFMax = 358,+ SpvOpGroupNonUniformBitwiseAnd = 359,+ SpvOpGroupNonUniformBitwiseOr = 360,+ SpvOpGroupNonUniformBitwiseXor = 361,+ SpvOpGroupNonUniformLogicalAnd = 362,+ SpvOpGroupNonUniformLogicalOr = 363,+ SpvOpGroupNonUniformLogicalXor = 364,+ SpvOpGroupNonUniformQuadBroadcast = 365,+ SpvOpGroupNonUniformQuadSwap = 366,+ SpvOpCopyLogical = 400,+ SpvOpPtrEqual = 401,+ SpvOpPtrNotEqual = 402,+ SpvOpPtrDiff = 403,+ SpvOpTerminateInvocation = 4416,+ SpvOpSubgroupBallotKHR = 4421,+ SpvOpSubgroupFirstInvocationKHR = 4422,+ SpvOpSubgroupAllKHR = 4428,+ SpvOpSubgroupAnyKHR = 4429,+ SpvOpSubgroupAllEqualKHR = 4430,+ SpvOpGroupNonUniformRotateKHR = 4431,+ SpvOpSubgroupReadInvocationKHR = 4432,+ SpvOpTraceRayKHR = 4445,+ SpvOpExecuteCallableKHR = 4446,+ SpvOpConvertUToAccelerationStructureKHR = 4447,+ SpvOpIgnoreIntersectionKHR = 4448,+ SpvOpTerminateRayKHR = 4449,+ SpvOpSDot = 4450,+ SpvOpSDotKHR = 4450,+ SpvOpUDot = 4451,+ SpvOpUDotKHR = 4451,+ SpvOpSUDot = 4452,+ SpvOpSUDotKHR = 4452,+ SpvOpSDotAccSat = 4453,+ SpvOpSDotAccSatKHR = 4453,+ SpvOpUDotAccSat = 4454,+ SpvOpUDotAccSatKHR = 4454,+ SpvOpSUDotAccSat = 4455,+ SpvOpSUDotAccSatKHR = 4455,+ SpvOpTypeRayQueryKHR = 4472,+ SpvOpRayQueryInitializeKHR = 4473,+ SpvOpRayQueryTerminateKHR = 4474,+ SpvOpRayQueryGenerateIntersectionKHR = 4475,+ SpvOpRayQueryConfirmIntersectionKHR = 4476,+ SpvOpRayQueryProceedKHR = 4477,+ SpvOpRayQueryGetIntersectionTypeKHR = 4479,+ SpvOpGroupIAddNonUniformAMD = 5000,+ SpvOpGroupFAddNonUniformAMD = 5001,+ SpvOpGroupFMinNonUniformAMD = 5002,+ SpvOpGroupUMinNonUniformAMD = 5003,+ SpvOpGroupSMinNonUniformAMD = 5004,+ SpvOpGroupFMaxNonUniformAMD = 5005,+ SpvOpGroupUMaxNonUniformAMD = 5006,+ SpvOpGroupSMaxNonUniformAMD = 5007,+ SpvOpFragmentMaskFetchAMD = 5011,+ SpvOpFragmentFetchAMD = 5012,+ SpvOpReadClockKHR = 5056,+ SpvOpImageSampleFootprintNV = 5283,+ SpvOpGroupNonUniformPartitionNV = 5296,+ SpvOpWritePackedPrimitiveIndices4x8NV = 5299,+ SpvOpReportIntersectionKHR = 5334,+ SpvOpReportIntersectionNV = 5334,+ SpvOpIgnoreIntersectionNV = 5335,+ SpvOpTerminateRayNV = 5336,+ SpvOpTraceNV = 5337,+ SpvOpTraceMotionNV = 5338,+ SpvOpTraceRayMotionNV = 5339,+ SpvOpTypeAccelerationStructureKHR = 5341,+ SpvOpTypeAccelerationStructureNV = 5341,+ SpvOpExecuteCallableNV = 5344,+ SpvOpTypeCooperativeMatrixNV = 5358,+ SpvOpCooperativeMatrixLoadNV = 5359,+ SpvOpCooperativeMatrixStoreNV = 5360,+ SpvOpCooperativeMatrixMulAddNV = 5361,+ SpvOpCooperativeMatrixLengthNV = 5362,+ SpvOpBeginInvocationInterlockEXT = 5364,+ SpvOpEndInvocationInterlockEXT = 5365,+ SpvOpDemoteToHelperInvocation = 5380,+ SpvOpDemoteToHelperInvocationEXT = 5380,+ SpvOpIsHelperInvocationEXT = 5381,+ SpvOpConvertUToImageNV = 5391,+ SpvOpConvertUToSamplerNV = 5392,+ SpvOpConvertImageToUNV = 5393,+ SpvOpConvertSamplerToUNV = 5394,+ SpvOpConvertUToSampledImageNV = 5395,+ SpvOpConvertSampledImageToUNV = 5396,+ SpvOpSamplerImageAddressingModeNV = 5397,+ SpvOpSubgroupShuffleINTEL = 5571,+ SpvOpSubgroupShuffleDownINTEL = 5572,+ SpvOpSubgroupShuffleUpINTEL = 5573,+ SpvOpSubgroupShuffleXorINTEL = 5574,+ SpvOpSubgroupBlockReadINTEL = 5575,+ SpvOpSubgroupBlockWriteINTEL = 5576,+ SpvOpSubgroupImageBlockReadINTEL = 5577,+ SpvOpSubgroupImageBlockWriteINTEL = 5578,+ SpvOpSubgroupImageMediaBlockReadINTEL = 5580,+ SpvOpSubgroupImageMediaBlockWriteINTEL = 5581,+ SpvOpUCountLeadingZerosINTEL = 5585,+ SpvOpUCountTrailingZerosINTEL = 5586,+ SpvOpAbsISubINTEL = 5587,+ SpvOpAbsUSubINTEL = 5588,+ SpvOpIAddSatINTEL = 5589,+ SpvOpUAddSatINTEL = 5590,+ SpvOpIAverageINTEL = 5591,+ SpvOpUAverageINTEL = 5592,+ SpvOpIAverageRoundedINTEL = 5593,+ SpvOpUAverageRoundedINTEL = 5594,+ SpvOpISubSatINTEL = 5595,+ SpvOpUSubSatINTEL = 5596,+ SpvOpIMul32x16INTEL = 5597,+ SpvOpUMul32x16INTEL = 5598,+ SpvOpConstantFunctionPointerINTEL = 5600,+ SpvOpFunctionPointerCallINTEL = 5601,+ SpvOpAsmTargetINTEL = 5609,+ SpvOpAsmINTEL = 5610,+ SpvOpAsmCallINTEL = 5611,+ SpvOpAtomicFMinEXT = 5614,+ SpvOpAtomicFMaxEXT = 5615,+ SpvOpAssumeTrueKHR = 5630,+ SpvOpExpectKHR = 5631,+ SpvOpDecorateString = 5632,+ SpvOpDecorateStringGOOGLE = 5632,+ SpvOpMemberDecorateString = 5633,+ SpvOpMemberDecorateStringGOOGLE = 5633,+ SpvOpVmeImageINTEL = 5699,+ SpvOpTypeVmeImageINTEL = 5700,+ SpvOpTypeAvcImePayloadINTEL = 5701,+ SpvOpTypeAvcRefPayloadINTEL = 5702,+ SpvOpTypeAvcSicPayloadINTEL = 5703,+ SpvOpTypeAvcMcePayloadINTEL = 5704,+ SpvOpTypeAvcMceResultINTEL = 5705,+ SpvOpTypeAvcImeResultINTEL = 5706,+ SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707,+ SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708,+ SpvOpTypeAvcImeSingleReferenceStreaminINTEL = 5709,+ SpvOpTypeAvcImeDualReferenceStreaminINTEL = 5710,+ SpvOpTypeAvcRefResultINTEL = 5711,+ SpvOpTypeAvcSicResultINTEL = 5712,+ SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713,+ SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714,+ SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715,+ SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716,+ SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717,+ SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718,+ SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719,+ SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720,+ SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721,+ SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722,+ SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723,+ SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724,+ SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725,+ SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726,+ SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727,+ SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728,+ SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729,+ SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730,+ SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731,+ SpvOpSubgroupAvcMceConvertToImePayloadINTEL = 5732,+ SpvOpSubgroupAvcMceConvertToImeResultINTEL = 5733,+ SpvOpSubgroupAvcMceConvertToRefPayloadINTEL = 5734,+ SpvOpSubgroupAvcMceConvertToRefResultINTEL = 5735,+ SpvOpSubgroupAvcMceConvertToSicPayloadINTEL = 5736,+ SpvOpSubgroupAvcMceConvertToSicResultINTEL = 5737,+ SpvOpSubgroupAvcMceGetMotionVectorsINTEL = 5738,+ SpvOpSubgroupAvcMceGetInterDistortionsINTEL = 5739,+ SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740,+ SpvOpSubgroupAvcMceGetInterMajorShapeINTEL = 5741,+ SpvOpSubgroupAvcMceGetInterMinorShapeINTEL = 5742,+ SpvOpSubgroupAvcMceGetInterDirectionsINTEL = 5743,+ SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744,+ SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745,+ SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746,+ SpvOpSubgroupAvcImeInitializeINTEL = 5747,+ SpvOpSubgroupAvcImeSetSingleReferenceINTEL = 5748,+ SpvOpSubgroupAvcImeSetDualReferenceINTEL = 5749,+ SpvOpSubgroupAvcImeRefWindowSizeINTEL = 5750,+ SpvOpSubgroupAvcImeAdjustRefOffsetINTEL = 5751,+ SpvOpSubgroupAvcImeConvertToMcePayloadINTEL = 5752,+ SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753,+ SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754,+ SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755,+ SpvOpSubgroupAvcImeSetWeightedSadINTEL = 5756,+ SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757,+ SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758,+ SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759,+ SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760,+ SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761,+ SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762,+ SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763,+ SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764,+ SpvOpSubgroupAvcImeConvertToMceResultINTEL = 5765,+ SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766,+ SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767,+ SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768,+ SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769,+ SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770,+ SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771,+ SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772,+ SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773,+ SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774,+ SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775,+ SpvOpSubgroupAvcImeGetBorderReachedINTEL = 5776,+ SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777,+ SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778,+ SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779,+ SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780,+ SpvOpSubgroupAvcFmeInitializeINTEL = 5781,+ SpvOpSubgroupAvcBmeInitializeINTEL = 5782,+ SpvOpSubgroupAvcRefConvertToMcePayloadINTEL = 5783,+ SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784,+ SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785,+ SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786,+ SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787,+ SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788,+ SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789,+ SpvOpSubgroupAvcRefConvertToMceResultINTEL = 5790,+ SpvOpSubgroupAvcSicInitializeINTEL = 5791,+ SpvOpSubgroupAvcSicConfigureSkcINTEL = 5792,+ SpvOpSubgroupAvcSicConfigureIpeLumaINTEL = 5793,+ SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794,+ SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795,+ SpvOpSubgroupAvcSicConvertToMcePayloadINTEL = 5796,+ SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797,+ SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798,+ SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799,+ SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800,+ SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801,+ SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802,+ SpvOpSubgroupAvcSicEvaluateIpeINTEL = 5803,+ SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804,+ SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805,+ SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806,+ SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807,+ SpvOpSubgroupAvcSicConvertToMceResultINTEL = 5808,+ SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809,+ SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810,+ SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811,+ SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812,+ SpvOpSubgroupAvcSicGetIpeChromaModeINTEL = 5813,+ SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,+ SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,+ SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816,+ SpvOpVariableLengthArrayINTEL = 5818,+ SpvOpSaveMemoryINTEL = 5819,+ SpvOpRestoreMemoryINTEL = 5820,+ SpvOpArbitraryFloatSinCosPiINTEL = 5840,+ SpvOpArbitraryFloatCastINTEL = 5841,+ SpvOpArbitraryFloatCastFromIntINTEL = 5842,+ SpvOpArbitraryFloatCastToIntINTEL = 5843,+ SpvOpArbitraryFloatAddINTEL = 5846,+ SpvOpArbitraryFloatSubINTEL = 5847,+ SpvOpArbitraryFloatMulINTEL = 5848,+ SpvOpArbitraryFloatDivINTEL = 5849,+ SpvOpArbitraryFloatGTINTEL = 5850,+ SpvOpArbitraryFloatGEINTEL = 5851,+ SpvOpArbitraryFloatLTINTEL = 5852,+ SpvOpArbitraryFloatLEINTEL = 5853,+ SpvOpArbitraryFloatEQINTEL = 5854,+ SpvOpArbitraryFloatRecipINTEL = 5855,+ SpvOpArbitraryFloatRSqrtINTEL = 5856,+ SpvOpArbitraryFloatCbrtINTEL = 5857,+ SpvOpArbitraryFloatHypotINTEL = 5858,+ SpvOpArbitraryFloatSqrtINTEL = 5859,+ SpvOpArbitraryFloatLogINTEL = 5860,+ SpvOpArbitraryFloatLog2INTEL = 5861,+ SpvOpArbitraryFloatLog10INTEL = 5862,+ SpvOpArbitraryFloatLog1pINTEL = 5863,+ SpvOpArbitraryFloatExpINTEL = 5864,+ SpvOpArbitraryFloatExp2INTEL = 5865,+ SpvOpArbitraryFloatExp10INTEL = 5866,+ SpvOpArbitraryFloatExpm1INTEL = 5867,+ SpvOpArbitraryFloatSinINTEL = 5868,+ SpvOpArbitraryFloatCosINTEL = 5869,+ SpvOpArbitraryFloatSinCosINTEL = 5870,+ SpvOpArbitraryFloatSinPiINTEL = 5871,+ SpvOpArbitraryFloatCosPiINTEL = 5872,+ SpvOpArbitraryFloatASinINTEL = 5873,+ SpvOpArbitraryFloatASinPiINTEL = 5874,+ SpvOpArbitraryFloatACosINTEL = 5875,+ SpvOpArbitraryFloatACosPiINTEL = 5876,+ SpvOpArbitraryFloatATanINTEL = 5877,+ SpvOpArbitraryFloatATanPiINTEL = 5878,+ SpvOpArbitraryFloatATan2INTEL = 5879,+ SpvOpArbitraryFloatPowINTEL = 5880,+ SpvOpArbitraryFloatPowRINTEL = 5881,+ SpvOpArbitraryFloatPowNINTEL = 5882,+ SpvOpLoopControlINTEL = 5887,+ SpvOpAliasDomainDeclINTEL = 5911,+ SpvOpAliasScopeDeclINTEL = 5912,+ SpvOpAliasScopeListDeclINTEL = 5913,+ SpvOpFixedSqrtINTEL = 5923,+ SpvOpFixedRecipINTEL = 5924,+ SpvOpFixedRsqrtINTEL = 5925,+ SpvOpFixedSinINTEL = 5926,+ SpvOpFixedCosINTEL = 5927,+ SpvOpFixedSinCosINTEL = 5928,+ SpvOpFixedSinPiINTEL = 5929,+ SpvOpFixedCosPiINTEL = 5930,+ SpvOpFixedSinCosPiINTEL = 5931,+ SpvOpFixedLogINTEL = 5932,+ SpvOpFixedExpINTEL = 5933,+ SpvOpPtrCastToCrossWorkgroupINTEL = 5934,+ SpvOpCrossWorkgroupCastToPtrINTEL = 5938,+ SpvOpReadPipeBlockingINTEL = 5946,+ SpvOpWritePipeBlockingINTEL = 5947,+ SpvOpFPGARegINTEL = 5949,+ SpvOpRayQueryGetRayTMinKHR = 6016,+ SpvOpRayQueryGetRayFlagsKHR = 6017,+ SpvOpRayQueryGetIntersectionTKHR = 6018,+ SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019,+ SpvOpRayQueryGetIntersectionInstanceIdKHR = 6020,+ SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021,+ SpvOpRayQueryGetIntersectionGeometryIndexKHR = 6022,+ SpvOpRayQueryGetIntersectionPrimitiveIndexKHR = 6023,+ SpvOpRayQueryGetIntersectionBarycentricsKHR = 6024,+ SpvOpRayQueryGetIntersectionFrontFaceKHR = 6025,+ SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026,+ SpvOpRayQueryGetIntersectionObjectRayDirectionKHR = 6027,+ SpvOpRayQueryGetIntersectionObjectRayOriginKHR = 6028,+ SpvOpRayQueryGetWorldRayDirectionKHR = 6029,+ SpvOpRayQueryGetWorldRayOriginKHR = 6030,+ SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031,+ SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032,+ SpvOpAtomicFAddEXT = 6035,+ SpvOpTypeBufferSurfaceINTEL = 6086,+ SpvOpTypeStructContinuedINTEL = 6090,+ SpvOpConstantCompositeContinuedINTEL = 6091,+ SpvOpSpecConstantCompositeContinuedINTEL = 6092,+ SpvOpControlBarrierArriveINTEL = 6142,+ SpvOpControlBarrierWaitINTEL = 6143,+ SpvOpGroupIMulKHR = 6401,+ SpvOpGroupFMulKHR = 6402,+ SpvOpGroupBitwiseAndKHR = 6403,+ SpvOpGroupBitwiseOrKHR = 6404,+ SpvOpGroupBitwiseXorKHR = 6405,+ SpvOpGroupLogicalAndKHR = 6406,+ SpvOpGroupLogicalOrKHR = 6407,+ SpvOpGroupLogicalXorKHR = 6408,+ SpvOpMax = 0x7fffffff,+} SpvOp;++#ifdef SPV_ENABLE_UTILITY_CODE+#ifndef __cplusplus+#include <stdbool.h>+#endif+inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) {+ *hasResult = *hasResultType = false;+ switch (opcode) {+ default: /* unknown opcode */ break;+ case SpvOpNop: *hasResult = false; *hasResultType = false; break;+ case SpvOpUndef: *hasResult = true; *hasResultType = true; break;+ case SpvOpSourceContinued: *hasResult = false; *hasResultType = false; break;+ case SpvOpSource: *hasResult = false; *hasResultType = false; break;+ case SpvOpSourceExtension: *hasResult = false; *hasResultType = false; break;+ case SpvOpName: *hasResult = false; *hasResultType = false; break;+ case SpvOpMemberName: *hasResult = false; *hasResultType = false; break;+ case SpvOpString: *hasResult = true; *hasResultType = false; break;+ case SpvOpLine: *hasResult = false; *hasResultType = false; break;+ case SpvOpExtension: *hasResult = false; *hasResultType = false; break;+ case SpvOpExtInstImport: *hasResult = true; *hasResultType = false; break;+ case SpvOpExtInst: *hasResult = true; *hasResultType = true; break;+ case SpvOpMemoryModel: *hasResult = false; *hasResultType = false; break;+ case SpvOpEntryPoint: *hasResult = false; *hasResultType = false; break;+ case SpvOpExecutionMode: *hasResult = false; *hasResultType = false; break;+ case SpvOpCapability: *hasResult = false; *hasResultType = false; break;+ case SpvOpTypeVoid: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeBool: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeInt: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeFloat: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeVector: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeMatrix: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeImage: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeSampler: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeSampledImage: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeArray: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeStruct: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeOpaque: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypePointer: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeFunction: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeEvent: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeReserveId: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeQueue: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypePipe: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeForwardPointer: *hasResult = false; *hasResultType = false; break;+ case SpvOpConstantTrue: *hasResult = true; *hasResultType = true; break;+ case SpvOpConstantFalse: *hasResult = true; *hasResultType = true; break;+ case SpvOpConstant: *hasResult = true; *hasResultType = true; break;+ case SpvOpConstantComposite: *hasResult = true; *hasResultType = true; break;+ case SpvOpConstantSampler: *hasResult = true; *hasResultType = true; break;+ case SpvOpConstantNull: *hasResult = true; *hasResultType = true; break;+ case SpvOpSpecConstantTrue: *hasResult = true; *hasResultType = true; break;+ case SpvOpSpecConstantFalse: *hasResult = true; *hasResultType = true; break;+ case SpvOpSpecConstant: *hasResult = true; *hasResultType = true; break;+ case SpvOpSpecConstantComposite: *hasResult = true; *hasResultType = true; break;+ case SpvOpSpecConstantOp: *hasResult = true; *hasResultType = true; break;+ case SpvOpFunction: *hasResult = true; *hasResultType = true; break;+ case SpvOpFunctionParameter: *hasResult = true; *hasResultType = true; break;+ case SpvOpFunctionEnd: *hasResult = false; *hasResultType = false; break;+ case SpvOpFunctionCall: *hasResult = true; *hasResultType = true; break;+ case SpvOpVariable: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageTexelPointer: *hasResult = true; *hasResultType = true; break;+ case SpvOpLoad: *hasResult = true; *hasResultType = true; break;+ case SpvOpStore: *hasResult = false; *hasResultType = false; break;+ case SpvOpCopyMemory: *hasResult = false; *hasResultType = false; break;+ case SpvOpCopyMemorySized: *hasResult = false; *hasResultType = false; break;+ case SpvOpAccessChain: *hasResult = true; *hasResultType = true; break;+ case SpvOpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break;+ case SpvOpPtrAccessChain: *hasResult = true; *hasResultType = true; break;+ case SpvOpArrayLength: *hasResult = true; *hasResultType = true; break;+ case SpvOpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break;+ case SpvOpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break;+ case SpvOpDecorate: *hasResult = false; *hasResultType = false; break;+ case SpvOpMemberDecorate: *hasResult = false; *hasResultType = false; break;+ case SpvOpDecorationGroup: *hasResult = true; *hasResultType = false; break;+ case SpvOpGroupDecorate: *hasResult = false; *hasResultType = false; break;+ case SpvOpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break;+ case SpvOpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break;+ case SpvOpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break;+ case SpvOpVectorShuffle: *hasResult = true; *hasResultType = true; break;+ case SpvOpCompositeConstruct: *hasResult = true; *hasResultType = true; break;+ case SpvOpCompositeExtract: *hasResult = true; *hasResultType = true; break;+ case SpvOpCompositeInsert: *hasResult = true; *hasResultType = true; break;+ case SpvOpCopyObject: *hasResult = true; *hasResultType = true; break;+ case SpvOpTranspose: *hasResult = true; *hasResultType = true; break;+ case SpvOpSampledImage: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageFetch: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageGather: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageDrefGather: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageRead: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageWrite: *hasResult = false; *hasResultType = false; break;+ case SpvOpImage: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageQueryFormat: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageQueryOrder: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageQuerySize: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageQueryLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageQueryLevels: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageQuerySamples: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertFToU: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertFToS: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertSToF: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertUToF: *hasResult = true; *hasResultType = true; break;+ case SpvOpUConvert: *hasResult = true; *hasResultType = true; break;+ case SpvOpSConvert: *hasResult = true; *hasResultType = true; break;+ case SpvOpFConvert: *hasResult = true; *hasResultType = true; break;+ case SpvOpQuantizeToF16: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertPtrToU: *hasResult = true; *hasResultType = true; break;+ case SpvOpSatConvertSToU: *hasResult = true; *hasResultType = true; break;+ case SpvOpSatConvertUToS: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertUToPtr: *hasResult = true; *hasResultType = true; break;+ case SpvOpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break;+ case SpvOpGenericCastToPtr: *hasResult = true; *hasResultType = true; break;+ case SpvOpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break;+ case SpvOpBitcast: *hasResult = true; *hasResultType = true; break;+ case SpvOpSNegate: *hasResult = true; *hasResultType = true; break;+ case SpvOpFNegate: *hasResult = true; *hasResultType = true; break;+ case SpvOpIAdd: *hasResult = true; *hasResultType = true; break;+ case SpvOpFAdd: *hasResult = true; *hasResultType = true; break;+ case SpvOpISub: *hasResult = true; *hasResultType = true; break;+ case SpvOpFSub: *hasResult = true; *hasResultType = true; break;+ case SpvOpIMul: *hasResult = true; *hasResultType = true; break;+ case SpvOpFMul: *hasResult = true; *hasResultType = true; break;+ case SpvOpUDiv: *hasResult = true; *hasResultType = true; break;+ case SpvOpSDiv: *hasResult = true; *hasResultType = true; break;+ case SpvOpFDiv: *hasResult = true; *hasResultType = true; break;+ case SpvOpUMod: *hasResult = true; *hasResultType = true; break;+ case SpvOpSRem: *hasResult = true; *hasResultType = true; break;+ case SpvOpSMod: *hasResult = true; *hasResultType = true; break;+ case SpvOpFRem: *hasResult = true; *hasResultType = true; break;+ case SpvOpFMod: *hasResult = true; *hasResultType = true; break;+ case SpvOpVectorTimesScalar: *hasResult = true; *hasResultType = true; break;+ case SpvOpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break;+ case SpvOpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break;+ case SpvOpMatrixTimesVector: *hasResult = true; *hasResultType = true; break;+ case SpvOpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break;+ case SpvOpOuterProduct: *hasResult = true; *hasResultType = true; break;+ case SpvOpDot: *hasResult = true; *hasResultType = true; break;+ case SpvOpIAddCarry: *hasResult = true; *hasResultType = true; break;+ case SpvOpISubBorrow: *hasResult = true; *hasResultType = true; break;+ case SpvOpUMulExtended: *hasResult = true; *hasResultType = true; break;+ case SpvOpSMulExtended: *hasResult = true; *hasResultType = true; break;+ case SpvOpAny: *hasResult = true; *hasResultType = true; break;+ case SpvOpAll: *hasResult = true; *hasResultType = true; break;+ case SpvOpIsNan: *hasResult = true; *hasResultType = true; break;+ case SpvOpIsInf: *hasResult = true; *hasResultType = true; break;+ case SpvOpIsFinite: *hasResult = true; *hasResultType = true; break;+ case SpvOpIsNormal: *hasResult = true; *hasResultType = true; break;+ case SpvOpSignBitSet: *hasResult = true; *hasResultType = true; break;+ case SpvOpLessOrGreater: *hasResult = true; *hasResultType = true; break;+ case SpvOpOrdered: *hasResult = true; *hasResultType = true; break;+ case SpvOpUnordered: *hasResult = true; *hasResultType = true; break;+ case SpvOpLogicalEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpLogicalNotEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpLogicalOr: *hasResult = true; *hasResultType = true; break;+ case SpvOpLogicalAnd: *hasResult = true; *hasResultType = true; break;+ case SpvOpLogicalNot: *hasResult = true; *hasResultType = true; break;+ case SpvOpSelect: *hasResult = true; *hasResultType = true; break;+ case SpvOpIEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpINotEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpUGreaterThan: *hasResult = true; *hasResultType = true; break;+ case SpvOpSGreaterThan: *hasResult = true; *hasResultType = true; break;+ case SpvOpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpULessThan: *hasResult = true; *hasResultType = true; break;+ case SpvOpSLessThan: *hasResult = true; *hasResultType = true; break;+ case SpvOpULessThanEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpSLessThanEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpFOrdEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpFUnordEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpFOrdNotEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpFUnordNotEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpFOrdLessThan: *hasResult = true; *hasResultType = true; break;+ case SpvOpFUnordLessThan: *hasResult = true; *hasResultType = true; break;+ case SpvOpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break;+ case SpvOpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break;+ case SpvOpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpShiftRightLogical: *hasResult = true; *hasResultType = true; break;+ case SpvOpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break;+ case SpvOpShiftLeftLogical: *hasResult = true; *hasResultType = true; break;+ case SpvOpBitwiseOr: *hasResult = true; *hasResultType = true; break;+ case SpvOpBitwiseXor: *hasResult = true; *hasResultType = true; break;+ case SpvOpBitwiseAnd: *hasResult = true; *hasResultType = true; break;+ case SpvOpNot: *hasResult = true; *hasResultType = true; break;+ case SpvOpBitFieldInsert: *hasResult = true; *hasResultType = true; break;+ case SpvOpBitFieldSExtract: *hasResult = true; *hasResultType = true; break;+ case SpvOpBitFieldUExtract: *hasResult = true; *hasResultType = true; break;+ case SpvOpBitReverse: *hasResult = true; *hasResultType = true; break;+ case SpvOpBitCount: *hasResult = true; *hasResultType = true; break;+ case SpvOpDPdx: *hasResult = true; *hasResultType = true; break;+ case SpvOpDPdy: *hasResult = true; *hasResultType = true; break;+ case SpvOpFwidth: *hasResult = true; *hasResultType = true; break;+ case SpvOpDPdxFine: *hasResult = true; *hasResultType = true; break;+ case SpvOpDPdyFine: *hasResult = true; *hasResultType = true; break;+ case SpvOpFwidthFine: *hasResult = true; *hasResultType = true; break;+ case SpvOpDPdxCoarse: *hasResult = true; *hasResultType = true; break;+ case SpvOpDPdyCoarse: *hasResult = true; *hasResultType = true; break;+ case SpvOpFwidthCoarse: *hasResult = true; *hasResultType = true; break;+ case SpvOpEmitVertex: *hasResult = false; *hasResultType = false; break;+ case SpvOpEndPrimitive: *hasResult = false; *hasResultType = false; break;+ case SpvOpEmitStreamVertex: *hasResult = false; *hasResultType = false; break;+ case SpvOpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break;+ case SpvOpControlBarrier: *hasResult = false; *hasResultType = false; break;+ case SpvOpMemoryBarrier: *hasResult = false; *hasResultType = false; break;+ case SpvOpAtomicLoad: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicStore: *hasResult = false; *hasResultType = false; break;+ case SpvOpAtomicExchange: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicIIncrement: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicIDecrement: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicIAdd: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicISub: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicSMin: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicUMin: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicSMax: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicUMax: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicAnd: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicOr: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicXor: *hasResult = true; *hasResultType = true; break;+ case SpvOpPhi: *hasResult = true; *hasResultType = true; break;+ case SpvOpLoopMerge: *hasResult = false; *hasResultType = false; break;+ case SpvOpSelectionMerge: *hasResult = false; *hasResultType = false; break;+ case SpvOpLabel: *hasResult = true; *hasResultType = false; break;+ case SpvOpBranch: *hasResult = false; *hasResultType = false; break;+ case SpvOpBranchConditional: *hasResult = false; *hasResultType = false; break;+ case SpvOpSwitch: *hasResult = false; *hasResultType = false; break;+ case SpvOpKill: *hasResult = false; *hasResultType = false; break;+ case SpvOpReturn: *hasResult = false; *hasResultType = false; break;+ case SpvOpReturnValue: *hasResult = false; *hasResultType = false; break;+ case SpvOpUnreachable: *hasResult = false; *hasResultType = false; break;+ case SpvOpLifetimeStart: *hasResult = false; *hasResultType = false; break;+ case SpvOpLifetimeStop: *hasResult = false; *hasResultType = false; break;+ case SpvOpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupWaitEvents: *hasResult = false; *hasResultType = false; break;+ case SpvOpGroupAll: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupAny: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupBroadcast: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupIAdd: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupFAdd: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupFMin: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupUMin: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupSMin: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupFMax: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupUMax: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupSMax: *hasResult = true; *hasResultType = true; break;+ case SpvOpReadPipe: *hasResult = true; *hasResultType = true; break;+ case SpvOpWritePipe: *hasResult = true; *hasResultType = true; break;+ case SpvOpReservedReadPipe: *hasResult = true; *hasResultType = true; break;+ case SpvOpReservedWritePipe: *hasResult = true; *hasResultType = true; break;+ case SpvOpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break;+ case SpvOpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break;+ case SpvOpCommitReadPipe: *hasResult = false; *hasResultType = false; break;+ case SpvOpCommitWritePipe: *hasResult = false; *hasResultType = false; break;+ case SpvOpIsValidReserveId: *hasResult = true; *hasResultType = true; break;+ case SpvOpGetNumPipePackets: *hasResult = true; *hasResultType = true; break;+ case SpvOpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break;+ case SpvOpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break;+ case SpvOpEnqueueMarker: *hasResult = true; *hasResultType = true; break;+ case SpvOpEnqueueKernel: *hasResult = true; *hasResultType = true; break;+ case SpvOpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break;+ case SpvOpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break;+ case SpvOpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break;+ case SpvOpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break;+ case SpvOpRetainEvent: *hasResult = false; *hasResultType = false; break;+ case SpvOpReleaseEvent: *hasResult = false; *hasResultType = false; break;+ case SpvOpCreateUserEvent: *hasResult = true; *hasResultType = true; break;+ case SpvOpIsValidEvent: *hasResult = true; *hasResultType = true; break;+ case SpvOpSetUserEventStatus: *hasResult = false; *hasResultType = false; break;+ case SpvOpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break;+ case SpvOpGetDefaultQueue: *hasResult = true; *hasResultType = true; break;+ case SpvOpBuildNDRange: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseFetch: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseGather: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break;+ case SpvOpNoLine: *hasResult = false; *hasResultType = false; break;+ case SpvOpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicFlagClear: *hasResult = false; *hasResultType = false; break;+ case SpvOpImageSparseRead: *hasResult = true; *hasResultType = true; break;+ case SpvOpSizeOf: *hasResult = true; *hasResultType = true; break;+ case SpvOpTypePipeStorage: *hasResult = true; *hasResultType = false; break;+ case SpvOpConstantPipeStorage: *hasResult = true; *hasResultType = true; break;+ case SpvOpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break;+ case SpvOpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break;+ case SpvOpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break;+ case SpvOpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break;+ case SpvOpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break;+ case SpvOpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break;+ case SpvOpModuleProcessed: *hasResult = false; *hasResultType = false; break;+ case SpvOpExecutionModeId: *hasResult = false; *hasResultType = false; break;+ case SpvOpDecorateId: *hasResult = false; *hasResultType = false; break;+ case SpvOpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break;+ case SpvOpCopyLogical: *hasResult = true; *hasResultType = true; break;+ case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break;+ case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break;+ case SpvOpTerminateInvocation: *hasResult = false; *hasResultType = false; break;+ case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break;+ case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;+ case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break;+ case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break;+ case SpvOpSDot: *hasResult = true; *hasResultType = true; break;+ case SpvOpUDot: *hasResult = true; *hasResultType = true; break;+ case SpvOpSUDot: *hasResult = true; *hasResultType = true; break;+ case SpvOpSDotAccSat: *hasResult = true; *hasResultType = true; break;+ case SpvOpUDotAccSat: *hasResult = true; *hasResultType = true; break;+ case SpvOpSUDotAccSat: *hasResult = true; *hasResultType = true; break;+ case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;+ case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;+ case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;+ case SpvOpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break;+ case SpvOpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break;+ case SpvOpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break;+ case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break;+ case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;+ case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break;+ case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break;+ case SpvOpTraceMotionNV: *hasResult = false; *hasResultType = false; break;+ case SpvOpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;+ case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;+ case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;+ case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;+ case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break;+ case SpvOpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;+ case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;+ case SpvOpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break;+ case SpvOpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertUToImageNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertImageToUNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break;+ case SpvOpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break;+ case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpAbsISubINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpIAddSatINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpUAddSatINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpIAverageINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpUAverageINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpISubSatINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpAsmINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpAsmCallINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break;+ case SpvOpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break;+ case SpvOpExpectKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break;+ case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break;+ case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedSinINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedCosINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedLogINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFixedExpINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;+ case SpvOpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break;+ case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break;+ case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;+ case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;+ }+}+#endif /* SPV_ENABLE_UTILITY_CODE */++#endif
+ cbits/spirv_reflect.c view
@@ -0,0 +1,5097 @@+/*+ Copyright 2017-2022 Google Inc.++ Licensed under the Apache License, Version 2.0 (the "License");+ you may not use this file except in compliance with the License.+ You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++ Unless required by applicable law or agreed to in writing, software+ distributed under the License is distributed on an "AS IS" BASIS,+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ See the License for the specific language governing permissions and+ limitations under the License.+*/++#include "spirv_reflect.h"+#include <assert.h>+#include <stdbool.h>+#include <string.h>++#if defined(WIN32)+ #define _CRTDBG_MAP_ALLOC+ #include <stdlib.h>+ #include <crtdbg.h>+#else+ #include <stdlib.h>+#endif++#if defined(SPIRV_REFLECT_ENABLE_ASSERTS)+ #define SPV_REFLECT_ASSERT(COND) \+ assert(COND);+#else+#define SPV_REFLECT_ASSERT(COND)+#endif++// Temporary enums until these make it into SPIR-V/Vulkan+// clang-format off+enum {+ SpvReflectOpDecorateId = 332,+ SpvReflectOpDecorateStringGOOGLE = 5632,+ SpvReflectOpMemberDecorateStringGOOGLE = 5633,+ SpvReflectDecorationHlslCounterBufferGOOGLE = 5634,+ SpvReflectDecorationHlslSemanticGOOGLE = 5635+};+// clang-format on++// clang-format off+enum {+ SPIRV_STARTING_WORD_INDEX = 5,+ SPIRV_WORD_SIZE = sizeof(uint32_t),+ SPIRV_BYTE_WIDTH = 8,+ SPIRV_MINIMUM_FILE_SIZE = SPIRV_STARTING_WORD_INDEX * SPIRV_WORD_SIZE,+ SPIRV_DATA_ALIGNMENT = 4 * SPIRV_WORD_SIZE, // 16+ SPIRV_ACCESS_CHAIN_INDEX_OFFSET = 4,+};+// clang-format on++// clang-format off+enum {+ INVALID_VALUE = 0xFFFFFFFF,+};+// clang-format on++// clang-format off+enum {+ MAX_NODE_NAME_LENGTH = 1024,+};+// clang-format on++// clang-format off+enum {+ IMAGE_SAMPLED = 1,+ IMAGE_STORAGE = 2+};+// clang-format on++// clang-format off+typedef struct SpvReflectPrvArrayTraits {+ uint32_t element_type_id;+ uint32_t length_id;+} SpvReflectPrvArrayTraits;+// clang-format on++// clang-format off+typedef struct SpvReflectPrvImageTraits {+ uint32_t sampled_type_id;+ SpvDim dim;+ uint32_t depth;+ uint32_t arrayed;+ uint32_t ms;+ uint32_t sampled;+ SpvImageFormat image_format;+} SpvReflectPrvImageTraits;+// clang-format on++// clang-format off+typedef struct SpvReflectPrvNumberDecoration {+ uint32_t word_offset;+ uint32_t value;+} SpvReflectPrvNumberDecoration;+// clang-format on++// clang-format off+typedef struct SpvReflectPrvStringDecoration {+ uint32_t word_offset;+ const char* value;+} SpvReflectPrvStringDecoration;+// clang-format on++// clang-format off+typedef struct SpvReflectPrvDecorations {+ bool is_relaxed_precision;+ bool is_block;+ bool is_buffer_block;+ bool is_row_major;+ bool is_column_major;+ bool is_built_in;+ bool is_noperspective;+ bool is_flat;+ bool is_non_writable;+ bool is_non_readable;+ SpvReflectPrvNumberDecoration set;+ SpvReflectPrvNumberDecoration binding;+ SpvReflectPrvNumberDecoration input_attachment_index;+ SpvReflectPrvNumberDecoration location;+ SpvReflectPrvNumberDecoration offset;+ SpvReflectPrvNumberDecoration uav_counter_buffer;+ SpvReflectPrvStringDecoration semantic;+ uint32_t array_stride;+ uint32_t matrix_stride;+ SpvBuiltIn built_in;+} SpvReflectPrvDecorations;+// clang-format on++// clang-format off+typedef struct SpvReflectPrvNode {+ uint32_t result_id;+ SpvOp op;+ uint32_t result_type_id;+ uint32_t type_id;+ SpvCapability capability;+ SpvStorageClass storage_class;+ uint32_t word_offset;+ uint32_t word_count;+ bool is_type;++ SpvReflectPrvArrayTraits array_traits;+ SpvReflectPrvImageTraits image_traits;+ uint32_t image_type_id;++ const char* name;+ SpvReflectPrvDecorations decorations;+ uint32_t member_count;+ const char** member_names;+ SpvReflectPrvDecorations* member_decorations;+} SpvReflectPrvNode;+// clang-format on++// clang-format off+typedef struct SpvReflectPrvString {+ uint32_t result_id;+ const char* string;+} SpvReflectPrvString;+// clang-format on++// clang-format off+typedef struct SpvReflectPrvFunction {+ uint32_t id;+ uint32_t callee_count;+ uint32_t* callees;+ struct SpvReflectPrvFunction** callee_ptrs;+ uint32_t accessed_ptr_count;+ uint32_t* accessed_ptrs;+} SpvReflectPrvFunction;+// clang-format on++// clang-format off+typedef struct SpvReflectPrvAccessChain {+ uint32_t result_id;+ uint32_t result_type_id;+ //+ // Pointing to the base of a composite object.+ // Generally the id of descriptor block variable+ uint32_t base_id;+ // + // From spec:+ // The first index in Indexes will select the + // top-level member/element/component/element + // of the base composite+ uint32_t index_count;+ uint32_t* indexes;+} SpvReflectPrvAccessChain;+// clang-format on++// clang-format off+typedef struct SpvReflectPrvParser {+ size_t spirv_word_count;+ uint32_t* spirv_code;+ uint32_t string_count;+ SpvReflectPrvString* strings;+ SpvSourceLanguage source_language;+ uint32_t source_language_version;+ uint32_t source_file_id;+ const char* source_embedded;+ size_t node_count;+ SpvReflectPrvNode* nodes;+ uint32_t entry_point_count;+ uint32_t capability_count;+ uint32_t function_count;+ SpvReflectPrvFunction* functions;+ uint32_t access_chain_count;+ SpvReflectPrvAccessChain* access_chains;++ uint32_t type_count;+ uint32_t descriptor_count;+ uint32_t push_constant_count;+} SpvReflectPrvParser;+// clang-format on++static uint32_t Max(+ uint32_t a, + uint32_t b)+{+ return a > b ? a : b;+}++static uint32_t RoundUp(+ uint32_t value,+ uint32_t multiple)+{+ assert(multiple && ((multiple & (multiple - 1)) == 0));+ return (value + multiple - 1) & ~(multiple - 1);+}++#define IsNull(ptr) \+ (ptr == NULL)++#define IsNotNull(ptr) \+ (ptr != NULL)++#define SafeFree(ptr) \+ { \+ free((void*)ptr); \+ ptr = NULL; \+ }++static int SortCompareUint32(+ const void* a, + const void* b)+{+ const uint32_t* p_a = (const uint32_t*)a;+ const uint32_t* p_b = (const uint32_t*)b;++ return (int)*p_a - (int)*p_b;+}++//+// De-duplicates a sorted array and returns the new size.+//+// Note: The array doesn't actually need to be sorted, just+// arranged into "runs" so that all the entries with one+// value are adjacent.+//+static size_t DedupSortedUint32(uint32_t* arr, size_t size)+{+ if (size == 0) {+ return 0;+ }+ size_t dedup_idx = 0;+ for (size_t i = 0; i < size; ++i) {+ if (arr[dedup_idx] != arr[i]) {+ ++dedup_idx;+ arr[dedup_idx] = arr[i];+ }+ }+ return dedup_idx+1;+}++static bool SearchSortedUint32(+ const uint32_t* arr, + size_t size, + uint32_t target)+{+ size_t lo = 0;+ size_t hi = size;+ while (lo < hi) {+ size_t mid = (hi - lo) / 2 + lo;+ if (arr[mid] == target) {+ return true;+ } else if (arr[mid] < target) {+ lo = mid+1;+ } else {+ hi = mid;+ }+ }+ return false;+}++static SpvReflectResult IntersectSortedUint32(+ const uint32_t* p_arr0, + size_t arr0_size,+ const uint32_t* p_arr1, + size_t arr1_size,+ uint32_t** pp_res,+ size_t* res_size+)+{+ *pp_res = NULL;+ *res_size = 0;+ if (IsNull(p_arr0) || IsNull(p_arr1)) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ const uint32_t* arr0_end = p_arr0 + arr0_size;+ const uint32_t* arr1_end = p_arr1 + arr1_size;++ const uint32_t* idx0 = p_arr0;+ const uint32_t* idx1 = p_arr1;+ while (idx0 != arr0_end && idx1 != arr1_end) {+ if (*idx0 < *idx1) {+ ++idx0;+ } else if (*idx0 > *idx1) {+ ++idx1;+ } else {+ ++*res_size;+ ++idx0;+ ++idx1;+ }+ }++ if (*res_size > 0) {+ *pp_res = (uint32_t*)calloc(*res_size, sizeof(**pp_res));+ if (IsNull(*pp_res)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ uint32_t* idxr = *pp_res;+ idx0 = p_arr0;+ idx1 = p_arr1;+ while (idx0 != arr0_end && idx1 != arr1_end) {+ if (*idx0 < *idx1) {+ ++idx0;+ } else if (*idx0 > *idx1) {+ ++idx1;+ } else {+ *(idxr++) = *idx0;+ ++idx0;+ ++idx1;+ }+ }+ }+ return SPV_REFLECT_RESULT_SUCCESS;+}+++static bool InRange(+ const SpvReflectPrvParser* p_parser, + uint32_t index)+{+ bool in_range = false;+ if (IsNotNull(p_parser)) {+ in_range = (index < p_parser->spirv_word_count);+ }+ return in_range;+}++static SpvReflectResult ReadU32(+ SpvReflectPrvParser* p_parser,+ uint32_t word_offset,+ uint32_t* p_value)+{+ assert(IsNotNull(p_parser));+ assert(IsNotNull(p_parser->spirv_code));+ assert(InRange(p_parser, word_offset));+ SpvReflectResult result = SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_EOF;+ if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && InRange(p_parser, word_offset)) {+ *p_value = *(p_parser->spirv_code + word_offset);+ result = SPV_REFLECT_RESULT_SUCCESS;+ }+ return result;+}++#define CHECKED_READU32(parser, word_offset, value) \+ { \+ SpvReflectResult checked_readu32_result = ReadU32(parser, \+ word_offset, (uint32_t*)&(value)); \+ if (checked_readu32_result != SPV_REFLECT_RESULT_SUCCESS) { \+ return checked_readu32_result; \+ } \+ }++#define CHECKED_READU32_CAST(parser, word_offset, cast_to_type, value) \+ { \+ uint32_t checked_readu32_cast_u32 = UINT32_MAX; \+ SpvReflectResult checked_readu32_cast_result = ReadU32(parser, \+ word_offset, \+ (uint32_t*)&(checked_readu32_cast_u32)); \+ if (checked_readu32_cast_result != SPV_REFLECT_RESULT_SUCCESS) { \+ return checked_readu32_cast_result; \+ } \+ value = (cast_to_type)checked_readu32_cast_u32; \+ }++#define IF_READU32(result, parser, word_offset, value) \+ if ((result) == SPV_REFLECT_RESULT_SUCCESS) { \+ result = ReadU32(parser, word_offset, (uint32_t*)&(value)); \+ }++#define IF_READU32_CAST(result, parser, word_offset, cast_to_type, value) \+ if ((result) == SPV_REFLECT_RESULT_SUCCESS) { \+ uint32_t if_readu32_cast_u32 = UINT32_MAX; \+ result = ReadU32(parser, word_offset, &if_readu32_cast_u32); \+ if ((result) == SPV_REFLECT_RESULT_SUCCESS) { \+ value = (cast_to_type)if_readu32_cast_u32; \+ } \+ }++static SpvReflectResult ReadStr(+ SpvReflectPrvParser* p_parser, + uint32_t word_offset, + uint32_t word_index, + uint32_t word_count,+ uint32_t* p_buf_size, + char* p_buf+)+{+ uint32_t limit = (word_offset + word_count);+ assert(IsNotNull(p_parser));+ assert(IsNotNull(p_parser->spirv_code));+ assert(InRange(p_parser, limit));+ SpvReflectResult result = SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_EOF;+ if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && InRange(p_parser, limit)) {+ const char* c_str = (const char*)(p_parser->spirv_code + word_offset + word_index);+ uint32_t n = word_count * SPIRV_WORD_SIZE;+ uint32_t length_with_terminator = 0;+ for (uint32_t i = 0; i < n; ++i) {+ char c = *(c_str + i);+ if (c == 0) {+ length_with_terminator = i + 1;+ break;+ }+ }++ if (length_with_terminator > 0) {+ result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ if (IsNotNull(p_buf_size) && IsNotNull(p_buf)) {+ result = SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;+ if (length_with_terminator <= *p_buf_size) {+ memset(p_buf, 0, *p_buf_size);+ memcpy(p_buf, c_str, length_with_terminator);+ result = SPV_REFLECT_RESULT_SUCCESS;+ }+ }+ else {+ if (IsNotNull(p_buf_size)) {+ *p_buf_size = length_with_terminator;+ result = SPV_REFLECT_RESULT_SUCCESS;+ }+ }+ }+ }+ return result;+}++static SpvReflectDecorationFlags ApplyDecorations(const SpvReflectPrvDecorations* p_decoration_fields)+{+ SpvReflectDecorationFlags decorations = SPV_REFLECT_DECORATION_NONE;+ if (p_decoration_fields->is_relaxed_precision) {+ decorations |= SPV_REFLECT_DECORATION_RELAXED_PRECISION;+ }+ if (p_decoration_fields->is_block) {+ decorations |= SPV_REFLECT_DECORATION_BLOCK;+ }+ if (p_decoration_fields->is_buffer_block) {+ decorations |= SPV_REFLECT_DECORATION_BUFFER_BLOCK;+ }+ if (p_decoration_fields->is_row_major) {+ decorations |= SPV_REFLECT_DECORATION_ROW_MAJOR;+ }+ if (p_decoration_fields->is_column_major) {+ decorations |= SPV_REFLECT_DECORATION_COLUMN_MAJOR;+ }+ if (p_decoration_fields->is_built_in) {+ decorations |= SPV_REFLECT_DECORATION_BUILT_IN;+ }+ if (p_decoration_fields->is_noperspective) {+ decorations |= SPV_REFLECT_DECORATION_NOPERSPECTIVE;+ }+ if (p_decoration_fields->is_flat) {+ decorations |= SPV_REFLECT_DECORATION_FLAT;+ }+ if (p_decoration_fields->is_non_writable) {+ decorations |= SPV_REFLECT_DECORATION_NON_WRITABLE;+ }+ if (p_decoration_fields->is_non_readable) {+ decorations |= SPV_REFLECT_DECORATION_NON_READABLE;+ }+ return decorations;+}++static void ApplyNumericTraits(const SpvReflectTypeDescription* p_type, SpvReflectNumericTraits* p_numeric_traits)+{+ memcpy(p_numeric_traits, &p_type->traits.numeric, sizeof(p_type->traits.numeric));+}++static void ApplyArrayTraits(const SpvReflectTypeDescription* p_type, SpvReflectArrayTraits* p_array_traits)+{+ memcpy(p_array_traits, &p_type->traits.array, sizeof(p_type->traits.array));+}++static SpvReflectPrvNode* FindNode(+ SpvReflectPrvParser* p_parser,+ uint32_t result_id)+{+ SpvReflectPrvNode* p_node = NULL;+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_elem = &(p_parser->nodes[i]);+ if (p_elem->result_id == result_id) {+ p_node = p_elem;+ break;+ }+ }+ return p_node;+}++static SpvReflectTypeDescription* FindType(SpvReflectShaderModule* p_module, uint32_t type_id)+{+ SpvReflectTypeDescription* p_type = NULL;+ for (size_t i = 0; i < p_module->_internal->type_description_count; ++i) {+ SpvReflectTypeDescription* p_elem = &(p_module->_internal->type_descriptions[i]);+ if (p_elem->id == type_id) {+ p_type = p_elem;+ break;+ }+ }+ return p_type;+}++static SpvReflectResult CreateParser(+ size_t size, + void* p_code, + SpvReflectPrvParser* p_parser)+{+ if (p_code == NULL) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ if (size < SPIRV_MINIMUM_FILE_SIZE) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_CODE_SIZE;+ }+ if ((size % 4) != 0) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_CODE_SIZE;+ }++ p_parser->spirv_word_count = size / SPIRV_WORD_SIZE;+ p_parser->spirv_code = (uint32_t*)p_code;++ if (p_parser->spirv_code[0] != SpvMagicNumber) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_MAGIC_NUMBER;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static void DestroyParser(SpvReflectPrvParser* p_parser)+{+ if (!IsNull(p_parser->nodes)) {+ // Free nodes+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if (IsNotNull(p_node->member_names)) {+ SafeFree(p_node->member_names);+ }+ if (IsNotNull(p_node->member_decorations)) {+ SafeFree(p_node->member_decorations);+ }+ }++ // Free functions+ for (size_t i = 0; i < p_parser->function_count; ++i) {+ SafeFree(p_parser->functions[i].callees);+ SafeFree(p_parser->functions[i].callee_ptrs);+ SafeFree(p_parser->functions[i].accessed_ptrs);+ }++ // Free access chains+ for (uint32_t i = 0; i < p_parser->access_chain_count; ++i) {+ SafeFree(p_parser->access_chains[i].indexes);+ }++ SafeFree(p_parser->nodes);+ SafeFree(p_parser->strings);+ SafeFree(p_parser->source_embedded);+ SafeFree(p_parser->functions);+ SafeFree(p_parser->access_chains);+ p_parser->node_count = 0;+ }+}++static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser)+{+ assert(IsNotNull(p_parser));+ assert(IsNotNull(p_parser->spirv_code));++ uint32_t* p_spirv = p_parser->spirv_code;+ uint32_t spirv_word_index = SPIRV_STARTING_WORD_INDEX;++ // Count nodes+ uint32_t node_count = 0;+ while (spirv_word_index < p_parser->spirv_word_count) {+ uint32_t word = p_spirv[spirv_word_index];+ SpvOp op = (SpvOp)(word & 0xFFFF);+ uint32_t node_word_count = (word >> 16) & 0xFFFF;+ if (node_word_count == 0) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_INSTRUCTION;+ }+ if (op == SpvOpAccessChain) {+ ++(p_parser->access_chain_count);+ }+ spirv_word_index += node_word_count;+ ++node_count;+ }++ if (node_count == 0) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_EOF;+ }++ // Allocate nodes+ p_parser->node_count = node_count;+ p_parser->nodes = (SpvReflectPrvNode*)calloc(p_parser->node_count, sizeof(*(p_parser->nodes)));+ if (IsNull(p_parser->nodes)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ // Mark all nodes with an invalid state+ for (uint32_t i = 0; i < node_count; ++i) {+ p_parser->nodes[i].op = (SpvOp)INVALID_VALUE;+ p_parser->nodes[i].storage_class = (SpvStorageClass)INVALID_VALUE;+ p_parser->nodes[i].decorations.set.value = (uint32_t)INVALID_VALUE;+ p_parser->nodes[i].decorations.binding.value = (uint32_t)INVALID_VALUE;+ p_parser->nodes[i].decorations.location.value = (uint32_t)INVALID_VALUE;+ p_parser->nodes[i].decorations.offset.value = (uint32_t)INVALID_VALUE;+ p_parser->nodes[i].decorations.uav_counter_buffer.value = (uint32_t)INVALID_VALUE;+ p_parser->nodes[i].decorations.built_in = (SpvBuiltIn)INVALID_VALUE;+ }+ // Mark source file id node+ p_parser->source_file_id = (uint32_t)INVALID_VALUE;+ p_parser->source_embedded = NULL;++ // Function node+ uint32_t function_node = (uint32_t)INVALID_VALUE;++ // Allocate access chain+ if (p_parser->access_chain_count > 0) {+ p_parser->access_chains = (SpvReflectPrvAccessChain*)calloc(p_parser->access_chain_count, sizeof(*(p_parser->access_chains)));+ if (IsNull(p_parser->access_chains)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }++ // Parse nodes+ uint32_t node_index = 0;+ uint32_t access_chain_index = 0;+ spirv_word_index = SPIRV_STARTING_WORD_INDEX;+ while (spirv_word_index < p_parser->spirv_word_count) {+ uint32_t word = p_spirv[spirv_word_index];+ SpvOp op = (SpvOp)(word & 0xFFFF);+ uint32_t node_word_count = (word >> 16) & 0xFFFF;++ SpvReflectPrvNode* p_node = &(p_parser->nodes[node_index]);+ p_node->op = op;+ p_node->word_offset = spirv_word_index;+ p_node->word_count = node_word_count;++ switch (p_node->op) {+ default: break;++ case SpvOpString: {+ ++(p_parser->string_count);+ }+ break;++ case SpvOpSource: {+ CHECKED_READU32_CAST(p_parser, p_node->word_offset + 1, SpvSourceLanguage, p_parser->source_language);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_parser->source_language_version);+ if (p_node->word_count >= 4) {+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_parser->source_file_id);+ }+ if (p_node->word_count >= 5) {+ const char* p_source = (const char*)(p_parser->spirv_code + p_node->word_offset + 4);++ const size_t source_len = strlen(p_source);+ char* p_source_temp = (char*)calloc(source_len + 1, sizeof(char*));++ if (IsNull(p_source_temp)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ #ifdef _WIN32+ strcpy_s(p_source_temp, source_len + 1, p_source);+ #else+ strcpy(p_source_temp, p_source);+ #endif++ p_parser->source_embedded = p_source_temp;+ }+ }+ break;++ case SpvOpSourceContinued: {+ const char* p_source = (const char*)(p_parser->spirv_code + p_node->word_offset + 1);++ const size_t source_len = strlen(p_source);+ const size_t embedded_source_len = strlen(p_parser->source_embedded); + char* p_continued_source = (char*)calloc(source_len + embedded_source_len + 1, sizeof(char*));++ if (IsNull(p_continued_source)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ #ifdef _WIN32+ strcpy_s(p_continued_source, embedded_source_len + 1, p_parser->source_embedded);+ strcat_s(p_continued_source, source_len + 1, p_source);+ #else+ strcpy(p_continued_source, p_parser->source_embedded);+ strcat(p_continued_source, p_source);+ #endif++ SafeFree(p_parser->source_embedded);+ p_parser->source_embedded = p_continued_source;+ }+ break;++ case SpvOpEntryPoint: {+ ++(p_parser->entry_point_count);+ }+ break;++ case SpvOpCapability: {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->capability);+ ++(p_parser->capability_count);+ }+ break;++ case SpvOpName:+ case SpvOpMemberName:+ {+ uint32_t member_offset = (p_node->op == SpvOpMemberName) ? 1 : 0;+ uint32_t name_start = p_node->word_offset + member_offset + 2;+ p_node->name = (const char*)(p_parser->spirv_code + name_start);+ }+ break;++ case SpvOpTypeStruct:+ {+ p_node->member_count = p_node->word_count - 2;+ } // Fall through+ case SpvOpTypeVoid:+ case SpvOpTypeBool:+ case SpvOpTypeInt:+ case SpvOpTypeFloat:+ case SpvOpTypeVector:+ case SpvOpTypeMatrix:+ case SpvOpTypeSampler:+ case SpvOpTypeOpaque:+ case SpvOpTypeFunction:+ case SpvOpTypeEvent:+ case SpvOpTypeDeviceEvent:+ case SpvOpTypeReserveId:+ case SpvOpTypeQueue:+ case SpvOpTypePipe:+ case SpvOpTypeAccelerationStructureKHR:+ case SpvOpTypeRayQueryKHR:+ {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);+ p_node->is_type = true;+ }+ break;++ case SpvOpTypeImage: {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->image_traits.sampled_type_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_node->image_traits.dim);+ CHECKED_READU32(p_parser, p_node->word_offset + 4, p_node->image_traits.depth);+ CHECKED_READU32(p_parser, p_node->word_offset + 5, p_node->image_traits.arrayed);+ CHECKED_READU32(p_parser, p_node->word_offset + 6, p_node->image_traits.ms);+ CHECKED_READU32(p_parser, p_node->word_offset + 7, p_node->image_traits.sampled);+ CHECKED_READU32(p_parser, p_node->word_offset + 8, p_node->image_traits.image_format);+ p_node->is_type = true;+ }+ break;++ case SpvOpTypeSampledImage: {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->image_type_id);+ p_node->is_type = true;+ }+ break;++ case SpvOpTypeArray: {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->array_traits.element_type_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_node->array_traits.length_id);+ p_node->is_type = true;+ }+ break;++ case SpvOpTypeRuntimeArray: {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->array_traits.element_type_id);+ p_node->is_type = true;+ }+ break;++ case SpvOpTypePointer: {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->storage_class);+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_node->type_id);+ p_node->is_type = true;+ }+ break;++ case SpvOpTypeForwardPointer:+ {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->storage_class);+ p_node->is_type = true;+ }+ break;++ case SpvOpConstantTrue:+ case SpvOpConstantFalse:+ case SpvOpConstant:+ case SpvOpConstantComposite:+ case SpvOpConstantSampler:+ case SpvOpConstantNull: {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);+ }+ break;++ case SpvOpSpecConstantTrue:+ case SpvOpSpecConstantFalse:+ case SpvOpSpecConstant:+ case SpvOpSpecConstantComposite:+ case SpvOpSpecConstantOp: {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);+ }+ break;++ case SpvOpVariable:+ {+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->type_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_node->storage_class);+ }+ break;++ case SpvOpLoad:+ {+ // Only load enough so OpDecorate can reference the node, skip the remaining operands.+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);+ }+ break;++ case SpvOpAccessChain:+ {+ SpvReflectPrvAccessChain* p_access_chain = &(p_parser->access_chains[access_chain_index]);+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_access_chain->result_type_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_access_chain->result_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_access_chain->base_id);+ //+ // SPIRV_ACCESS_CHAIN_INDEX_OFFSET (4) is the number of words up until the first index:+ // [Node, Result Type Id, Result Id, Base Id, <Indexes>]+ //+ p_access_chain->index_count = (node_word_count - SPIRV_ACCESS_CHAIN_INDEX_OFFSET);+ if (p_access_chain->index_count > 0) {+ p_access_chain->indexes = (uint32_t*)calloc(p_access_chain->index_count, sizeof(*(p_access_chain->indexes)));+ if (IsNull( p_access_chain->indexes)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ // Parse any index values for access chain+ for (uint32_t index_index = 0; index_index < p_access_chain->index_count; ++index_index) {+ // Read index id+ uint32_t index_id = 0;+ CHECKED_READU32(p_parser, p_node->word_offset + SPIRV_ACCESS_CHAIN_INDEX_OFFSET + index_index, index_id);+ // Find OpConstant node that contains index value+ SpvReflectPrvNode* p_index_value_node = FindNode(p_parser, index_id);+ if ((p_index_value_node != NULL) && (p_index_value_node->op == SpvOpConstant)) {+ // Read index value+ uint32_t index_value = UINT32_MAX;+ CHECKED_READU32(p_parser, p_index_value_node->word_offset + 3, index_value);+ assert(index_value != UINT32_MAX);+ // Write index value to array+ p_access_chain->indexes[index_index] = index_value;+ }+ }+ }+ ++access_chain_index;+ }+ break;++ case SpvOpFunction:+ {+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);+ // Count function definitions, not function declarations. To determine+ // the difference, set an in-function variable, and then if an OpLabel+ // is reached before the end of the function increment the function+ // count.+ function_node = node_index;+ }+ break;++ case SpvOpLabel:+ {+ if (function_node != (uint32_t)INVALID_VALUE) {+ SpvReflectPrvNode* p_func_node = &(p_parser->nodes[function_node]);+ CHECKED_READU32(p_parser, p_func_node->word_offset + 2, p_func_node->result_id);+ ++(p_parser->function_count);+ }+ } // Fall through++ case SpvOpFunctionEnd:+ {+ function_node = (uint32_t)INVALID_VALUE;+ }+ break;+ }++ if (p_node->is_type) {+ ++(p_parser->type_count);+ }++ spirv_word_index += node_word_count;+ ++node_index;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseStrings(SpvReflectPrvParser* p_parser)+{+ assert(IsNotNull(p_parser));+ assert(IsNotNull(p_parser->spirv_code));+ assert(IsNotNull(p_parser->nodes));++ // Early out+ if (p_parser->string_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {+ // Allocate string storage+ p_parser->strings = (SpvReflectPrvString*)calloc(p_parser->string_count, sizeof(*(p_parser->strings))); ++ uint32_t string_index = 0;+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if (p_node->op != SpvOpString) {+ continue;+ }++ // Paranoid check against string count+ assert(string_index < p_parser->string_count);+ if (string_index >= p_parser->string_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ // Result id+ SpvReflectPrvString* p_string = &(p_parser->strings[string_index]);+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_string->result_id);++ // String+ uint32_t string_start = p_node->word_offset + 2;+ p_string->string = (const char*)(p_parser->spirv_code + string_start);++ // Increment string index+ ++string_index;+ }+ }+ + return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseSource(SpvReflectPrvParser* p_parser, SpvReflectShaderModule* p_module)+{+ assert(IsNotNull(p_parser));+ assert(IsNotNull(p_parser->spirv_code));++ if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code)) {+ // Source file+ if (IsNotNull(p_parser->strings)) {+ for (uint32_t i = 0; i < p_parser->string_count; ++i) {+ SpvReflectPrvString* p_string = &(p_parser->strings[i]);+ if (p_string->result_id == p_parser->source_file_id) {+ p_module->source_file = p_string->string;+ break;+ }+ }+ }++ //Source code+ if (IsNotNull(p_parser->source_embedded))+ {+ const size_t source_len = strlen(p_parser->source_embedded);+ char* p_source = (char*)calloc(source_len + 1, sizeof(char*));++ if (IsNull(p_source)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ #ifdef _WIN32+ strcpy_s(p_source, source_len + 1, p_parser->source_embedded);+ #else+ strcpy(p_source, p_parser->source_embedded);+ #endif++ p_module->source_source = p_source;+ }+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseFunction(+ SpvReflectPrvParser* p_parser, + SpvReflectPrvNode* p_func_node, + SpvReflectPrvFunction* p_func, + size_t first_label_index)+{+ p_func->id = p_func_node->result_id;++ p_func->callee_count = 0;+ p_func->accessed_ptr_count = 0;++ for (size_t i = first_label_index; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if (p_node->op == SpvOpFunctionEnd) {+ break;+ }+ switch (p_node->op) {+ case SpvOpFunctionCall: {+ ++(p_func->callee_count);+ }+ break;+ case SpvOpLoad:+ case SpvOpAccessChain:+ case SpvOpInBoundsAccessChain:+ case SpvOpPtrAccessChain:+ case SpvOpArrayLength:+ case SpvOpGenericPtrMemSemantics:+ case SpvOpInBoundsPtrAccessChain:+ case SpvOpStore:+ case SpvOpImageTexelPointer:+ {+ ++(p_func->accessed_ptr_count);+ }+ break;+ case SpvOpCopyMemory:+ case SpvOpCopyMemorySized:+ {+ p_func->accessed_ptr_count += 2;+ }+ break;+ default: break;+ }+ }++ if (p_func->callee_count > 0) {+ p_func->callees = (uint32_t*)calloc(p_func->callee_count,+ sizeof(*(p_func->callees)));+ if (IsNull(p_func->callees)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }++ if (p_func->accessed_ptr_count > 0) {+ p_func->accessed_ptrs = (uint32_t*)calloc(p_func->accessed_ptr_count,+ sizeof(*(p_func->accessed_ptrs)));+ if (IsNull(p_func->accessed_ptrs)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }++ p_func->callee_count = 0;+ p_func->accessed_ptr_count = 0;+ for (size_t i = first_label_index; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if (p_node->op == SpvOpFunctionEnd) {+ break;+ }+ switch (p_node->op) {+ case SpvOpFunctionCall: {+ CHECKED_READU32(p_parser, p_node->word_offset + 3,+ p_func->callees[p_func->callee_count]);+ (++p_func->callee_count);+ }+ break;+ case SpvOpLoad:+ case SpvOpAccessChain:+ case SpvOpInBoundsAccessChain:+ case SpvOpPtrAccessChain:+ case SpvOpArrayLength:+ case SpvOpGenericPtrMemSemantics:+ case SpvOpInBoundsPtrAccessChain:+ case SpvOpImageTexelPointer:+ {+ CHECKED_READU32(p_parser, p_node->word_offset + 3,+ p_func->accessed_ptrs[p_func->accessed_ptr_count]);+ (++p_func->accessed_ptr_count);+ }+ break;+ case SpvOpStore:+ {+ CHECKED_READU32(p_parser, p_node->word_offset + 2,+ p_func->accessed_ptrs[p_func->accessed_ptr_count]);+ (++p_func->accessed_ptr_count);+ }+ break;+ case SpvOpCopyMemory:+ case SpvOpCopyMemorySized:+ {+ CHECKED_READU32(p_parser, p_node->word_offset + 2,+ p_func->accessed_ptrs[p_func->accessed_ptr_count]);+ (++p_func->accessed_ptr_count);+ CHECKED_READU32(p_parser, p_node->word_offset + 3,+ p_func->accessed_ptrs[p_func->accessed_ptr_count]);+ (++p_func->accessed_ptr_count);+ }+ break;+ default: break;+ }+ }++ if (p_func->callee_count > 0) {+ qsort(p_func->callees, p_func->callee_count,+ sizeof(*(p_func->callees)), SortCompareUint32);+ }+ p_func->callee_count = (uint32_t)DedupSortedUint32(p_func->callees,+ p_func->callee_count);++ if (p_func->accessed_ptr_count > 0) {+ qsort(p_func->accessed_ptrs, p_func->accessed_ptr_count,+ sizeof(*(p_func->accessed_ptrs)), SortCompareUint32);+ }+ p_func->accessed_ptr_count = (uint32_t)DedupSortedUint32(p_func->accessed_ptrs,+ p_func->accessed_ptr_count);++ return SPV_REFLECT_RESULT_SUCCESS;+}++static int SortCompareFunctions(+ const void* a, + const void* b)+{+ const SpvReflectPrvFunction* af = (const SpvReflectPrvFunction*)a;+ const SpvReflectPrvFunction* bf = (const SpvReflectPrvFunction*)b;+ return (int)af->id - (int)bf->id;+}++static SpvReflectResult ParseFunctions(SpvReflectPrvParser* p_parser)+{+ assert(IsNotNull(p_parser));+ assert(IsNotNull(p_parser->spirv_code));+ assert(IsNotNull(p_parser->nodes));++ if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {+ if (p_parser->function_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ p_parser->functions = (SpvReflectPrvFunction*)calloc(p_parser->function_count,+ sizeof(*(p_parser->functions)));+ if (IsNull(p_parser->functions)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ size_t function_index = 0;+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if (p_node->op != SpvOpFunction) {+ continue;+ }++ // Skip over function declarations that aren't definitions+ bool func_definition = false;+ // Intentionally reuse i to avoid iterating over these nodes more than+ // once+ for (; i < p_parser->node_count; ++i) {+ if (p_parser->nodes[i].op == SpvOpLabel) {+ func_definition = true;+ break;+ }+ if (p_parser->nodes[i].op == SpvOpFunctionEnd) {+ break;+ }+ }+ if (!func_definition) {+ continue;+ }++ SpvReflectPrvFunction* p_function = &(p_parser->functions[function_index]);++ SpvReflectResult result = ParseFunction(p_parser, p_node, p_function, i);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }++ ++function_index;+ }++ qsort(p_parser->functions, p_parser->function_count,+ sizeof(*(p_parser->functions)), SortCompareFunctions);++ // Once they're sorted, link the functions with pointers to improve graph+ // traversal efficiency+ for (size_t i = 0; i < p_parser->function_count; ++i) {+ SpvReflectPrvFunction* p_func = &(p_parser->functions[i]);+ if (p_func->callee_count == 0) {+ continue;+ }+ p_func->callee_ptrs = (SpvReflectPrvFunction**)calloc(p_func->callee_count,+ sizeof(*(p_func->callee_ptrs)));+ for (size_t j = 0, k = 0; j < p_func->callee_count; ++j) {+ while (p_parser->functions[k].id != p_func->callees[j]) {+ ++k;+ if (k >= p_parser->function_count) {+ // Invalid called function ID somewhere+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ }+ p_func->callee_ptrs[j] = &(p_parser->functions[k]);+ }+ }+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseMemberCounts(SpvReflectPrvParser* p_parser)+{+ assert(IsNotNull(p_parser));+ assert(IsNotNull(p_parser->spirv_code));+ assert(IsNotNull(p_parser->nodes));++ if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if ((p_node->op != SpvOpMemberName) && (p_node->op != SpvOpMemberDecorate)) {+ continue;+ }++ uint32_t target_id = 0;+ uint32_t member_index = (uint32_t)INVALID_VALUE;+ CHECKED_READU32(p_parser, p_node->word_offset + 1, target_id);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, member_index);+ SpvReflectPrvNode* p_target_node = FindNode(p_parser, target_id);+ // Not all nodes get parsed, so FindNode returning NULL is expected.+ if (IsNull(p_target_node)) {+ continue;+ }++ if (member_index == INVALID_VALUE) {+ return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;+ }++ p_target_node->member_count = Max(p_target_node->member_count, member_index + 1);+ }++ for (uint32_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if (p_node->member_count == 0) {+ continue;+ }++ p_node->member_names = (const char **)calloc(p_node->member_count, sizeof(*(p_node->member_names)));+ if (IsNull(p_node->member_names)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ p_node->member_decorations = (SpvReflectPrvDecorations*)calloc(p_node->member_count, sizeof(*(p_node->member_decorations)));+ if (IsNull(p_node->member_decorations)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }+ }+ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseNames(SpvReflectPrvParser* p_parser)+{+ assert(IsNotNull(p_parser));+ assert(IsNotNull(p_parser->spirv_code));+ assert(IsNotNull(p_parser->nodes));++ if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if ((p_node->op != SpvOpName) && (p_node->op != SpvOpMemberName)) {+ continue;+ }++ uint32_t target_id = 0;+ CHECKED_READU32(p_parser, p_node->word_offset + 1, target_id);+ SpvReflectPrvNode* p_target_node = FindNode(p_parser, target_id);+ // Not all nodes get parsed, so FindNode returning NULL is expected.+ if (IsNull(p_target_node)) {+ continue;+ }++ const char** pp_target_name = &(p_target_node->name);+ if (p_node->op == SpvOpMemberName) {+ uint32_t member_index = UINT32_MAX;+ CHECKED_READU32(p_parser, p_node->word_offset + 2, member_index);+ pp_target_name = &(p_target_node->member_names[member_index]);+ }++ *pp_target_name = p_node->name;+ }+ }+ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser)+{+ for (uint32_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);++ if (((uint32_t)p_node->op != (uint32_t)SpvOpDecorate) &&+ ((uint32_t)p_node->op != (uint32_t)SpvOpMemberDecorate) &&+ ((uint32_t)p_node->op != (uint32_t)SpvReflectOpDecorateId) &&+ ((uint32_t)p_node->op != (uint32_t)SpvReflectOpDecorateStringGOOGLE) &&+ ((uint32_t)p_node->op != (uint32_t)SpvReflectOpMemberDecorateStringGOOGLE))+ {+ continue;+ }++ // Need to adjust the read offset if this is a member decoration+ uint32_t member_offset = 0;+ if (p_node->op == SpvOpMemberDecorate) {+ member_offset = 1;+ }++ // Get decoration+ uint32_t decoration = (uint32_t)INVALID_VALUE;+ CHECKED_READU32(p_parser, p_node->word_offset + member_offset + 2, decoration);++ // Filter out the decoration that do not affect reflection, otherwise+ // there will be random crashes because the nodes aren't found.+ bool skip = false;+ switch (decoration) {+ default: {+ skip = true;+ }+ break;+ case SpvDecorationRelaxedPrecision:+ case SpvDecorationBlock:+ case SpvDecorationBufferBlock:+ case SpvDecorationColMajor:+ case SpvDecorationRowMajor:+ case SpvDecorationArrayStride:+ case SpvDecorationMatrixStride:+ case SpvDecorationBuiltIn:+ case SpvDecorationNoPerspective:+ case SpvDecorationFlat:+ case SpvDecorationNonWritable:+ case SpvDecorationNonReadable:+ case SpvDecorationLocation:+ case SpvDecorationBinding:+ case SpvDecorationDescriptorSet:+ case SpvDecorationOffset:+ case SpvDecorationInputAttachmentIndex:+ case SpvReflectDecorationHlslCounterBufferGOOGLE:+ case SpvReflectDecorationHlslSemanticGOOGLE: {+ skip = false;+ }+ break; + }+ if (skip) {+ continue;+ } + + // Find target target node + uint32_t target_id = 0;+ CHECKED_READU32(p_parser, p_node->word_offset + 1, target_id);+ SpvReflectPrvNode* p_target_node = FindNode(p_parser, target_id);+ if (IsNull(p_target_node)) {+ if ((p_node->op == (uint32_t)SpvOpDecorate) && (decoration == SpvDecorationRelaxedPrecision)) {+ // Many OPs can be decorated that we don't care about. Ignore those.+ // See https://github.com/KhronosGroup/SPIRV-Reflect/issues/134+ continue;+ }+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // Get decorations+ SpvReflectPrvDecorations* p_target_decorations = &(p_target_node->decorations);+ // Update pointer if this is a member member decoration+ if (p_node->op == SpvOpMemberDecorate) {+ uint32_t member_index = (uint32_t)INVALID_VALUE;+ CHECKED_READU32(p_parser, p_node->word_offset + 2, member_index);+ p_target_decorations = &(p_target_node->member_decorations[member_index]);+ }++ switch (decoration) {+ default: break;++ case SpvDecorationRelaxedPrecision: {+ p_target_decorations->is_relaxed_precision = true;+ }+ break;++ case SpvDecorationBlock: {+ p_target_decorations->is_block = true;+ }+ break;++ case SpvDecorationBufferBlock: {+ p_target_decorations->is_buffer_block = true;+ }+ break;++ case SpvDecorationColMajor: {+ p_target_decorations->is_column_major = true;+ }+ break;++ case SpvDecorationRowMajor: {+ p_target_decorations->is_row_major = true;+ }+ break;++ case SpvDecorationArrayStride: {+ uint32_t word_offset = p_node->word_offset + member_offset + 3;+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->array_stride);+ }+ break;++ case SpvDecorationMatrixStride: {+ uint32_t word_offset = p_node->word_offset + member_offset + 3;+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->matrix_stride);+ }+ break;++ case SpvDecorationBuiltIn: {+ p_target_decorations->is_built_in = true;+ uint32_t word_offset = p_node->word_offset + member_offset + 3;+ CHECKED_READU32_CAST(p_parser, word_offset, SpvBuiltIn, p_target_decorations->built_in);+ }+ break;++ case SpvDecorationNoPerspective: {+ p_target_decorations->is_noperspective = true;+ }+ break;++ case SpvDecorationFlat: {+ p_target_decorations->is_flat = true;+ }+ break;++ case SpvDecorationNonWritable: {+ p_target_decorations->is_non_writable = true;+ }+ break;++ case SpvDecorationNonReadable: {+ p_target_decorations->is_non_readable = true;+ }+ break;++ case SpvDecorationLocation: {+ uint32_t word_offset = p_node->word_offset + member_offset + 3;+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->location.value);+ p_target_decorations->location.word_offset = word_offset;+ }+ break;++ case SpvDecorationBinding: {+ uint32_t word_offset = p_node->word_offset + member_offset+ 3;+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->binding.value);+ p_target_decorations->binding.word_offset = word_offset;+ }+ break;++ case SpvDecorationDescriptorSet: {+ uint32_t word_offset = p_node->word_offset + member_offset+ 3;+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->set.value);+ p_target_decorations->set.word_offset = word_offset;+ }+ break;++ case SpvDecorationOffset: {+ uint32_t word_offset = p_node->word_offset + member_offset+ 3;+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->offset.value);+ p_target_decorations->offset.word_offset = word_offset;+ }+ break;++ case SpvDecorationInputAttachmentIndex: {+ uint32_t word_offset = p_node->word_offset + member_offset+ 3;+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->input_attachment_index.value);+ p_target_decorations->input_attachment_index.word_offset = word_offset;+ }+ break;++ case SpvReflectDecorationHlslCounterBufferGOOGLE: {+ uint32_t word_offset = p_node->word_offset + member_offset+ 3;+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->uav_counter_buffer.value);+ p_target_decorations->uav_counter_buffer.word_offset = word_offset;+ }+ break;++ case SpvReflectDecorationHlslSemanticGOOGLE: {+ uint32_t word_offset = p_node->word_offset + member_offset + 3;+ p_target_decorations->semantic.value = (const char*)(p_parser->spirv_code + word_offset);+ p_target_decorations->semantic.word_offset = word_offset;+ }+ break;+ }+ }+ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult EnumerateAllUniforms(+ SpvReflectShaderModule* p_module,+ size_t* p_uniform_count, + uint32_t** pp_uniforms+)+{+ *p_uniform_count = p_module->descriptor_binding_count;+ if (*p_uniform_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }+ *pp_uniforms = (uint32_t*)calloc(*p_uniform_count, sizeof(**pp_uniforms));++ if (IsNull(*pp_uniforms)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ for (size_t i = 0; i < *p_uniform_count; ++i) {+ (*pp_uniforms)[i] = p_module->descriptor_bindings[i].spirv_id;+ }+ qsort(*pp_uniforms, *p_uniform_count, sizeof(**pp_uniforms),+ SortCompareUint32);+ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseType(+ SpvReflectPrvParser* p_parser, + SpvReflectPrvNode* p_node, + SpvReflectPrvDecorations* p_struct_member_decorations, + SpvReflectShaderModule* p_module, + SpvReflectTypeDescription* p_type+)+{+ SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;++ if (p_node->member_count > 0) {+ p_type->member_count = p_node->member_count;+ p_type->members = (SpvReflectTypeDescription*)calloc(p_type->member_count, sizeof(*(p_type->members)));+ if (IsNotNull(p_type->members)) {+ // Mark all members types with an invalid state+ for (size_t i = 0; i < p_type->members->member_count; ++i) {+ SpvReflectTypeDescription* p_member_type = &(p_type->members[i]);+ p_member_type->id = (uint32_t)INVALID_VALUE;+ p_member_type->op = (SpvOp)INVALID_VALUE;+ p_member_type->storage_class = (SpvStorageClass)INVALID_VALUE;+ }+ }+ else {+ result = SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }++ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ // Since the parse descends on type information, these will get overwritten+ // if not guarded against assignment. Only assign if the id is invalid.+ if (p_type->id == INVALID_VALUE) {+ p_type->id = p_node->result_id;+ p_type->op = p_node->op;+ p_type->decoration_flags = 0;+ }+ // Top level types need to pick up decorations from all types below it.+ // Issue and fix here: https://github.com/chaoticbob/SPIRV-Reflect/issues/64+ p_type->decoration_flags = ApplyDecorations(&p_node->decorations);++ switch (p_node->op) {+ default: break;+ case SpvOpTypeVoid:+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_VOID;+ break;++ case SpvOpTypeBool:+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_BOOL;+ break;++ case SpvOpTypeInt: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_INT;+ IF_READU32(result, p_parser, p_node->word_offset + 2, p_type->traits.numeric.scalar.width);+ IF_READU32(result, p_parser, p_node->word_offset + 3, p_type->traits.numeric.scalar.signedness);+ }+ break;++ case SpvOpTypeFloat: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_FLOAT;+ IF_READU32(result, p_parser, p_node->word_offset + 2, p_type->traits.numeric.scalar.width);+ }+ break;++ case SpvOpTypeVector: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_VECTOR;+ uint32_t component_type_id = (uint32_t)INVALID_VALUE;+ IF_READU32(result, p_parser, p_node->word_offset + 2, component_type_id);+ IF_READU32(result, p_parser, p_node->word_offset + 3, p_type->traits.numeric.vector.component_count);+ // Parse component type+ SpvReflectPrvNode* p_next_node = FindNode(p_parser, component_type_id);+ if (IsNotNull(p_next_node)) {+ result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);+ }+ else {+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ SPV_REFLECT_ASSERT(false);+ }+ }+ break;++ case SpvOpTypeMatrix: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_MATRIX;+ uint32_t column_type_id = (uint32_t)INVALID_VALUE;+ IF_READU32(result, p_parser, p_node->word_offset + 2, column_type_id);+ IF_READU32(result, p_parser, p_node->word_offset + 3, p_type->traits.numeric.matrix.column_count);+ SpvReflectPrvNode* p_next_node = FindNode(p_parser, column_type_id);+ if (IsNotNull(p_next_node)) {+ result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);+ }+ else {+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ SPV_REFLECT_ASSERT(false);+ }+ p_type->traits.numeric.matrix.row_count = p_type->traits.numeric.vector.component_count;+ p_type->traits.numeric.matrix.stride = p_node->decorations.matrix_stride;+ // NOTE: Matrix stride is decorated using OpMemberDecoreate - not OpDecoreate.+ if (IsNotNull(p_struct_member_decorations)) {+ p_type->traits.numeric.matrix.stride = p_struct_member_decorations->matrix_stride;+ }+ }+ break;++ case SpvOpTypeImage: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE;+ uint32_t sampled_type_id = (uint32_t)INVALID_VALUE;+ IF_READU32(result, p_parser, p_node->word_offset + 2, sampled_type_id);+ SpvReflectPrvNode* p_next_node = FindNode(p_parser, sampled_type_id);+ if (IsNotNull(p_next_node)) {+ result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);+ }+ else {+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ IF_READU32_CAST(result, p_parser, p_node->word_offset + 3, SpvDim, p_type->traits.image.dim);+ IF_READU32(result, p_parser, p_node->word_offset + 4, p_type->traits.image.depth);+ IF_READU32(result, p_parser, p_node->word_offset + 5, p_type->traits.image.arrayed);+ IF_READU32(result, p_parser, p_node->word_offset + 6, p_type->traits.image.ms);+ IF_READU32(result, p_parser, p_node->word_offset + 7, p_type->traits.image.sampled);+ IF_READU32_CAST(result, p_parser, p_node->word_offset + 8, SpvImageFormat, p_type->traits.image.image_format);+ }+ break;++ case SpvOpTypeSampler: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER;+ }+ break;++ case SpvOpTypeSampledImage: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE;+ uint32_t image_type_id = (uint32_t)INVALID_VALUE;+ IF_READU32(result, p_parser, p_node->word_offset + 2, image_type_id);+ SpvReflectPrvNode* p_next_node = FindNode(p_parser, image_type_id);+ if (IsNotNull(p_next_node)) {+ result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);+ }+ else {+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + SPV_REFLECT_ASSERT(false);+ }+ }+ break;++ case SpvOpTypeArray: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_ARRAY;+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ uint32_t element_type_id = (uint32_t)INVALID_VALUE;+ uint32_t length_id = (uint32_t)INVALID_VALUE;+ IF_READU32(result, p_parser, p_node->word_offset + 2, element_type_id);+ IF_READU32(result, p_parser, p_node->word_offset + 3, length_id);+ // NOTE: Array stride is decorated using OpDecorate instead of+ // OpMemberDecorate, even if the array is apart of a struct.+ p_type->traits.array.stride = p_node->decorations.array_stride;+ // Get length for current dimension+ SpvReflectPrvNode* p_length_node = FindNode(p_parser, length_id);+ if (IsNotNull(p_length_node)) {+ uint32_t dim_index = p_type->traits.array.dims_count;+ if (p_length_node->op == SpvOpSpecConstant ||+ p_length_node->op == SpvOpSpecConstantOp) {+ p_type->traits.array.dims[dim_index] = 0xFFFFFFFF;+ p_type->traits.array.spec_constant_op_ids[dim_index] = length_id;+ p_type->traits.array.dims_count += 1;+ } else {+ uint32_t length = 0;+ IF_READU32(result, p_parser, p_length_node->word_offset + 3, length);+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ // Write the array dim and increment the count and offset+ p_type->traits.array.dims[dim_index] = length;+ p_type->traits.array.spec_constant_op_ids[dim_index] = 0xFFFFFFFF;+ p_type->traits.array.dims_count += 1;+ } else {+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ SPV_REFLECT_ASSERT(false);+ }+ }+ // Parse next dimension or element type+ SpvReflectPrvNode* p_next_node = FindNode(p_parser, element_type_id);+ if (IsNotNull(p_next_node)) {+ result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);+ }+ }+ else {+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ SPV_REFLECT_ASSERT(false);+ }+ }+ }+ break;++ case SpvOpTypeRuntimeArray: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_ARRAY;+ uint32_t element_type_id = (uint32_t)INVALID_VALUE;+ IF_READU32(result, p_parser, p_node->word_offset + 2, element_type_id);+ p_type->traits.array.stride = p_node->decorations.array_stride;+ uint32_t dim_index = p_type->traits.array.dims_count;+ p_type->traits.array.dims[dim_index] = 0;+ p_type->traits.array.spec_constant_op_ids[dim_index] = 0;+ p_type->traits.array.dims_count += 1;+ // Parse next dimension or element type+ SpvReflectPrvNode* p_next_node = FindNode(p_parser, element_type_id);+ if (IsNotNull(p_next_node)) {+ result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);+ }+ else {+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ SPV_REFLECT_ASSERT(false);+ }+ }+ break;++ case SpvOpTypeStruct: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_STRUCT;+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK;+ uint32_t word_index = 2;+ uint32_t member_index = 0;+ for (; word_index < p_node->word_count; ++word_index, ++member_index) {+ uint32_t member_id = (uint32_t)INVALID_VALUE;+ IF_READU32(result, p_parser, p_node->word_offset + word_index, member_id);+ // Find member node+ SpvReflectPrvNode* p_member_node = FindNode(p_parser, member_id);+ if (IsNull(p_member_node)) {+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ SPV_REFLECT_ASSERT(false);+ break;+ }++ // Member decorations+ SpvReflectPrvDecorations* p_member_decorations = &p_node->member_decorations[member_index];++ assert(member_index < p_type->member_count);+ // Parse member type+ SpvReflectTypeDescription* p_member_type = &(p_type->members[member_index]);+ p_member_type->id = member_id;+ p_member_type->op = p_member_node->op;+ result = ParseType(p_parser, p_member_node, p_member_decorations, p_module, p_member_type);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ break;+ }+ // This looks wrong + //p_member_type->type_name = p_member_node->name;+ p_member_type->struct_member_name = p_node->member_names[member_index];+ }+ }+ break;++ case SpvOpTypeOpaque: break;++ case SpvOpTypePointer: {+ IF_READU32_CAST(result, p_parser, p_node->word_offset + 2, SpvStorageClass, p_type->storage_class);+ uint32_t type_id = (uint32_t)INVALID_VALUE;+ IF_READU32(result, p_parser, p_node->word_offset + 3, type_id);+ // Parse type+ SpvReflectPrvNode* p_next_node = FindNode(p_parser, type_id);+ if (IsNotNull(p_next_node)) {+ result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);+ }+ else {+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ SPV_REFLECT_ASSERT(false);+ }+ }+ break;++ case SpvOpTypeAccelerationStructureKHR: {+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE;+ }+ break;+ }++ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ // Names get assigned on the way down. Guard against names+ // get overwritten on the way up.+ if (IsNull(p_type->type_name)) {+ p_type->type_name = p_node->name;+ }+ }+ }++ return result;+}++static SpvReflectResult ParseTypes(+ SpvReflectPrvParser* p_parser,+ SpvReflectShaderModule* p_module)+{+ if (p_parser->type_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ p_module->_internal->type_description_count = p_parser->type_count;+ p_module->_internal->type_descriptions = (SpvReflectTypeDescription*)calloc(p_module->_internal->type_description_count,+ sizeof(*(p_module->_internal->type_descriptions)));+ if (IsNull(p_module->_internal->type_descriptions)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ // Mark all types with an invalid state+ for (size_t i = 0; i < p_module->_internal->type_description_count; ++i) {+ SpvReflectTypeDescription* p_type = &(p_module->_internal->type_descriptions[i]);+ p_type->id = (uint32_t)INVALID_VALUE;+ p_type->op = (SpvOp)INVALID_VALUE;+ p_type->storage_class = (SpvStorageClass)INVALID_VALUE;+ }++ size_t type_index = 0;+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if (! p_node->is_type) {+ continue;+ }++ SpvReflectTypeDescription* p_type = &(p_module->_internal->type_descriptions[type_index]);+ SpvReflectResult result = ParseType(p_parser, p_node, NULL, p_module, p_type);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ ++type_index;+ }+ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseCapabilities(+ SpvReflectPrvParser* p_parser,+ SpvReflectShaderModule* p_module)+{+ if (p_parser->capability_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ p_module->capability_count = p_parser->capability_count;+ p_module->capabilities = (SpvReflectCapability*)calloc(p_module->capability_count,+ sizeof(*(p_module->capabilities)));+ if (IsNull(p_module->capabilities)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ // Mark all types with an invalid state+ for (size_t i = 0; i < p_module->capability_count; ++i) {+ SpvReflectCapability* p_cap = &(p_module->capabilities[i]);+ p_cap->value = SpvCapabilityMax;+ p_cap->word_offset = (uint32_t)INVALID_VALUE;+ }++ size_t capability_index = 0;+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if (SpvOpCapability != p_node->op) {+ continue;+ }++ SpvReflectCapability* p_cap = &(p_module->capabilities[capability_index]);+ p_cap->value = p_node->capability;+ p_cap->word_offset = p_node->word_offset + 1;+ ++capability_index;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static int SortCompareDescriptorBinding(const void* a, const void* b)+{+ const SpvReflectDescriptorBinding* p_elem_a = (const SpvReflectDescriptorBinding*)a;+ const SpvReflectDescriptorBinding* p_elem_b = (const SpvReflectDescriptorBinding*)b;+ int value = (int)(p_elem_a->binding) - (int)(p_elem_b->binding);+ if (value == 0) {+ // use spirv-id as a tiebreaker to ensure a stable ordering, as they're guaranteed+ // unique.+ assert(p_elem_a->spirv_id != p_elem_b->spirv_id);+ value = (int)(p_elem_a->spirv_id) - (int)(p_elem_b->spirv_id);+ }+ return value;+}++static SpvReflectResult ParseDescriptorBindings(+ SpvReflectPrvParser* p_parser,+ SpvReflectShaderModule* p_module)+{+ p_module->descriptor_binding_count = 0;+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if ((p_node->op != SpvOpVariable) ||+ ((p_node->storage_class != SpvStorageClassUniform) &&+ (p_node->storage_class != SpvStorageClassStorageBuffer) &&+ (p_node->storage_class != SpvStorageClassUniformConstant)))+ {+ continue;+ }+ if ((p_node->decorations.set.value == INVALID_VALUE) || (p_node->decorations.binding.value == INVALID_VALUE)) {+ continue;+ }++ p_module->descriptor_binding_count += 1;+ }++ if (p_module->descriptor_binding_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ p_module->descriptor_bindings = (SpvReflectDescriptorBinding*)calloc(p_module->descriptor_binding_count, sizeof(*(p_module->descriptor_bindings)));+ if (IsNull(p_module->descriptor_bindings)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ // Mark all types with an invalid state+ for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {+ SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);+ p_descriptor->binding = (uint32_t)INVALID_VALUE;+ p_descriptor->input_attachment_index = (uint32_t)INVALID_VALUE;+ p_descriptor->set = (uint32_t)INVALID_VALUE;+ p_descriptor->descriptor_type = (SpvReflectDescriptorType)INVALID_VALUE;+ p_descriptor->uav_counter_id = (uint32_t)INVALID_VALUE;+ }++ size_t descriptor_index = 0;+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if ((p_node->op != SpvOpVariable) ||+ ((p_node->storage_class != SpvStorageClassUniform) &&+ (p_node->storage_class != SpvStorageClassStorageBuffer) &&+ (p_node->storage_class != SpvStorageClassUniformConstant)))+ {+ continue;+ }+ if ((p_node->decorations.set.value == INVALID_VALUE) || (p_node->decorations.binding.value == INVALID_VALUE)) {+ continue;+ }++ SpvReflectTypeDescription* p_type = FindType(p_module, p_node->type_id);+ if (IsNull(p_type)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // If the type is a pointer, resolve it. We need to retain the storage class+ // from the pointer so that we can use it to deduce deescriptor types.+ SpvStorageClass pointer_storage_class = SpvStorageClassMax;+ if (p_type->op == SpvOpTypePointer) {+ pointer_storage_class = p_type->storage_class;+ // Find the type's node+ SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);+ if (IsNull(p_type_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // Should be the resolved type+ p_type = FindType(p_module, p_type_node->type_id);+ if (IsNull(p_type)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ }++ SpvReflectDescriptorBinding* p_descriptor = &p_module->descriptor_bindings[descriptor_index];+ p_descriptor->spirv_id = p_node->result_id;+ p_descriptor->name = p_node->name;+ p_descriptor->binding = p_node->decorations.binding.value;+ p_descriptor->input_attachment_index = p_node->decorations.input_attachment_index.value;+ p_descriptor->set = p_node->decorations.set.value;+ p_descriptor->count = 1;+ p_descriptor->uav_counter_id = p_node->decorations.uav_counter_buffer.value;+ p_descriptor->type_description = p_type;+ p_descriptor->decoration_flags = ApplyDecorations(&p_node->decorations);++ // If this is in the StorageBuffer storage class, it's for sure a storage+ // buffer descriptor. We need to handle this case earlier because in SPIR-V+ // there are two ways to indicate a storage buffer:+ // 1) Uniform storage class + BufferBlock decoration, or+ // 2) StorageBuffer storage class + Buffer decoration.+ // The 1) way is deprecated since SPIR-V v1.3. But the Buffer decoration is+ // also used together with Uniform storage class to mean uniform buffer..+ // We'll handle the pre-v1.3 cases in ParseDescriptorType().+ if (pointer_storage_class == SpvStorageClassStorageBuffer) {+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER;+ }++ // Copy image traits+ if ((p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) == SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE) {+ memcpy(&p_descriptor->image, &p_type->traits.image, sizeof(p_descriptor->image));+ }++ // This is a workaround for: https://github.com/KhronosGroup/glslang/issues/1096+ {+ const uint32_t resource_mask = SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE | SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE;+ if ((p_type->type_flags & resource_mask) == resource_mask) {+ memcpy(&p_descriptor->image, &p_type->traits.image, sizeof(p_descriptor->image));+ }+ }++ // Copy array traits+ if (p_type->traits.array.dims_count > 0) {+ p_descriptor->array.dims_count = p_type->traits.array.dims_count;+ for (uint32_t dim_index = 0; dim_index < p_type->traits.array.dims_count; ++dim_index) {+ uint32_t dim_value = p_type->traits.array.dims[dim_index];+ p_descriptor->array.dims[dim_index] = dim_value;+ p_descriptor->count *= dim_value;+ }+ }++ // Count+++ p_descriptor->word_offset.binding = p_node->decorations.binding.word_offset;+ p_descriptor->word_offset.set = p_node->decorations.set.word_offset;++ ++descriptor_index;+ }++ if (p_module->descriptor_binding_count > 0) {+ qsort(p_module->descriptor_bindings,+ p_module->descriptor_binding_count,+ sizeof(*(p_module->descriptor_bindings)),+ SortCompareDescriptorBinding);+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseDescriptorType(SpvReflectShaderModule* p_module)+{+ if (p_module->descriptor_binding_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {+ SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);+ SpvReflectTypeDescription* p_type = p_descriptor->type_description;++ if ((int)p_descriptor->descriptor_type == (int)INVALID_VALUE) {+ switch (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) {+ default: assert(false && "unknown type flag"); break;++ case SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE: {+ if (p_descriptor->image.dim == SpvDimBuffer) {+ switch (p_descriptor->image.sampled) {+ default: assert(false && "unknown texel buffer sampled value"); break;+ case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break;+ case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break;+ }+ }+ else if(p_descriptor->image.dim == SpvDimSubpassData) {+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;+ }+ else {+ switch (p_descriptor->image.sampled) {+ default: assert(false && "unknown image sampled value"); break;+ case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE; break;+ case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE; break;+ }+ }+ }+ break;++ case SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER: {+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER;+ }+ break;++ case (SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE | SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE): {+ // This is a workaround for: https://github.com/KhronosGroup/glslang/issues/1096+ if (p_descriptor->image.dim == SpvDimBuffer) {+ switch (p_descriptor->image.sampled) {+ default: assert(false && "unknown texel buffer sampled value"); break;+ case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break;+ case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break;+ }+ }+ else {+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;+ }+ }+ break;++ case SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK: {+ if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BLOCK) {+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER;+ }+ else if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BUFFER_BLOCK) {+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER;+ }+ else {+ assert(false && "unknown struct");+ }+ }+ break;++ case SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE: {+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;+ }+ break;+ }+ }++ switch (p_descriptor->descriptor_type) {+ case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SAMPLER; break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : p_descriptor->resource_type = (SpvReflectResourceType)(SPV_REFLECT_RESOURCE_FLAG_SAMPLER | SPV_REFLECT_RESOURCE_FLAG_SRV); break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT : break;+ case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;+ }+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseUAVCounterBindings(SpvReflectShaderModule* p_module)+{+ char name[MAX_NODE_NAME_LENGTH];+ const char* k_count_tag = "@count";++ for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {+ SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);++ if (p_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) {+ continue;+ }++ SpvReflectDescriptorBinding* p_counter_descriptor = NULL;+ // Use UAV counter buffer id if present...+ if (p_descriptor->uav_counter_id != UINT32_MAX) {+ for (uint32_t counter_descriptor_index = 0; counter_descriptor_index < p_module->descriptor_binding_count; ++counter_descriptor_index) {+ SpvReflectDescriptorBinding* p_test_counter_descriptor = &(p_module->descriptor_bindings[counter_descriptor_index]);+ if (p_test_counter_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) {+ continue;+ }+ if (p_descriptor->uav_counter_id == p_test_counter_descriptor->spirv_id) {+ p_counter_descriptor = p_test_counter_descriptor;+ break;+ }+ }+ }+ // ...otherwise use old @count convention.+ else {+ const size_t descriptor_name_length = p_descriptor->name? strlen(p_descriptor->name): 0;++ memset(name, 0, MAX_NODE_NAME_LENGTH); + memcpy(name, p_descriptor->name, descriptor_name_length);+#if defined(_WIN32)+ strcat_s(name, MAX_NODE_NAME_LENGTH, k_count_tag);+#else+ strcat(name, k_count_tag);+#endif++ for (uint32_t counter_descriptor_index = 0; counter_descriptor_index < p_module->descriptor_binding_count; ++counter_descriptor_index) {+ SpvReflectDescriptorBinding* p_test_counter_descriptor = &(p_module->descriptor_bindings[counter_descriptor_index]);+ if (p_test_counter_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) {+ continue;+ }+ if (p_test_counter_descriptor->name && strcmp(name, p_test_counter_descriptor->name) == 0) {+ p_counter_descriptor = p_test_counter_descriptor;+ break;+ }+ }+ }++ if (p_counter_descriptor != NULL) {+ p_descriptor->uav_counter_binding = p_counter_descriptor;+ }+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseDescriptorBlockVariable(+ SpvReflectPrvParser* p_parser, + SpvReflectShaderModule* p_module, + SpvReflectTypeDescription* p_type, + SpvReflectBlockVariable* p_var+)+{+ bool has_non_writable = false;++ if (IsNotNull(p_type->members) && (p_type->member_count > 0)) {+ p_var->member_count = p_type->member_count;+ p_var->members = (SpvReflectBlockVariable*)calloc(p_var->member_count, sizeof(*p_var->members));+ if (IsNull(p_var->members)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);+ if (IsNull(p_type_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // Resolve to element type if current type is array or run time array+ while (p_type_node->op == SpvOpTypeArray || p_type_node->op == SpvOpTypeRuntimeArray) {+ if (p_type_node->op == SpvOpTypeArray) {+ p_type_node = FindNode(p_parser, p_type_node->array_traits.element_type_id);+ }+ else {+ // Element type description+ SpvReflectTypeDescription* p_type_temp = FindType(p_module, p_type_node->array_traits.element_type_id);+ if (IsNull(p_type_temp)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // Element type node+ p_type_node = FindNode(p_parser, p_type_temp->id);+ }+ if (IsNull(p_type_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ }+ + // Parse members+ for (uint32_t member_index = 0; member_index < p_type->member_count; ++member_index) {+ SpvReflectTypeDescription* p_member_type = &p_type->members[member_index];+ SpvReflectBlockVariable* p_member_var = &p_var->members[member_index];+ bool is_struct = (p_member_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) == SPV_REFLECT_TYPE_FLAG_STRUCT;+ if (is_struct) {+ SpvReflectResult result = ParseDescriptorBlockVariable(p_parser, p_module, p_member_type, p_member_var);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ }++ p_member_var->name = p_type_node->member_names[member_index];+ p_member_var->offset = p_type_node->member_decorations[member_index].offset.value;+ p_member_var->decoration_flags = ApplyDecorations(&p_type_node->member_decorations[member_index]);+ p_member_var->flags |= SPV_REFLECT_VARIABLE_FLAGS_UNUSED;+ if (!has_non_writable && (p_member_var->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE)) {+ has_non_writable = true;+ }+ ApplyNumericTraits(p_member_type, &p_member_var->numeric);+ if (p_member_type->op == SpvOpTypeArray) {+ ApplyArrayTraits(p_member_type, &p_member_var->array);+ }++ p_member_var->type_description = p_member_type;+ }+ }++ p_var->name = p_type->type_name;+ p_var->type_description = p_type;+ if (has_non_writable) {+ p_var->decoration_flags |= SPV_REFLECT_DECORATION_NON_WRITABLE;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseDescriptorBlockVariableSizes(+ SpvReflectPrvParser* p_parser, + SpvReflectShaderModule* p_module, + bool is_parent_root, + bool is_parent_aos, + bool is_parent_rta, + SpvReflectBlockVariable* p_var+)+{+ if (p_var->member_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ // Absolute offsets+ for (uint32_t member_index = 0; member_index < p_var->member_count; ++member_index) {+ SpvReflectBlockVariable* p_member_var = &p_var->members[member_index];+ if (is_parent_root) {+ p_member_var->absolute_offset = p_member_var->offset;+ }+ else {+ p_member_var->absolute_offset = is_parent_aos ? 0 : p_member_var->offset + p_var->absolute_offset;+ }+ }++ // Size+ for (uint32_t member_index = 0; member_index < p_var->member_count; ++member_index) {+ SpvReflectBlockVariable* p_member_var = &p_var->members[member_index];+ SpvReflectTypeDescription* p_member_type = p_member_var->type_description;++ switch (p_member_type->op) {+ case SpvOpTypeBool: {+ p_member_var->size = SPIRV_WORD_SIZE;+ }+ break;++ case SpvOpTypeInt:+ case SpvOpTypeFloat: {+ p_member_var->size = p_member_type->traits.numeric.scalar.width / SPIRV_BYTE_WIDTH;+ }+ break;++ case SpvOpTypeVector: {+ uint32_t size = p_member_type->traits.numeric.vector.component_count *+ (p_member_type->traits.numeric.scalar.width / SPIRV_BYTE_WIDTH);+ p_member_var->size = size;+ }+ break;++ case SpvOpTypeMatrix: {+ if (p_member_var->decoration_flags & SPV_REFLECT_DECORATION_COLUMN_MAJOR) {+ p_member_var->size = p_member_var->numeric.matrix.column_count * p_member_var->numeric.matrix.stride;+ }+ else if (p_member_var->decoration_flags & SPV_REFLECT_DECORATION_ROW_MAJOR) {+ p_member_var->size = p_member_var->numeric.matrix.row_count * p_member_var->numeric.matrix.stride;+ }+ }+ break;++ case SpvOpTypeArray: {+ // If array of structs, parse members first...+ bool is_struct = (p_member_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) == SPV_REFLECT_TYPE_FLAG_STRUCT;+ if (is_struct) {+ SpvReflectResult result = ParseDescriptorBlockVariableSizes(p_parser, p_module, false, true, is_parent_rta, p_member_var);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ }+ // ...then array+ uint32_t element_count = (p_member_var->array.dims_count > 0 ? 1 : 0);+ for (uint32_t i = 0; i < p_member_var->array.dims_count; ++i) {+ element_count *= p_member_var->array.dims[i];+ }+ p_member_var->size = element_count * p_member_var->array.stride;+ }+ break;++ case SpvOpTypeRuntimeArray: {+ bool is_struct = (p_member_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) == SPV_REFLECT_TYPE_FLAG_STRUCT;+ if (is_struct) {+ SpvReflectResult result = ParseDescriptorBlockVariableSizes(p_parser, p_module, false, true, true, p_member_var);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ }+ }+ break;++ case SpvOpTypeStruct: {+ SpvReflectResult result = ParseDescriptorBlockVariableSizes(p_parser, p_module, false, is_parent_aos, is_parent_rta, p_member_var);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ }+ break;++ default:+ break;+ }+ }++ // Parse padded size using offset difference for all member except for the last entry...+ for (uint32_t member_index = 0; member_index < (p_var->member_count - 1); ++member_index) {+ SpvReflectBlockVariable* p_member_var = &p_var->members[member_index];+ SpvReflectBlockVariable* p_next_member_var = &p_var->members[member_index + 1];+ p_member_var->padded_size = p_next_member_var->offset - p_member_var->offset;+ if (p_member_var->size > p_member_var->padded_size) {+ p_member_var->size = p_member_var->padded_size;+ }+ if (is_parent_rta) {+ p_member_var->padded_size = p_member_var->size;+ }+ }+ // ...last entry just gets rounded up to near multiple of SPIRV_DATA_ALIGNMENT, which is 16 and+ // subtract the offset.+ if (p_var->member_count > 0) {+ SpvReflectBlockVariable* p_member_var = &p_var->members[p_var->member_count - 1];+ p_member_var->padded_size = RoundUp(p_member_var->offset + p_member_var->size, SPIRV_DATA_ALIGNMENT) - p_member_var->offset;+ if (p_member_var->size > p_member_var->padded_size) {+ p_member_var->size = p_member_var->padded_size;+ }+ if (is_parent_rta) {+ p_member_var->padded_size = p_member_var->size;+ }+ }++ // @TODO validate this with assertion+ p_var->size = p_var->members[p_var->member_count - 1].offset ++ p_var->members[p_var->member_count - 1].padded_size;+ p_var->padded_size = p_var->size;++ return SPV_REFLECT_RESULT_SUCCESS;+}++static void MarkSelfAndAllMemberVarsAsUsed(SpvReflectBlockVariable* p_var)+{+ // Clear the current variable's USED flag+ p_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED;++ SpvOp op_type = p_var->type_description->op;+ switch (op_type) {+ default: break;++ case SpvOpTypeArray: {+ }+ break;++ case SpvOpTypeStruct: {+ for (uint32_t i = 0; i < p_var->member_count; ++i) {+ SpvReflectBlockVariable* p_member_var = &p_var->members[i];+ MarkSelfAndAllMemberVarsAsUsed(p_member_var);+ }+ }+ break;+ }+}++static SpvReflectResult ParseDescriptorBlockVariableUsage(+ SpvReflectPrvParser* p_parser,+ SpvReflectShaderModule* p_module,+ SpvReflectPrvAccessChain* p_access_chain,+ uint32_t index_index,+ SpvOp override_op_type,+ SpvReflectBlockVariable* p_var+)+{+ (void)p_parser;+ (void)p_access_chain;+ (void)p_var;++ // Clear the current variable's UNUSED flag+ p_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED;+ + // Parsing arrays requires overriding the op type for+ // for the lowest dim's element type.+ SpvOp op_type = p_var->type_description->op;+ if (override_op_type != (SpvOp)INVALID_VALUE) {+ op_type = override_op_type;+ }++ switch (op_type) {+ default: break;++ case SpvOpTypeArray: {+ // Parse through array's type hierarchy to find the actual/non-array element type+ SpvReflectTypeDescription* p_type = p_var->type_description;+ while ((p_type->op == SpvOpTypeArray) && (index_index < p_access_chain->index_count)) {+ // Find the array element type id+ SpvReflectPrvNode* p_node = FindNode(p_parser, p_type->id);+ if (p_node == NULL) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ uint32_t element_type_id = p_node->array_traits.element_type_id;+ // Get the array element type+ p_type = FindType(p_module, element_type_id);+ if (p_type == NULL) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // Next access chain index+ index_index += 1;+ }+ + // Only continue parsing if there's remaining indices in the access+ // chain. If the end of the access chain has been reach then all+ // remaining variables (including those in struct hierarchies)+ // are considered USED.+ //+ // See: https://github.com/KhronosGroup/SPIRV-Reflect/issues/78+ // + if (index_index < p_access_chain->index_count) {+ // Parse current var again with a type override and advanced index index+ SpvReflectResult result = ParseDescriptorBlockVariableUsage(+ p_parser,+ p_module,+ p_access_chain,+ index_index,+ p_type->op,+ p_var);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ }+ else {+ // Clear UNUSED flag for remaining variables+ MarkSelfAndAllMemberVarsAsUsed(p_var);+ }+ }+ break;++ case SpvOpTypeStruct: {+ assert(p_var->member_count > 0);+ if (p_var->member_count == 0) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA;+ }+ // Get member variable at the access's chain current index+ uint32_t index = p_access_chain->indexes[index_index];+ if (index >= p_var->member_count) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE;+ }+ SpvReflectBlockVariable* p_member_var = &p_var->members[index];++ // Next access chain index+ index_index += 1;++ // Only continue parsing if there's remaining indices in the access+ // chain. If the end of the access chain has been reach then all+ // remaining variables (including those in struct hierarchies)+ // are considered USED.+ //+ // See: https://github.com/KhronosGroup/SPIRV-Reflect/issues/78+ //+ if (index_index < p_access_chain->index_count) {+ SpvReflectResult result = ParseDescriptorBlockVariableUsage(+ p_parser,+ p_module,+ p_access_chain,+ index_index,+ (SpvOp)INVALID_VALUE,+ p_member_var);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ }+ else {+ // Clear UNUSED flag for remaining variables+ MarkSelfAndAllMemberVarsAsUsed(p_member_var);+ }+ //SpvReflectBlockVariable* p_member_var = &p_var->members[index];+ //if (index_index < p_access_chain->index_count) {+ // SpvReflectResult result = ParseDescriptorBlockVariableUsage(+ // p_parser,+ // p_module,+ // p_access_chain,+ // index_index + 1,+ // (SpvOp)INVALID_VALUE,+ // p_member_var);+ // if (result != SPV_REFLECT_RESULT_SUCCESS) {+ // return result;+ // }+ //}+ }+ break;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseDescriptorBlocks(+ SpvReflectPrvParser* p_parser, + SpvReflectShaderModule* p_module)+{+ if (p_module->descriptor_binding_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {+ SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);+ SpvReflectTypeDescription* p_type = p_descriptor->type_description;+ if ((p_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER) &&+ (p_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) )+ {+ continue;+ }++ // Mark UNUSED+ p_descriptor->block.flags |= SPV_REFLECT_VARIABLE_FLAGS_UNUSED;+ // Parse descriptor block + SpvReflectResult result = ParseDescriptorBlockVariable(p_parser, p_module, p_type, &p_descriptor->block);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }++ for (uint32_t access_chain_index = 0; access_chain_index < p_parser->access_chain_count; ++access_chain_index) {+ SpvReflectPrvAccessChain* p_access_chain = &(p_parser->access_chains[access_chain_index]);+ // Skip any access chains that aren't touching this descriptor block+ if (p_descriptor->spirv_id != p_access_chain->base_id) {+ continue;+ }+ result = ParseDescriptorBlockVariableUsage(+ p_parser,+ p_module,+ p_access_chain,+ 0,+ (SpvOp)INVALID_VALUE,+ &p_descriptor->block);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ }+ + p_descriptor->block.name = p_descriptor->name;++ bool is_parent_rta = (p_descriptor->descriptor_type == SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER);+ result = ParseDescriptorBlockVariableSizes(p_parser, p_module, true, false, is_parent_rta, &p_descriptor->block);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }++ if (is_parent_rta) {+ p_descriptor->block.size = 0;+ p_descriptor->block.padded_size = 0;+ }+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseFormat(+ const SpvReflectTypeDescription* p_type,+ SpvReflectFormat* p_format+)+{+ SpvReflectResult result = SPV_REFLECT_RESULT_ERROR_INTERNAL_ERROR;+ bool signedness = (p_type->traits.numeric.scalar.signedness != 0);+ uint32_t bit_width = p_type->traits.numeric.scalar.width;+ if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_VECTOR) {+ uint32_t component_count = p_type->traits.numeric.vector.component_count;+ if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_FLOAT) {+ switch (bit_width) {+ case 32: {+ switch (component_count) {+ case 2: *p_format = SPV_REFLECT_FORMAT_R32G32_SFLOAT; break;+ case 3: *p_format = SPV_REFLECT_FORMAT_R32G32B32_SFLOAT; break;+ case 4: *p_format = SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT; break;+ }+ }+ break;+ + case 64: {+ switch (component_count) {+ case 2: *p_format = SPV_REFLECT_FORMAT_R64G64_SFLOAT; break;+ case 3: *p_format = SPV_REFLECT_FORMAT_R64G64B64_SFLOAT; break;+ case 4: *p_format = SPV_REFLECT_FORMAT_R64G64B64A64_SFLOAT; break;+ }+ }+ }+ result = SPV_REFLECT_RESULT_SUCCESS;+ }+ else if (p_type->type_flags & (SPV_REFLECT_TYPE_FLAG_INT | SPV_REFLECT_TYPE_FLAG_BOOL)) {+ switch (bit_width) {+ case 32: {+ switch (component_count) {+ case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32_SINT : SPV_REFLECT_FORMAT_R32G32_UINT; break;+ case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32_SINT : SPV_REFLECT_FORMAT_R32G32B32_UINT; break;+ case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32A32_SINT : SPV_REFLECT_FORMAT_R32G32B32A32_UINT; break;+ }+ }+ break;+ + case 64: {+ switch (component_count) {+ case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64_SINT : SPV_REFLECT_FORMAT_R64G64_UINT; break;+ case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64B64_SINT : SPV_REFLECT_FORMAT_R64G64B64_UINT; break;+ case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64B64A64_SINT : SPV_REFLECT_FORMAT_R64G64B64A64_UINT; break;+ }+ }+ }+ result = SPV_REFLECT_RESULT_SUCCESS;+ }+ }+ else if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_FLOAT) {+ switch(bit_width) {+ case 32:+ *p_format = SPV_REFLECT_FORMAT_R32_SFLOAT;+ break;+ case 64:+ *p_format = SPV_REFLECT_FORMAT_R64_SFLOAT;+ break;+ }+ result = SPV_REFLECT_RESULT_SUCCESS;+ }+ else if (p_type->type_flags & (SPV_REFLECT_TYPE_FLAG_INT | SPV_REFLECT_TYPE_FLAG_BOOL)) {+ switch(bit_width) {+ case 32:+ *p_format = signedness ? SPV_REFLECT_FORMAT_R32_SINT : SPV_REFLECT_FORMAT_R32_UINT; break;+ break;+ case 64:+ *p_format = signedness ? SPV_REFLECT_FORMAT_R64_SINT : SPV_REFLECT_FORMAT_R64_UINT; break;+ } + result = SPV_REFLECT_RESULT_SUCCESS;+ }+ else if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) {+ *p_format = SPV_REFLECT_FORMAT_UNDEFINED;+ result = SPV_REFLECT_RESULT_SUCCESS;+ }+ return result;+}++static SpvReflectResult ParseInterfaceVariable(+ SpvReflectPrvParser* p_parser,+ const SpvReflectPrvDecorations* p_var_node_decorations,+ const SpvReflectPrvDecorations* p_type_node_decorations,+ SpvReflectShaderModule* p_module,+ SpvReflectTypeDescription* p_type,+ SpvReflectInterfaceVariable* p_var,+ bool* p_has_built_in+)+{+ SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);+ if (IsNull(p_type_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }++ if (p_type->member_count > 0) {+ p_var->member_count = p_type->member_count;+ p_var->members = (SpvReflectInterfaceVariable*)calloc(p_var->member_count, sizeof(*p_var->members));+ if (IsNull(p_var->members)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ for (uint32_t member_index = 0; member_index < p_type_node->member_count; ++member_index) {+ SpvReflectPrvDecorations* p_member_decorations = &p_type_node->member_decorations[member_index];+ SpvReflectTypeDescription* p_member_type = &p_type->members[member_index];+ SpvReflectInterfaceVariable* p_member_var = &p_var->members[member_index];+ SpvReflectResult result = ParseInterfaceVariable(p_parser, NULL, p_member_decorations, p_module, p_member_type, p_member_var, p_has_built_in);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ SPV_REFLECT_ASSERT(false);+ return result;+ }+ }+ }++ p_var->name = p_type_node->name;+ p_var->decoration_flags = ApplyDecorations(p_type_node_decorations);+ if (p_var_node_decorations != NULL) {+ p_var->decoration_flags |= ApplyDecorations(p_var_node_decorations);+ }+ p_var->built_in = p_type_node_decorations->built_in;+ ApplyNumericTraits(p_type, &p_var->numeric);+ if (p_type->op == SpvOpTypeArray) {+ ApplyArrayTraits(p_type, &p_var->array);+ }++ p_var->type_description = p_type;++ *p_has_built_in |= p_type_node_decorations->is_built_in;++ // Only parse format for interface variables that are input or output+ if ((p_var->storage_class == SpvStorageClassInput) || (p_var->storage_class == SpvStorageClassOutput)) {+ SpvReflectResult result = ParseFormat(p_var->type_description, &p_var->format);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ SPV_REFLECT_ASSERT(false);+ return result;+ }+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseInterfaceVariables(+ SpvReflectPrvParser* p_parser,+ SpvReflectShaderModule* p_module,+ SpvReflectEntryPoint* p_entry,+ uint32_t interface_variable_count,+ uint32_t* p_interface_variable_ids+)+{+ if (interface_variable_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ p_entry->interface_variable_count = interface_variable_count;+ p_entry->input_variable_count = 0;+ p_entry->output_variable_count = 0; + for (size_t i = 0; i < interface_variable_count; ++i) {+ uint32_t var_result_id = *(p_interface_variable_ids + i);+ SpvReflectPrvNode* p_node = FindNode(p_parser, var_result_id);+ if (IsNull(p_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ + if (p_node->storage_class == SpvStorageClassInput) {+ p_entry->input_variable_count += 1;+ }+ else if (p_node->storage_class == SpvStorageClassOutput) {+ p_entry->output_variable_count += 1;+ }+ }+ + if (p_entry->input_variable_count > 0) {+ p_entry->input_variables = (SpvReflectInterfaceVariable**)calloc(p_entry->input_variable_count, sizeof(*(p_entry->input_variables)));+ if (IsNull(p_entry->input_variables)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }+ + if (p_entry->output_variable_count > 0) {+ p_entry->output_variables = (SpvReflectInterfaceVariable**)calloc(p_entry->output_variable_count, sizeof(*(p_entry->output_variables)));+ if (IsNull(p_entry->output_variables)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }++ if (p_entry->interface_variable_count > 0) {+ p_entry->interface_variables = (SpvReflectInterfaceVariable*)calloc(p_entry->interface_variable_count, sizeof(*(p_entry->interface_variables)));+ if (IsNull(p_entry->interface_variables)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }++ size_t input_index = 0;+ size_t output_index = 0;+ for (size_t i = 0; i < interface_variable_count; ++i) {+ uint32_t var_result_id = *(p_interface_variable_ids + i);+ SpvReflectPrvNode* p_node = FindNode(p_parser, var_result_id);+ if (IsNull(p_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }++ SpvReflectTypeDescription* p_type = FindType(p_module, p_node->type_id);+ if (IsNull(p_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // If the type is a pointer, resolve it+ if (p_type->op == SpvOpTypePointer) {+ // Find the type's node+ SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);+ if (IsNull(p_type_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // Should be the resolved type+ p_type = FindType(p_module, p_type_node->type_id);+ if (IsNull(p_type)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ }++ SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);+ if (IsNull(p_type_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }++ SpvReflectInterfaceVariable* p_var = &(p_entry->interface_variables[i]);+ p_var->storage_class = p_node->storage_class;++ bool has_built_in = p_node->decorations.is_built_in;+ SpvReflectResult result = ParseInterfaceVariable(+ p_parser,+ &p_node->decorations,+ &p_type_node->decorations,+ p_module,+ p_type,+ p_var,+ &has_built_in);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ SPV_REFLECT_ASSERT(false);+ return result;+ }++ // Input and output variables+ if (p_var->storage_class == SpvStorageClassInput) {+ p_entry->input_variables[input_index] = p_var;+ ++input_index;+ }+ else if (p_node->storage_class == SpvStorageClassOutput) {+ p_entry->output_variables[output_index] = p_var;+ ++output_index;+ }++ // SPIR-V result id+ p_var->spirv_id = p_node->result_id;+ // Name+ p_var->name = p_node->name;+ // Semantic+ p_var->semantic = p_node->decorations.semantic.value;++ // Decorate with built-in if any member is built-in+ if (has_built_in) {+ p_var->decoration_flags |= SPV_REFLECT_DECORATION_BUILT_IN;+ }++ // Location is decorated on OpVariable node, not the type node.+ p_var->location = p_node->decorations.location.value;+ p_var->word_offset.location = p_node->decorations.location.word_offset;++ // Built in+ if (p_node->decorations.is_built_in) {+ p_var->built_in = p_node->decorations.built_in;+ }+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult EnumerateAllPushConstants(+ SpvReflectShaderModule* p_module,+ size_t* p_push_constant_count,+ uint32_t** p_push_constants+)+{+ *p_push_constant_count = p_module->push_constant_block_count;+ if (*p_push_constant_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }+ *p_push_constants = (uint32_t*)calloc(*p_push_constant_count, sizeof(**p_push_constants));++ if (IsNull(*p_push_constants)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ for (size_t i = 0; i < *p_push_constant_count; ++i) {+ (*p_push_constants)[i] = p_module->push_constant_blocks[i].spirv_id;+ }+ qsort(*p_push_constants, *p_push_constant_count, sizeof(**p_push_constants),+ SortCompareUint32);+ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult TraverseCallGraph(+ SpvReflectPrvParser* p_parser,+ SpvReflectPrvFunction* p_func,+ size_t* p_func_count,+ uint32_t* p_func_ids,+ uint32_t depth+)+{+ if (depth > p_parser->function_count) {+ // Vulkan does not permit recursion (Vulkan spec Appendix A):+ // "Recursion: The static function-call graph for an entry point must not+ // contain cycles."+ return SPV_REFLECT_RESULT_ERROR_SPIRV_RECURSION;+ }+ if (IsNotNull(p_func_ids)) {+ p_func_ids[(*p_func_count)++] = p_func->id;+ } else {+ ++*p_func_count;+ }+ for (size_t i = 0; i < p_func->callee_count; ++i) {+ SpvReflectResult result = TraverseCallGraph(+ p_parser, p_func->callee_ptrs[i], p_func_count, p_func_ids, depth + 1);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ }+ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseStaticallyUsedResources(+ SpvReflectPrvParser* p_parser,+ SpvReflectShaderModule* p_module,+ SpvReflectEntryPoint* p_entry,+ size_t uniform_count,+ uint32_t* uniforms,+ size_t push_constant_count,+ uint32_t* push_constants+)+{+ // Find function with the right id+ SpvReflectPrvFunction* p_func = NULL;+ for (size_t i = 0; i < p_parser->function_count; ++i) {+ if (p_parser->functions[i].id == p_entry->id) {+ p_func = &(p_parser->functions[i]);+ break;+ }+ }+ if (p_func == NULL) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }++ size_t called_function_count = 0;+ SpvReflectResult result = TraverseCallGraph(+ p_parser,+ p_func,+ &called_function_count,+ NULL,+ 0);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }++ uint32_t* p_called_functions = NULL;+ if (called_function_count > 0) {+ p_called_functions = (uint32_t*)calloc(called_function_count, sizeof(*p_called_functions));+ if (IsNull(p_called_functions)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }++ called_function_count = 0;+ result = TraverseCallGraph(+ p_parser,+ p_func,+ &called_function_count,+ p_called_functions,+ 0);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }++ if (called_function_count > 0) {+ qsort(+ p_called_functions, + called_function_count, + sizeof(*p_called_functions),+ SortCompareUint32);+ }+ called_function_count = DedupSortedUint32(p_called_functions, called_function_count);++ uint32_t used_variable_count = 0;+ for (size_t i = 0, j = 0; i < called_function_count; ++i) {+ // No need to bounds check j because a missing ID issue would have been+ // found during TraverseCallGraph+ while (p_parser->functions[j].id != p_called_functions[i]) {+ ++j;+ }+ used_variable_count += p_parser->functions[j].accessed_ptr_count;+ }+ uint32_t* used_variables = NULL;+ if (used_variable_count > 0) {+ used_variables = (uint32_t*)calloc(used_variable_count,+ sizeof(*used_variables));+ if (IsNull(used_variables)) {+ SafeFree(p_called_functions);+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }+ used_variable_count = 0;+ for (size_t i = 0, j = 0; i < called_function_count; ++i) {+ while (p_parser->functions[j].id != p_called_functions[i]) {+ ++j;+ }++ memcpy(&used_variables[used_variable_count],+ p_parser->functions[j].accessed_ptrs,+ p_parser->functions[j].accessed_ptr_count * sizeof(*used_variables));+ used_variable_count += p_parser->functions[j].accessed_ptr_count;+ }+ SafeFree(p_called_functions);++ if (used_variable_count > 0) {+ qsort(used_variables, used_variable_count, sizeof(*used_variables),+ SortCompareUint32);+ }+ used_variable_count = (uint32_t)DedupSortedUint32(used_variables, + used_variable_count);++ // Do set intersection to find the used uniform and push constants+ size_t used_uniform_count = 0;+ //+ SpvReflectResult result0 = IntersectSortedUint32(+ used_variables,+ used_variable_count,+ uniforms, + uniform_count,+ &p_entry->used_uniforms,+ &used_uniform_count);++ size_t used_push_constant_count = 0;+ //+ SpvReflectResult result1 = IntersectSortedUint32(+ used_variables, + used_variable_count,+ push_constants, + push_constant_count,+ &p_entry->used_push_constants,+ &used_push_constant_count);++ for (uint32_t j = 0; j < p_module->descriptor_binding_count; ++j) {+ SpvReflectDescriptorBinding* p_binding = &p_module->descriptor_bindings[j];+ bool found = SearchSortedUint32(+ used_variables,+ used_variable_count,+ p_binding->spirv_id);+ if (found) {+ p_binding->accessed = 1;+ }+ }++ SafeFree(used_variables);+ if (result0 != SPV_REFLECT_RESULT_SUCCESS) {+ return result0;+ }+ if (result1 != SPV_REFLECT_RESULT_SUCCESS) {+ return result1;+ }++ p_entry->used_uniform_count = (uint32_t)used_uniform_count;+ p_entry->used_push_constant_count = (uint32_t)used_push_constant_count;++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseEntryPoints(+ SpvReflectPrvParser* p_parser, + SpvReflectShaderModule* p_module)+{+ if (p_parser->entry_point_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ p_module->entry_point_count = p_parser->entry_point_count;+ p_module->entry_points = (SpvReflectEntryPoint*)calloc(p_module->entry_point_count,+ sizeof(*(p_module->entry_points)));+ if (IsNull(p_module->entry_points)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ SpvReflectResult result;+ size_t uniform_count = 0;+ uint32_t* uniforms = NULL;+ if ((result = EnumerateAllUniforms(p_module, &uniform_count, &uniforms)) !=+ SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ size_t push_constant_count = 0;+ uint32_t* push_constants = NULL;+ if ((result = EnumerateAllPushConstants(p_module, &push_constant_count, &push_constants)) !=+ SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }++ size_t entry_point_index = 0;+ for (size_t i = 0; entry_point_index < p_parser->entry_point_count && i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if (p_node->op != SpvOpEntryPoint) {+ continue;+ }++ SpvReflectEntryPoint* p_entry_point = &(p_module->entry_points[entry_point_index]);+ CHECKED_READU32_CAST(p_parser, p_node->word_offset + 1, SpvExecutionModel, p_entry_point->spirv_execution_model);+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_entry_point->id);++ switch (p_entry_point->spirv_execution_model) {+ default: break;+ case SpvExecutionModelVertex : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_VERTEX_BIT; break;+ case SpvExecutionModelTessellationControl : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TESSELLATION_CONTROL_BIT; break;+ case SpvExecutionModelTessellationEvaluation : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; break;+ case SpvExecutionModelGeometry : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_GEOMETRY_BIT; break;+ case SpvExecutionModelFragment : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_FRAGMENT_BIT; break;+ case SpvExecutionModelGLCompute : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_COMPUTE_BIT; break;+ case SpvExecutionModelTaskNV : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV; break;+ case SpvExecutionModelMeshNV : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV; break;+ case SpvExecutionModelRayGenerationKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR; break;+ case SpvExecutionModelIntersectionKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR; break;+ case SpvExecutionModelAnyHitKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR; break;+ case SpvExecutionModelClosestHitKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; break;+ case SpvExecutionModelMissKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR; break;+ case SpvExecutionModelCallableKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR; break;+ }++ ++entry_point_index;++ // Name length is required to calculate next operand+ uint32_t name_start_word_offset = 3;+ uint32_t name_length_with_terminator = 0;+ result = ReadStr(p_parser, p_node->word_offset + name_start_word_offset, 0, p_node->word_count, &name_length_with_terminator, NULL);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ p_entry_point->name = (const char*)(p_parser->spirv_code + p_node->word_offset + name_start_word_offset);++ uint32_t name_word_count = RoundUp(name_length_with_terminator, SPIRV_WORD_SIZE) / SPIRV_WORD_SIZE;+ uint32_t interface_variable_count = (p_node->word_count - (name_start_word_offset + name_word_count));+ uint32_t* p_interface_variables = NULL;+ if (interface_variable_count > 0) {+ p_interface_variables = (uint32_t*)calloc(interface_variable_count, sizeof(*(p_interface_variables)));+ if (IsNull(p_interface_variables)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }++ for (uint32_t var_index = 0; var_index < interface_variable_count; ++var_index) {+ uint32_t var_result_id = (uint32_t)INVALID_VALUE;+ uint32_t offset = name_start_word_offset + name_word_count + var_index;+ CHECKED_READU32(p_parser, p_node->word_offset + offset, var_result_id);+ p_interface_variables[var_index] = var_result_id;+ }++ result = ParseInterfaceVariables(+ p_parser,+ p_module,+ p_entry_point,+ interface_variable_count,+ p_interface_variables);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ SafeFree(p_interface_variables);++ result = ParseStaticallyUsedResources(+ p_parser,+ p_module,+ p_entry_point,+ uniform_count,+ uniforms,+ push_constant_count,+ push_constants);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ }++ SafeFree(uniforms);+ SafeFree(push_constants);++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseExecutionModes(+ SpvReflectPrvParser* p_parser,+ SpvReflectShaderModule* p_module)+{+ assert(IsNotNull(p_parser));+ assert(IsNotNull(p_parser->nodes));+ assert(IsNotNull(p_module));++ if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {+ for (size_t node_idx = 0; node_idx < p_parser->node_count; ++node_idx) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[node_idx]);+ if (p_node->op != SpvOpExecutionMode) {+ continue;+ }++ // Read entry point id+ uint32_t entry_point_id = 0;+ CHECKED_READU32(p_parser, p_node->word_offset + 1, entry_point_id);++ // Find entry point+ SpvReflectEntryPoint* p_entry_point = NULL;+ for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) {+ if (p_module->entry_points[entry_point_idx].id == entry_point_id) {+ p_entry_point = &p_module->entry_points[entry_point_idx];+ break;+ }+ }+ // Bail if entry point is null+ if (IsNull(p_entry_point)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT;+ }++ // Read execution mode+ uint32_t execution_mode = (uint32_t)INVALID_VALUE;+ CHECKED_READU32(p_parser, p_node->word_offset + 2, execution_mode);++ // Parse execution mode+ switch (execution_mode) {+ default: {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE;+ }+ break;++ case SpvExecutionModeInvocations: {+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->invocations);+ }+ break;++ case SpvExecutionModeSpacingEqual:+ case SpvExecutionModeSpacingFractionalEven:+ case SpvExecutionModeSpacingFractionalOdd:+ case SpvExecutionModeVertexOrderCw:+ case SpvExecutionModeVertexOrderCcw:+ case SpvExecutionModePixelCenterInteger:+ case SpvExecutionModeOriginUpperLeft:+ case SpvExecutionModeOriginLowerLeft:+ case SpvExecutionModeEarlyFragmentTests:+ case SpvExecutionModePointMode:+ case SpvExecutionModeXfb:+ case SpvExecutionModeDepthReplacing:+ case SpvExecutionModeDepthGreater:+ case SpvExecutionModeDepthLess:+ case SpvExecutionModeDepthUnchanged:+ break;++ case SpvExecutionModeLocalSize: {+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->local_size.x);+ CHECKED_READU32(p_parser, p_node->word_offset + 4, p_entry_point->local_size.y);+ CHECKED_READU32(p_parser, p_node->word_offset + 5, p_entry_point->local_size.z);+ }+ break;++ case SpvExecutionModeLocalSizeHint:+ case SpvExecutionModeInputPoints:+ case SpvExecutionModeInputLines:+ case SpvExecutionModeInputLinesAdjacency:+ case SpvExecutionModeTriangles:+ case SpvExecutionModeInputTrianglesAdjacency:+ case SpvExecutionModeQuads:+ case SpvExecutionModeIsolines:+ case SpvExecutionModeOutputVertices: {+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->output_vertices);+ }+ break;++ case SpvExecutionModeOutputPoints:+ case SpvExecutionModeOutputLineStrip:+ case SpvExecutionModeOutputTriangleStrip:+ case SpvExecutionModeVecTypeHint:+ case SpvExecutionModeContractionOff:+ case SpvExecutionModeInitializer:+ case SpvExecutionModeFinalizer:+ case SpvExecutionModeSubgroupSize:+ case SpvExecutionModeSubgroupsPerWorkgroup:+ case SpvExecutionModeSubgroupsPerWorkgroupId:+ case SpvExecutionModeLocalSizeId:+ case SpvExecutionModeLocalSizeHintId:+ case SpvExecutionModePostDepthCoverage:+ case SpvExecutionModeDenormPreserve:+ case SpvExecutionModeDenormFlushToZero:+ case SpvExecutionModeSignedZeroInfNanPreserve:+ case SpvExecutionModeRoundingModeRTE:+ case SpvExecutionModeRoundingModeRTZ:+ case SpvExecutionModeStencilRefReplacingEXT:+ case SpvExecutionModeOutputLinesNV:+ case SpvExecutionModeOutputPrimitivesNV:+ case SpvExecutionModeOutputTrianglesNV:+ break;+ }+ p_entry_point->execution_mode_count++;+ }+ uint32_t* indices = (uint32_t*)calloc(p_module->entry_point_count, sizeof(indices));+ if (IsNull(indices)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) {+ SpvReflectEntryPoint* p_entry_point = &p_module->entry_points[entry_point_idx];+ p_entry_point->execution_modes =+ (SpvExecutionMode*)calloc(p_entry_point->execution_mode_count, sizeof(*p_entry_point->execution_modes));+ if (IsNull(p_entry_point->execution_modes)) {+ SafeFree(indices);+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }++ for (size_t node_idx = 0; node_idx < p_parser->node_count; ++node_idx) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[node_idx]);+ if (p_node->op != SpvOpExecutionMode) {+ continue;+ }++ // Read entry point id+ uint32_t entry_point_id = 0;+ CHECKED_READU32(p_parser, p_node->word_offset + 1, entry_point_id);++ // Find entry point+ SpvReflectEntryPoint* p_entry_point = NULL;+ uint32_t* idx = NULL;+ for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) {+ if (p_module->entry_points[entry_point_idx].id == entry_point_id) {+ p_entry_point = &p_module->entry_points[entry_point_idx];+ idx = &indices[entry_point_idx];+ break;+ }+ }++ // Read execution mode+ uint32_t execution_mode = (uint32_t)INVALID_VALUE;+ CHECKED_READU32(p_parser, p_node->word_offset + 2, execution_mode);+ p_entry_point->execution_modes[(*idx)++] = (SpvExecutionMode)execution_mode;+ }+ SafeFree(indices);+ }+ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParsePushConstantBlocks(+ SpvReflectPrvParser* p_parser, + SpvReflectShaderModule* p_module)+{+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if ((p_node->op != SpvOpVariable) || (p_node->storage_class != SpvStorageClassPushConstant)) {+ continue;+ }++ p_module->push_constant_block_count += 1;+ }++ if (p_module->push_constant_block_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ p_module->push_constant_blocks = (SpvReflectBlockVariable*)calloc(p_module->push_constant_block_count, sizeof(*p_module->push_constant_blocks));+ if (IsNull(p_module->push_constant_blocks)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }++ uint32_t push_constant_index = 0;+ for (size_t i = 0; i < p_parser->node_count; ++i) {+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);+ if ((p_node->op != SpvOpVariable) || (p_node->storage_class != SpvStorageClassPushConstant)) {+ continue;+ }++ SpvReflectTypeDescription* p_type = FindType(p_module, p_node->type_id);+ if (IsNull(p_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // If the type is a pointer, resolve it+ if (p_type->op == SpvOpTypePointer) {+ // Find the type's node+ SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);+ if (IsNull(p_type_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ // Should be the resolved type+ p_type = FindType(p_module, p_type_node->type_id);+ if (IsNull(p_type)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }+ }++ SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);+ if (IsNull(p_type_node)) {+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;+ }++ SpvReflectBlockVariable* p_push_constant = &p_module->push_constant_blocks[push_constant_index];+ p_push_constant->spirv_id = p_node->result_id;+ SpvReflectResult result = ParseDescriptorBlockVariable(p_parser, p_module, p_type, p_push_constant);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }+ result = ParseDescriptorBlockVariableSizes(p_parser, p_module, true, false, false, p_push_constant);+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ return result;+ }++ ++push_constant_index;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static int SortCompareDescriptorSet(const void* a, const void* b)+{+ const SpvReflectDescriptorSet* p_elem_a = (const SpvReflectDescriptorSet*)a;+ const SpvReflectDescriptorSet* p_elem_b = (const SpvReflectDescriptorSet*)b;+ int value = (int)(p_elem_a->set) - (int)(p_elem_b->set);+ // We should never see duplicate descriptor set numbers in a shader; if so, a tiebreaker+ // would be needed here.+ assert(value != 0);+ return value;+}++static SpvReflectResult ParseEntrypointDescriptorSets(SpvReflectShaderModule* p_module) {+ // Update the entry point's sets+ for (uint32_t i = 0; i < p_module->entry_point_count; ++i) {+ SpvReflectEntryPoint* p_entry = &p_module->entry_points[i];+ for (uint32_t j = 0; j < p_entry->descriptor_set_count; ++j) {+ SafeFree(p_entry->descriptor_sets[j].bindings);+ }+ SafeFree(p_entry->descriptor_sets);+ p_entry->descriptor_set_count = 0;+ for (uint32_t j = 0; j < p_module->descriptor_set_count; ++j) {+ const SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[j];+ for (uint32_t k = 0; k < p_set->binding_count; ++k) {+ bool found = SearchSortedUint32(+ p_entry->used_uniforms,+ p_entry->used_uniform_count,+ p_set->bindings[k]->spirv_id);+ if (found) {+ ++p_entry->descriptor_set_count;+ break;+ }+ }+ }++ p_entry->descriptor_sets = NULL;+ if (p_entry->descriptor_set_count > 0) {+ p_entry->descriptor_sets = (SpvReflectDescriptorSet*)calloc(p_entry->descriptor_set_count,+ sizeof(*p_entry->descriptor_sets));+ if (IsNull(p_entry->descriptor_sets)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ }+ p_entry->descriptor_set_count = 0;+ for (uint32_t j = 0; j < p_module->descriptor_set_count; ++j) {+ const SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[j];+ uint32_t count = 0;+ for (uint32_t k = 0; k < p_set->binding_count; ++k) {+ bool found = SearchSortedUint32(+ p_entry->used_uniforms,+ p_entry->used_uniform_count,+ p_set->bindings[k]->spirv_id);+ if (found) {+ ++count;+ }+ }+ if (count == 0) {+ continue;+ }+ SpvReflectDescriptorSet* p_entry_set = &p_entry->descriptor_sets[+ p_entry->descriptor_set_count++];+ p_entry_set->set = p_set->set;+ p_entry_set->bindings = (SpvReflectDescriptorBinding**)calloc(count,+ sizeof(*p_entry_set->bindings));+ if (IsNull(p_entry_set->bindings)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ for (uint32_t k = 0; k < p_set->binding_count; ++k) {+ bool found = SearchSortedUint32(+ p_entry->used_uniforms,+ p_entry->used_uniform_count,+ p_set->bindings[k]->spirv_id);+ if (found) {+ p_entry_set->bindings[p_entry_set->binding_count++] = p_set->bindings[k];+ }+ }+ }+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult ParseDescriptorSets(SpvReflectShaderModule* p_module)+{+ // Count the descriptors in each set+ for (uint32_t i = 0; i < p_module->descriptor_binding_count; ++i) {+ SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[i]);++ // Look for a target set using the descriptor's set number+ SpvReflectDescriptorSet* p_target_set = NULL;+ for (uint32_t j = 0; j < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++j) {+ SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[j];+ if (p_set->set == p_descriptor->set) {+ p_target_set = p_set;+ break;+ }+ }++ // If a target set isn't found, find the first available one.+ if (IsNull(p_target_set)) {+ for (uint32_t j = 0; j < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++j) {+ SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[j];+ if (p_set->set == (uint32_t)INVALID_VALUE) {+ p_target_set = p_set;+ p_target_set->set = p_descriptor->set;+ break;+ }+ }+ }++ if (IsNull(p_target_set)) {+ return SPV_REFLECT_RESULT_ERROR_INTERNAL_ERROR;+ }++ p_target_set->binding_count += 1;+ }++ // Count the descriptor sets+ for (uint32_t i = 0; i < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++i) {+ const SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[i];+ if (p_set->set != (uint32_t)INVALID_VALUE) {+ p_module->descriptor_set_count += 1;+ }+ }++ // Sort the descriptor sets based on numbers+ if (p_module->descriptor_set_count > 0) {+ qsort(p_module->descriptor_sets,+ p_module->descriptor_set_count,+ sizeof(*(p_module->descriptor_sets)),+ SortCompareDescriptorSet);+ }++ // Build descriptor pointer array+ for (uint32_t i = 0; i <p_module->descriptor_set_count; ++i) {+ SpvReflectDescriptorSet* p_set = &(p_module->descriptor_sets[i]);+ p_set->bindings = (SpvReflectDescriptorBinding **)calloc(p_set->binding_count, sizeof(*(p_set->bindings)));++ uint32_t descriptor_index = 0;+ for (uint32_t j = 0; j < p_module->descriptor_binding_count; ++j) {+ SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[j]);+ if (p_descriptor->set == p_set->set) {+ assert(descriptor_index < p_set->binding_count);+ p_set->bindings[descriptor_index] = p_descriptor;+ ++descriptor_index;+ }+ }+ }++ return ParseEntrypointDescriptorSets(p_module);+}++static SpvReflectResult DisambiguateStorageBufferSrvUav(SpvReflectShaderModule* p_module)+{+ if (p_module->descriptor_binding_count == 0) {+ return SPV_REFLECT_RESULT_SUCCESS;+ }++ for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {+ SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);+ // Skip everything that isn't a STORAGE_BUFFER descriptor+ if (p_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) {+ continue;+ }++ //+ // Vulkan doesn't disambiguate between SRVs and UAVs so they+ // come back as STORAGE_BUFFER. The block parsing process will+ // mark a block as non-writable should any member of the block+ // or its descendants are non-writable.+ //+ if (p_descriptor->block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) {+ p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV;+ }+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++static SpvReflectResult SynchronizeDescriptorSets(SpvReflectShaderModule* p_module)+{+ // Free and reset all descriptor set numbers+ for (uint32_t i = 0; i < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++i) {+ SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[i];+ SafeFree(p_set->bindings);+ p_set->binding_count = 0;+ p_set->set = (uint32_t)INVALID_VALUE;+ }+ // Set descriptor set count to zero+ p_module->descriptor_set_count = 0;++ SpvReflectResult result = ParseDescriptorSets(p_module);+ return result;+}++static SpvReflectResult CreateShaderModule(+ uint32_t flags,+ size_t size,+ const void* p_code,+ SpvReflectShaderModule* p_module+)+{+ // Initialize all module fields to zero+ memset(p_module, 0, sizeof(*p_module));++ // Allocate module internals+#ifdef __cplusplus+ p_module->_internal = (SpvReflectShaderModule::Internal*)calloc(1, sizeof(*(p_module->_internal)));+#else+ p_module->_internal = calloc(1, sizeof(*(p_module->_internal)));+#endif+ if (IsNull(p_module->_internal)) {+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ // Copy flags+ p_module->_internal->module_flags = flags;+ // Figure out if we need to copy the SPIR-V code or not+ if (flags & SPV_REFLECT_MODULE_FLAG_NO_COPY) {+ // Set internal size and pointer to args passed in+ p_module->_internal->spirv_size = size;+#if defined(__cplusplus)+ p_module->_internal->spirv_code = const_cast<uint32_t*>(static_cast<const uint32_t*>(p_code)); // cast that const away+#else+ p_module->_internal->spirv_code = (void*)p_code; // cast that const away+#endif+ p_module->_internal->spirv_word_count = (uint32_t)(size / SPIRV_WORD_SIZE);+ }+ else {+ // Allocate SPIR-V code storage+ p_module->_internal->spirv_size = size;+ p_module->_internal->spirv_code = (uint32_t*)calloc(1, p_module->_internal->spirv_size);+ p_module->_internal->spirv_word_count = (uint32_t)(size / SPIRV_WORD_SIZE);+ if (IsNull(p_module->_internal->spirv_code)) {+ SafeFree(p_module->_internal);+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;+ }+ // Copy SPIR-V to code storage+ memcpy(p_module->_internal->spirv_code, p_code, size);+ }++ SpvReflectPrvParser parser = { 0 };+ SpvReflectResult result = CreateParser(p_module->_internal->spirv_size,+ p_module->_internal->spirv_code,+ &parser);++ // Generator+ {+ const uint32_t* p_ptr = (const uint32_t*)p_module->_internal->spirv_code;+ p_module->generator = (SpvReflectGenerator)((*(p_ptr + 2) & 0xFFFF0000) >> 16);+ }++ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseNodes(&parser);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseStrings(&parser);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseSource(&parser, p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseFunctions(&parser);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseMemberCounts(&parser);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseNames(&parser);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseDecorations(&parser);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }++ // Start of reflection data parsing+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ p_module->source_language = parser.source_language;+ p_module->source_language_version = parser.source_language_version;++ // Zero out descriptor set data+ p_module->descriptor_set_count = 0;+ memset(p_module->descriptor_sets, 0, SPV_REFLECT_MAX_DESCRIPTOR_SETS * sizeof(*p_module->descriptor_sets));+ // Initialize descriptor set numbers+ for (uint32_t set_number = 0; set_number < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++set_number) {+ p_module->descriptor_sets[set_number].set = (uint32_t)INVALID_VALUE;+ }+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseTypes(&parser, p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseDescriptorBindings(&parser, p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseDescriptorType(p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseUAVCounterBindings(p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseDescriptorBlocks(&parser, p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParsePushConstantBlocks(&parser, p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseEntryPoints(&parser, p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseCapabilities(&parser, p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS && p_module->entry_point_count > 0) {+ SpvReflectEntryPoint* p_entry = &(p_module->entry_points[0]);+ p_module->entry_point_name = p_entry->name;+ p_module->entry_point_id = p_entry->id;+ p_module->spirv_execution_model = p_entry->spirv_execution_model;+ p_module->shader_stage = p_entry->shader_stage;+ p_module->input_variable_count = p_entry->input_variable_count;+ p_module->input_variables = p_entry->input_variables;+ p_module->output_variable_count = p_entry->output_variable_count;+ p_module->output_variables = p_entry->output_variables;+ p_module->interface_variable_count = p_entry->interface_variable_count;+ p_module->interface_variables = p_entry->interface_variables;+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = DisambiguateStorageBufferSrvUav(p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = SynchronizeDescriptorSets(p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }+ if (result == SPV_REFLECT_RESULT_SUCCESS) {+ result = ParseExecutionModes(&parser, p_module);+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);+ }++ // Destroy module if parse was not successful+ if (result != SPV_REFLECT_RESULT_SUCCESS) {+ spvReflectDestroyShaderModule(p_module);+ }++ DestroyParser(&parser);++ return result;+}++SpvReflectResult spvReflectCreateShaderModule(+ size_t size,+ const void* p_code,+ SpvReflectShaderModule* p_module+)+{+ return CreateShaderModule(0, size, p_code, p_module);+}++SpvReflectResult spvReflectCreateShaderModule2(+ uint32_t flags,+ size_t size,+ const void* p_code,+ SpvReflectShaderModule* p_module+)+{+ return CreateShaderModule(flags, size, p_code, p_module);+}++SpvReflectResult spvReflectGetShaderModule(+ size_t size,+ const void* p_code,+ SpvReflectShaderModule* p_module+)+{+ return spvReflectCreateShaderModule(size, p_code, p_module);+}++static void SafeFreeTypes(SpvReflectTypeDescription* p_type)+{+ if (IsNull(p_type)) {+ return;+ }++ if (IsNotNull(p_type->members)) {+ for (size_t i = 0; i < p_type->member_count; ++i) {+ SpvReflectTypeDescription* p_member = &p_type->members[i];+ SafeFreeTypes(p_member);+ }++ SafeFree(p_type->members);+ p_type->members = NULL;+ }+}++static void SafeFreeBlockVariables(SpvReflectBlockVariable* p_block)+{+ if (IsNull(p_block)) {+ return;+ }++ if (IsNotNull(p_block->members)) {+ for (size_t i = 0; i < p_block->member_count; ++i) {+ SpvReflectBlockVariable* p_member = &p_block->members[i];+ SafeFreeBlockVariables(p_member);+ }++ SafeFree(p_block->members);+ p_block->members = NULL;+ }+}++static void SafeFreeInterfaceVariable(SpvReflectInterfaceVariable* p_interface)+{+ if (IsNull(p_interface)) {+ return;+ }++ if (IsNotNull(p_interface->members)) {+ for (size_t i = 0; i < p_interface->member_count; ++i) {+ SpvReflectInterfaceVariable* p_member = &p_interface->members[i];+ SafeFreeInterfaceVariable(p_member);+ }++ SafeFree(p_interface->members);+ p_interface->members = NULL;+ }+}++void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module)+{+ if (IsNull(p_module->_internal)) {+ return;+ }++ SafeFree(p_module->source_source);++ // Descriptor set bindings+ for (size_t i = 0; i < p_module->descriptor_set_count; ++i) {+ SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[i];+ free(p_set->bindings);+ }++ // Descriptor binding blocks+ for (size_t i = 0; i < p_module->descriptor_binding_count; ++i) {+ SpvReflectDescriptorBinding* p_descriptor = &p_module->descriptor_bindings[i];+ SafeFreeBlockVariables(&p_descriptor->block);+ }+ SafeFree(p_module->descriptor_bindings);++ // Entry points+ for (size_t i = 0; i < p_module->entry_point_count; ++i) {+ SpvReflectEntryPoint* p_entry = &p_module->entry_points[i];+ for (size_t j = 0; j < p_entry->interface_variable_count; j++) {+ SafeFreeInterfaceVariable(&p_entry->interface_variables[j]);+ }+ for (uint32_t j = 0; j < p_entry->descriptor_set_count; ++j) {+ SafeFree(p_entry->descriptor_sets[j].bindings);+ }+ SafeFree(p_entry->descriptor_sets);+ SafeFree(p_entry->input_variables);+ SafeFree(p_entry->output_variables);+ SafeFree(p_entry->interface_variables);+ SafeFree(p_entry->used_uniforms);+ SafeFree(p_entry->used_push_constants);+ SafeFree(p_entry->execution_modes);+ }+ SafeFree(p_module->capabilities);+ SafeFree(p_module->entry_points);++ // Push constants+ for (size_t i = 0; i < p_module->push_constant_block_count; ++i) {+ SafeFreeBlockVariables(&p_module->push_constant_blocks[i]);+ }+ SafeFree(p_module->push_constant_blocks);++ // Type infos+ for (size_t i = 0; i < p_module->_internal->type_description_count; ++i) {+ SpvReflectTypeDescription* p_type = &p_module->_internal->type_descriptions[i];+ if (IsNotNull(p_type->members)) {+ SafeFreeTypes(p_type);+ }+ SafeFree(p_type->members);+ }+ SafeFree(p_module->_internal->type_descriptions);++ // Free SPIR-V code if there was a copy+ if ((p_module->_internal->module_flags & SPV_REFLECT_MODULE_FLAG_NO_COPY) == 0) {+ SafeFree(p_module->_internal->spirv_code);+ }+ // Free internal+ SafeFree(p_module->_internal);+}++uint32_t spvReflectGetCodeSize(const SpvReflectShaderModule* p_module)+{+ if (IsNull(p_module)) {+ return 0;+ }++ return (uint32_t)(p_module->_internal->spirv_size);+}++const uint32_t* spvReflectGetCode(const SpvReflectShaderModule* p_module)+{+ if (IsNull(p_module)) {+ return NULL;+ }++ return p_module->_internal->spirv_code;+}++const SpvReflectEntryPoint* spvReflectGetEntryPoint(+ const SpvReflectShaderModule* p_module,+ const char* entry_point+) {+ if (IsNull(p_module) || IsNull(entry_point)) {+ return NULL;+ }++ for (uint32_t i = 0; i < p_module->entry_point_count; ++i) {+ if (strcmp(p_module->entry_points[i].name, entry_point) == 0) {+ return &p_module->entry_points[i];+ }+ }+ return NULL;+}++SpvReflectResult spvReflectEnumerateDescriptorBindings(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectDescriptorBinding** pp_bindings+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ if (IsNotNull(pp_bindings)) {+ if (*p_count != p_module->descriptor_binding_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectDescriptorBinding* p_bindings = (SpvReflectDescriptorBinding*)&p_module->descriptor_bindings[index];+ pp_bindings[index] = p_bindings;+ }+ }+ else {+ *p_count = p_module->descriptor_binding_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumerateEntryPointDescriptorBindings(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectDescriptorBinding** pp_bindings+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ const SpvReflectEntryPoint* p_entry =+ spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }++ uint32_t count = 0;+ for (uint32_t i = 0; i < p_module->descriptor_binding_count; ++i) {+ bool found = SearchSortedUint32(+ p_entry->used_uniforms,+ p_entry->used_uniform_count,+ p_module->descriptor_bindings[i].spirv_id);+ if (found) {+ if (IsNotNull(pp_bindings)) {+ if (count >= *p_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }+ pp_bindings[count++] = (SpvReflectDescriptorBinding*)&p_module->descriptor_bindings[i];+ } else {+ ++count;+ }+ }+ }+ if (IsNotNull(pp_bindings)) {+ if (count != *p_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }+ } else {+ *p_count = count;+ }+ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumerateDescriptorSets(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectDescriptorSet** pp_sets+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ if (IsNotNull(pp_sets)) {+ if (*p_count != p_module->descriptor_set_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectDescriptorSet* p_set = (SpvReflectDescriptorSet*)&p_module->descriptor_sets[index];+ pp_sets[index] = p_set;+ }+ }+ else {+ *p_count = p_module->descriptor_set_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumerateEntryPointDescriptorSets(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectDescriptorSet** pp_sets+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ const SpvReflectEntryPoint* p_entry =+ spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }++ if (IsNotNull(pp_sets)) {+ if (*p_count != p_entry->descriptor_set_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectDescriptorSet* p_set = (SpvReflectDescriptorSet*)&p_entry->descriptor_sets[index];+ pp_sets[index] = p_set;+ }+ }+ else {+ *p_count = p_entry->descriptor_set_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumerateInterfaceVariables(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ if (IsNotNull(pp_variables)) {+ if (*p_count != p_module->interface_variable_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectInterfaceVariable* p_var = &p_module->interface_variables[index];+ pp_variables[index] = p_var;+ }+ }+ else {+ *p_count = p_module->interface_variable_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ const SpvReflectEntryPoint* p_entry =+ spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }++ if (IsNotNull(pp_variables)) {+ if (*p_count != p_entry->interface_variable_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectInterfaceVariable* p_var = &p_entry->interface_variables[index];+ pp_variables[index] = p_var;+ }+ }+ else {+ *p_count = p_entry->interface_variable_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumerateInputVariables(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ if (IsNotNull(pp_variables)) {+ if (*p_count != p_module->input_variable_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectInterfaceVariable* p_var = p_module->input_variables[index];+ pp_variables[index] = p_var;+ }+ }+ else {+ *p_count = p_module->input_variable_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumerateEntryPointInputVariables(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ const SpvReflectEntryPoint* p_entry =+ spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }++ if (IsNotNull(pp_variables)) {+ if (*p_count != p_entry->input_variable_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectInterfaceVariable* p_var = p_entry->input_variables[index];+ pp_variables[index] = p_var;+ }+ }+ else {+ *p_count = p_entry->input_variable_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumerateOutputVariables(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ if (IsNotNull(pp_variables)) {+ if (*p_count != p_module->output_variable_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectInterfaceVariable* p_var = p_module->output_variables[index];+ pp_variables[index] = p_var;+ }+ }+ else {+ *p_count = p_module->output_variable_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumerateEntryPointOutputVariables(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ const SpvReflectEntryPoint* p_entry =+ spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }++ if (IsNotNull(pp_variables)) {+ if (*p_count != p_entry->output_variable_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectInterfaceVariable* p_var = p_entry->output_variables[index];+ pp_variables[index] = p_var;+ }+ }+ else {+ *p_count = p_entry->output_variable_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectEnumeratePushConstantBlocks(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectBlockVariable** pp_blocks+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ if (pp_blocks != NULL) {+ if (*p_count != p_module->push_constant_block_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }++ for (uint32_t index = 0; index < *p_count; ++index) {+ SpvReflectBlockVariable* p_push_constant_blocks = (SpvReflectBlockVariable*)&p_module->push_constant_blocks[index];+ pp_blocks[index] = p_push_constant_blocks;+ }+ }+ else {+ *p_count = p_module->push_constant_block_count;+ }++ return SPV_REFLECT_RESULT_SUCCESS;+}+SpvReflectResult spvReflectEnumeratePushConstants(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectBlockVariable** pp_blocks+)+{+ return spvReflectEnumeratePushConstantBlocks(p_module, p_count, pp_blocks);+}++SpvReflectResult spvReflectEnumerateEntryPointPushConstantBlocks(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectBlockVariable** pp_blocks+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_count)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+++ const SpvReflectEntryPoint* p_entry =+ spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }++ uint32_t count = 0;+ for (uint32_t i = 0; i < p_module->push_constant_block_count; ++i) {+ bool found = SearchSortedUint32(p_entry->used_push_constants,+ p_entry->used_push_constant_count,+ p_module->push_constant_blocks[i].spirv_id);+ if (found) {+ if (IsNotNull(pp_blocks)) {+ if (count >= *p_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }+ pp_blocks[count++] = (SpvReflectBlockVariable*)&p_module->push_constant_blocks[i];+ } else {+ ++count;+ }+ }+ }+ if (IsNotNull(pp_blocks)) {+ if (count != *p_count) {+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;+ }+ } else {+ *p_count = count;+ }+ return SPV_REFLECT_RESULT_SUCCESS;+}++const SpvReflectDescriptorBinding* spvReflectGetDescriptorBinding(+ const SpvReflectShaderModule* p_module,+ uint32_t binding_number,+ uint32_t set_number,+ SpvReflectResult* p_result+)+{+ const SpvReflectDescriptorBinding* p_descriptor = NULL;+ if (IsNotNull(p_module)) {+ for (uint32_t index = 0; index < p_module->descriptor_binding_count; ++index) {+ const SpvReflectDescriptorBinding* p_potential = &p_module->descriptor_bindings[index];+ if ((p_potential->binding == binding_number) && (p_potential->set == set_number)) {+ p_descriptor = p_potential;+ break;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_descriptor)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_descriptor;+}++const SpvReflectDescriptorBinding* spvReflectGetEntryPointDescriptorBinding(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t binding_number,+ uint32_t set_number,+ SpvReflectResult* p_result+)+{+ const SpvReflectEntryPoint* p_entry =+ spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ const SpvReflectDescriptorBinding* p_descriptor = NULL;+ if (IsNotNull(p_module)) {+ for (uint32_t index = 0; index < p_module->descriptor_binding_count; ++index) {+ const SpvReflectDescriptorBinding* p_potential = &p_module->descriptor_bindings[index];+ bool found = SearchSortedUint32(+ p_entry->used_uniforms, + p_entry->used_uniform_count,+ p_potential->spirv_id);+ if ((p_potential->binding == binding_number) && (p_potential->set == set_number) && found) {+ p_descriptor = p_potential;+ break;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_descriptor)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_descriptor;+}++const SpvReflectDescriptorSet* spvReflectGetDescriptorSet(+ const SpvReflectShaderModule* p_module,+ uint32_t set_number,+ SpvReflectResult* p_result+)+{+ const SpvReflectDescriptorSet* p_set = NULL;+ if (IsNotNull(p_module)) {+ for (uint32_t index = 0; index < p_module->descriptor_set_count; ++index) {+ const SpvReflectDescriptorSet* p_potential = &p_module->descriptor_sets[index];+ if (p_potential->set == set_number) {+ p_set = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_set)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_set;+}++const SpvReflectDescriptorSet* spvReflectGetEntryPointDescriptorSet(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t set_number,+ SpvReflectResult* p_result)+{+ const SpvReflectDescriptorSet* p_set = NULL;+ if (IsNotNull(p_module)) {+ const SpvReflectEntryPoint* p_entry = spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ for (uint32_t index = 0; index < p_entry->descriptor_set_count; ++index) {+ const SpvReflectDescriptorSet* p_potential = &p_entry->descriptor_sets[index];+ if (p_potential->set == set_number) {+ p_set = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_set)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_set;+}+++const SpvReflectInterfaceVariable* spvReflectGetInputVariableByLocation(+ const SpvReflectShaderModule* p_module,+ uint32_t location,+ SpvReflectResult* p_result+)+{+ if (location == INVALID_VALUE) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ const SpvReflectInterfaceVariable* p_var = NULL;+ if (IsNotNull(p_module)) {+ for (uint32_t index = 0; index < p_module->input_variable_count; ++index) {+ const SpvReflectInterfaceVariable* p_potential = p_module->input_variables[index];+ if (p_potential->location == location) {+ p_var = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_var)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_var;+}+const SpvReflectInterfaceVariable* spvReflectGetInputVariable(+ const SpvReflectShaderModule* p_module,+ uint32_t location,+ SpvReflectResult* p_result+)+{+ return spvReflectGetInputVariableByLocation(p_module, location, p_result);+}++const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableByLocation(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t location,+ SpvReflectResult* p_result+)+{+ if (location == INVALID_VALUE) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }++ const SpvReflectInterfaceVariable* p_var = NULL;+ if (IsNotNull(p_module)) {+ const SpvReflectEntryPoint* p_entry =+ spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ for (uint32_t index = 0; index < p_entry->input_variable_count; ++index) {+ const SpvReflectInterfaceVariable* p_potential = p_entry->input_variables[index];+ if (p_potential->location == location) {+ p_var = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_var)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_var;+}++const SpvReflectInterfaceVariable* spvReflectGetInputVariableBySemantic(+ const SpvReflectShaderModule* p_module,+ const char* semantic,+ SpvReflectResult* p_result+)+{+ if (IsNull(semantic)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ return NULL;+ }+ if (semantic[0] == '\0') {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ const SpvReflectInterfaceVariable* p_var = NULL;+ if (IsNotNull(p_module)) {+ for (uint32_t index = 0; index < p_module->input_variable_count; ++index) {+ const SpvReflectInterfaceVariable* p_potential = p_module->input_variables[index];+ if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {+ p_var = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_var)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_var;+}++const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableBySemantic(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ const char* semantic,+ SpvReflectResult* p_result+)+{+ if (IsNull(semantic)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ return NULL;+ }+ if (semantic[0] == '\0') {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ const SpvReflectInterfaceVariable* p_var = NULL;+ if (IsNotNull(p_module)) {+ const SpvReflectEntryPoint* p_entry = spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ for (uint32_t index = 0; index < p_entry->input_variable_count; ++index) {+ const SpvReflectInterfaceVariable* p_potential = p_entry->input_variables[index];+ if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {+ p_var = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_var)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_var;+}++const SpvReflectInterfaceVariable* spvReflectGetOutputVariableByLocation(+ const SpvReflectShaderModule* p_module,+ uint32_t location,+ SpvReflectResult* p_result+)+{+ if (location == INVALID_VALUE) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ const SpvReflectInterfaceVariable* p_var = NULL;+ if (IsNotNull(p_module)) {+ for (uint32_t index = 0; index < p_module->output_variable_count; ++index) {+ const SpvReflectInterfaceVariable* p_potential = p_module->output_variables[index];+ if (p_potential->location == location) {+ p_var = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_var)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_var;+}+const SpvReflectInterfaceVariable* spvReflectGetOutputVariable(+ const SpvReflectShaderModule* p_module,+ uint32_t location,+ SpvReflectResult* p_result+)+{+ return spvReflectGetOutputVariableByLocation(p_module, location, p_result);+}++const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableByLocation(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t location,+ SpvReflectResult* p_result+)+{+ if (location == INVALID_VALUE) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }++ const SpvReflectInterfaceVariable* p_var = NULL;+ if (IsNotNull(p_module)) {+ const SpvReflectEntryPoint* p_entry = spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ for (uint32_t index = 0; index < p_entry->output_variable_count; ++index) {+ const SpvReflectInterfaceVariable* p_potential = p_entry->output_variables[index];+ if (p_potential->location == location) {+ p_var = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_var)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_var;+}++const SpvReflectInterfaceVariable* spvReflectGetOutputVariableBySemantic(+ const SpvReflectShaderModule* p_module,+ const char* semantic,+ SpvReflectResult* p_result+)+{+ if (IsNull(semantic)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ return NULL;+ }+ if (semantic[0] == '\0') {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ const SpvReflectInterfaceVariable* p_var = NULL;+ if (IsNotNull(p_module)) {+ for (uint32_t index = 0; index < p_module->output_variable_count; ++index) {+ const SpvReflectInterfaceVariable* p_potential = p_module->output_variables[index];+ if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {+ p_var = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_var)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_var;+}++const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableBySemantic(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ const char* semantic,+ SpvReflectResult* p_result)+{+ if (IsNull(semantic)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ return NULL;+ }+ if (semantic[0] == '\0') {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ const SpvReflectInterfaceVariable* p_var = NULL;+ if (IsNotNull(p_module)) {+ const SpvReflectEntryPoint* p_entry = spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ for (uint32_t index = 0; index < p_entry->output_variable_count; ++index) {+ const SpvReflectInterfaceVariable* p_potential = p_entry->output_variables[index];+ if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {+ p_var = p_potential;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_var)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_var;+}++const SpvReflectBlockVariable* spvReflectGetPushConstantBlock(+ const SpvReflectShaderModule* p_module,+ uint32_t index,+ SpvReflectResult* p_result+)+{+ const SpvReflectBlockVariable* p_push_constant = NULL;+ if (IsNotNull(p_module)) {+ if (index < p_module->push_constant_block_count) {+ p_push_constant = &p_module->push_constant_blocks[index];+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_push_constant)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_push_constant;+}+const SpvReflectBlockVariable* spvReflectGetPushConstant(+ const SpvReflectShaderModule* p_module,+ uint32_t index,+ SpvReflectResult* p_result+)+{+ return spvReflectGetPushConstantBlock(p_module, index, p_result);+}++const SpvReflectBlockVariable* spvReflectGetEntryPointPushConstantBlock(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ SpvReflectResult* p_result)+{+ const SpvReflectBlockVariable* p_push_constant = NULL;+ if (IsNotNull(p_module)) {+ const SpvReflectEntryPoint* p_entry =+ spvReflectGetEntryPoint(p_module, entry_point);+ if (IsNull(p_entry)) {+ if (IsNotNull(p_result)) {+ *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+ }+ return NULL;+ }+ for (uint32_t i = 0; i < p_module->push_constant_block_count; ++i) {+ bool found = SearchSortedUint32(+ p_entry->used_push_constants,+ p_entry->used_push_constant_count,+ p_module->push_constant_blocks[i].spirv_id);+ if (found) {+ p_push_constant = &p_module->push_constant_blocks[i];+ break;+ }+ }+ }+ if (IsNotNull(p_result)) {+ *p_result = IsNotNull(p_push_constant)+ ? SPV_REFLECT_RESULT_SUCCESS+ : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER+ : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);+ }+ return p_push_constant;+}++SpvReflectResult spvReflectChangeDescriptorBindingNumbers(+ SpvReflectShaderModule* p_module,+ const SpvReflectDescriptorBinding* p_binding,+ uint32_t new_binding_number,+ uint32_t new_set_binding+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_binding)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }++ SpvReflectDescriptorBinding* p_target_descriptor = NULL;+ for (uint32_t index = 0; index < p_module->descriptor_binding_count; ++index) {+ if(&p_module->descriptor_bindings[index] == p_binding) {+ p_target_descriptor = &p_module->descriptor_bindings[index];+ break;+ }+ }++ if (IsNotNull(p_target_descriptor)) {+ if (p_target_descriptor->word_offset.binding > (p_module->_internal->spirv_word_count - 1)) {+ return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;+ }+ // Binding number+ if (new_binding_number != (uint32_t)SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE) {+ uint32_t* p_code = p_module->_internal->spirv_code + p_target_descriptor->word_offset.binding;+ *p_code = new_binding_number;+ p_target_descriptor->binding = new_binding_number;+ }+ // Set number+ if (new_set_binding != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {+ uint32_t* p_code = p_module->_internal->spirv_code + p_target_descriptor->word_offset.set;+ *p_code = new_set_binding;+ p_target_descriptor->set = new_set_binding;+ }+ }++ SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;+ if (new_set_binding != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {+ result = SynchronizeDescriptorSets(p_module);+ }+ return result;+}+SpvReflectResult spvReflectChangeDescriptorBindingNumber(+ SpvReflectShaderModule* p_module,+ const SpvReflectDescriptorBinding* p_descriptor_binding,+ uint32_t new_binding_number,+ uint32_t optional_new_set_number+)+{+ return spvReflectChangeDescriptorBindingNumbers(+ p_module,p_descriptor_binding, + new_binding_number, + optional_new_set_number);+}++SpvReflectResult spvReflectChangeDescriptorSetNumber(+ SpvReflectShaderModule* p_module,+ const SpvReflectDescriptorSet* p_set,+ uint32_t new_set_number+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_set)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ SpvReflectDescriptorSet* p_target_set = NULL;+ for (uint32_t index = 0; index < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++index) {+ // The descriptor sets for specific entry points might not be in this set,+ // so just match on set index.+ if (p_module->descriptor_sets[index].set == p_set->set) {+ p_target_set = (SpvReflectDescriptorSet*)p_set;+ break;+ }+ }++ SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;+ if (IsNotNull(p_target_set) && new_set_number != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {+ for (uint32_t index = 0; index < p_target_set->binding_count; ++index) {+ SpvReflectDescriptorBinding* p_descriptor = p_target_set->bindings[index];+ if (p_descriptor->word_offset.set > (p_module->_internal->spirv_word_count - 1)) {+ return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;+ }++ uint32_t* p_code = p_module->_internal->spirv_code + p_descriptor->word_offset.set;+ *p_code = new_set_number;+ p_descriptor->set = new_set_number;+ }++ result = SynchronizeDescriptorSets(p_module);+ }++ return result;+}++static SpvReflectResult ChangeVariableLocation(+ SpvReflectShaderModule* p_module,+ SpvReflectInterfaceVariable* p_variable,+ uint32_t new_location+)+{+ if (p_variable->word_offset.location > (p_module->_internal->spirv_word_count - 1)) {+ return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;+ }+ uint32_t* p_code = p_module->_internal->spirv_code + p_variable->word_offset.location;+ *p_code = new_location;+ p_variable->location = new_location;+ return SPV_REFLECT_RESULT_SUCCESS;+}++SpvReflectResult spvReflectChangeInputVariableLocation(+ SpvReflectShaderModule* p_module,+ const SpvReflectInterfaceVariable* p_input_variable,+ uint32_t new_location+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_input_variable)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ for (uint32_t index = 0; index < p_module->input_variable_count; ++index) {+ if(p_module->input_variables[index] == p_input_variable) {+ return ChangeVariableLocation(p_module, p_module->input_variables[index], new_location);+ }+ }+ return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+}++SpvReflectResult spvReflectChangeOutputVariableLocation(+ SpvReflectShaderModule* p_module,+ const SpvReflectInterfaceVariable* p_output_variable,+ uint32_t new_location+)+{+ if (IsNull(p_module)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ if (IsNull(p_output_variable)) {+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;+ }+ for (uint32_t index = 0; index < p_module->output_variable_count; ++index) {+ if(p_module->output_variables[index] == p_output_variable) {+ return ChangeVariableLocation(p_module, p_module->output_variables[index], new_location);+ }+ }+ return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;+}++const char* spvReflectSourceLanguage(SpvSourceLanguage source_lang)+{+ switch (source_lang) {+ case SpvSourceLanguageUnknown : return "Unknown";+ case SpvSourceLanguageESSL : return "ESSL";+ case SpvSourceLanguageGLSL : return "GLSL";+ case SpvSourceLanguageOpenCL_C : return "OpenCL_C";+ case SpvSourceLanguageOpenCL_CPP : return "OpenCL_CPP";+ case SpvSourceLanguageHLSL : return "HLSL";+ case SpvSourceLanguageCPP_for_OpenCL : return "CPP_for_OpenCL";+ case SpvSourceLanguageSYCL : return "SYCL";+ case SpvSourceLanguageMax:+ break;+ }+ return "";+}++const char* spvReflectBlockVariableTypeName(+ const SpvReflectBlockVariable* p_var+)+{+ if (p_var == NULL) {+ return NULL;+ }+ return p_var->type_description->type_name;+}
+ cbits/spirv_reflect.h view
@@ -0,0 +1,2292 @@+/*+ Copyright 2017-2022 Google Inc.++ Licensed under the Apache License, Version 2.0 (the "License");+ you may not use this file except in compliance with the License.+ You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++ Unless required by applicable law or agreed to in writing, software+ distributed under the License is distributed on an "AS IS" BASIS,+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ See the License for the specific language governing permissions and+ limitations under the License.+*/++/*++VERSION HISTORY++ 1.0 (2018-03-27) Initial public release++*/++/*!++ @file spirv_reflect.h++*/+#ifndef SPIRV_REFLECT_H+#define SPIRV_REFLECT_H++#if defined(SPIRV_REFLECT_USE_SYSTEM_SPIRV_H)+#include <spirv/unified1/spirv.h>+#else+#include "./include/spirv/unified1/spirv.h"+#endif+++#include <stdint.h>+#include <string.h>++#ifdef _MSC_VER+ #define SPV_REFLECT_DEPRECATED(msg_str) __declspec(deprecated("This symbol is deprecated. Details: " msg_str))+#elif defined(__clang__)+ #define SPV_REFLECT_DEPRECATED(msg_str) __attribute__((deprecated(msg_str)))+#elif defined(__GNUC__)+ #if GCC_VERSION >= 40500+ #define SPV_REFLECT_DEPRECATED(msg_str) __attribute__((deprecated(msg_str)))+ #else+ #define SPV_REFLECT_DEPRECATED(msg_str) __attribute__((deprecated))+ #endif+#else+ #define SPV_REFLECT_DEPRECATED(msg_str)+#endif++/*! @enum SpvReflectResult++*/+typedef enum SpvReflectResult {+ SPV_REFLECT_RESULT_SUCCESS,+ SPV_REFLECT_RESULT_NOT_READY,+ SPV_REFLECT_RESULT_ERROR_PARSE_FAILED,+ SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED,+ SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED,+ SPV_REFLECT_RESULT_ERROR_NULL_POINTER,+ SPV_REFLECT_RESULT_ERROR_INTERNAL_ERROR,+ SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH,+ SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND,+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_CODE_SIZE,+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_MAGIC_NUMBER,+ SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_EOF,+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE,+ SPV_REFLECT_RESULT_ERROR_SPIRV_SET_NUMBER_OVERFLOW,+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_STORAGE_CLASS,+ SPV_REFLECT_RESULT_ERROR_SPIRV_RECURSION,+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_INSTRUCTION,+ SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA,+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE,+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT,+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE,+} SpvReflectResult;++/*! @enum SpvReflectModuleFlagBits++SPV_REFLECT_MODULE_FLAG_NO_COPY - Disables copying of SPIR-V code + when a SPIRV-Reflect shader module is created. It is the + responsibility of the calling program to ensure that the pointer+ remains valid and the memory it's pointing to is not freed while+ SPIRV-Reflect operations are taking place. Freeing the backing + memory will cause undefined behavior or most likely a crash.+ This is flag is intended for cases where the memory overhead of+ storing the copied SPIR-V is undesirable.++*/+typedef enum SpvReflectModuleFlagBits {+ SPV_REFLECT_MODULE_FLAG_NONE = 0x00000000,+ SPV_REFLECT_MODULE_FLAG_NO_COPY = 0x00000001,+} SpvReflectModuleFlagBits;++typedef uint32_t SpvReflectModuleFlags;++/*! @enum SpvReflectTypeFlagBits++*/+typedef enum SpvReflectTypeFlagBits {+ SPV_REFLECT_TYPE_FLAG_UNDEFINED = 0x00000000,+ SPV_REFLECT_TYPE_FLAG_VOID = 0x00000001,+ SPV_REFLECT_TYPE_FLAG_BOOL = 0x00000002,+ SPV_REFLECT_TYPE_FLAG_INT = 0x00000004,+ SPV_REFLECT_TYPE_FLAG_FLOAT = 0x00000008,+ SPV_REFLECT_TYPE_FLAG_VECTOR = 0x00000100,+ SPV_REFLECT_TYPE_FLAG_MATRIX = 0x00000200,+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE = 0x00010000,+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER = 0x00020000,+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE = 0x00040000,+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK = 0x00080000,+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE = 0x00100000,+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK = 0x00FF0000,+ SPV_REFLECT_TYPE_FLAG_STRUCT = 0x10000000,+ SPV_REFLECT_TYPE_FLAG_ARRAY = 0x20000000,+} SpvReflectTypeFlagBits;++typedef uint32_t SpvReflectTypeFlags;++/*! @enum SpvReflectDecorationBits++NOTE: HLSL row_major and column_major decorations are reversed+ in SPIR-V. Meaning that matrices declrations with row_major+ will get reflected as column_major and vice versa. The+ row and column decorations get appied during the compilation.+ SPIRV-Reflect reads the data as is and does not make any+ attempt to correct it to match what's in the source.++*/+typedef enum SpvReflectDecorationFlagBits {+ SPV_REFLECT_DECORATION_NONE = 0x00000000,+ SPV_REFLECT_DECORATION_BLOCK = 0x00000001,+ SPV_REFLECT_DECORATION_BUFFER_BLOCK = 0x00000002,+ SPV_REFLECT_DECORATION_ROW_MAJOR = 0x00000004,+ SPV_REFLECT_DECORATION_COLUMN_MAJOR = 0x00000008,+ SPV_REFLECT_DECORATION_BUILT_IN = 0x00000010,+ SPV_REFLECT_DECORATION_NOPERSPECTIVE = 0x00000020,+ SPV_REFLECT_DECORATION_FLAT = 0x00000040,+ SPV_REFLECT_DECORATION_NON_WRITABLE = 0x00000080,+ SPV_REFLECT_DECORATION_RELAXED_PRECISION = 0x00000100,+ SPV_REFLECT_DECORATION_NON_READABLE = 0x00000200,+} SpvReflectDecorationFlagBits;++typedef uint32_t SpvReflectDecorationFlags;++/*! @enum SpvReflectResourceType++*/+typedef enum SpvReflectResourceType {+ SPV_REFLECT_RESOURCE_FLAG_UNDEFINED = 0x00000000,+ SPV_REFLECT_RESOURCE_FLAG_SAMPLER = 0x00000001,+ SPV_REFLECT_RESOURCE_FLAG_CBV = 0x00000002,+ SPV_REFLECT_RESOURCE_FLAG_SRV = 0x00000004,+ SPV_REFLECT_RESOURCE_FLAG_UAV = 0x00000008,+} SpvReflectResourceType;++/*! @enum SpvReflectFormat++*/+typedef enum SpvReflectFormat {+ SPV_REFLECT_FORMAT_UNDEFINED = 0, // = VK_FORMAT_UNDEFINED+ SPV_REFLECT_FORMAT_R32_UINT = 98, // = VK_FORMAT_R32_UINT+ SPV_REFLECT_FORMAT_R32_SINT = 99, // = VK_FORMAT_R32_SINT+ SPV_REFLECT_FORMAT_R32_SFLOAT = 100, // = VK_FORMAT_R32_SFLOAT+ SPV_REFLECT_FORMAT_R32G32_UINT = 101, // = VK_FORMAT_R32G32_UINT+ SPV_REFLECT_FORMAT_R32G32_SINT = 102, // = VK_FORMAT_R32G32_SINT+ SPV_REFLECT_FORMAT_R32G32_SFLOAT = 103, // = VK_FORMAT_R32G32_SFLOAT+ SPV_REFLECT_FORMAT_R32G32B32_UINT = 104, // = VK_FORMAT_R32G32B32_UINT+ SPV_REFLECT_FORMAT_R32G32B32_SINT = 105, // = VK_FORMAT_R32G32B32_SINT+ SPV_REFLECT_FORMAT_R32G32B32_SFLOAT = 106, // = VK_FORMAT_R32G32B32_SFLOAT+ SPV_REFLECT_FORMAT_R32G32B32A32_UINT = 107, // = VK_FORMAT_R32G32B32A32_UINT+ SPV_REFLECT_FORMAT_R32G32B32A32_SINT = 108, // = VK_FORMAT_R32G32B32A32_SINT+ SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT = 109, // = VK_FORMAT_R32G32B32A32_SFLOAT+ SPV_REFLECT_FORMAT_R64_UINT = 110, // = VK_FORMAT_R64_UINT+ SPV_REFLECT_FORMAT_R64_SINT = 111, // = VK_FORMAT_R64_SINT+ SPV_REFLECT_FORMAT_R64_SFLOAT = 112, // = VK_FORMAT_R64_SFLOAT+ SPV_REFLECT_FORMAT_R64G64_UINT = 113, // = VK_FORMAT_R64G64_UINT+ SPV_REFLECT_FORMAT_R64G64_SINT = 114, // = VK_FORMAT_R64G64_SINT+ SPV_REFLECT_FORMAT_R64G64_SFLOAT = 115, // = VK_FORMAT_R64G64_SFLOAT+ SPV_REFLECT_FORMAT_R64G64B64_UINT = 116, // = VK_FORMAT_R64G64B64_UINT+ SPV_REFLECT_FORMAT_R64G64B64_SINT = 117, // = VK_FORMAT_R64G64B64_SINT+ SPV_REFLECT_FORMAT_R64G64B64_SFLOAT = 118, // = VK_FORMAT_R64G64B64_SFLOAT+ SPV_REFLECT_FORMAT_R64G64B64A64_UINT = 119, // = VK_FORMAT_R64G64B64A64_UINT+ SPV_REFLECT_FORMAT_R64G64B64A64_SINT = 120, // = VK_FORMAT_R64G64B64A64_SINT+ SPV_REFLECT_FORMAT_R64G64B64A64_SFLOAT = 121, // = VK_FORMAT_R64G64B64A64_SFLOAT+} SpvReflectFormat;++/*! @enum SpvReflectVariableFlagBits++*/+enum SpvReflectVariableFlagBits{+ SPV_REFLECT_VARIABLE_FLAGS_NONE = 0x00000000,+ SPV_REFLECT_VARIABLE_FLAGS_UNUSED = 0x00000001,+};++typedef uint32_t SpvReflectVariableFlags;++/*! @enum SpvReflectDescriptorType++*/+typedef enum SpvReflectDescriptorType {+ SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER = 0, // = VK_DESCRIPTOR_TYPE_SAMPLER+ SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, // = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER+ SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, // = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE+ SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, // = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE+ SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, // = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER+ SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, // = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER+ SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER+ SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER+ SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC+ SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC+ SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, // = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT+ SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000 // = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR+} SpvReflectDescriptorType;++/*! @enum SpvReflectShaderStageFlagBits++*/+typedef enum SpvReflectShaderStageFlagBits {+ SPV_REFLECT_SHADER_STAGE_VERTEX_BIT = 0x00000001, // = VK_SHADER_STAGE_VERTEX_BIT+ SPV_REFLECT_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002, // = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT+ SPV_REFLECT_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004, // = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT+ SPV_REFLECT_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, // = VK_SHADER_STAGE_GEOMETRY_BIT+ SPV_REFLECT_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, // = VK_SHADER_STAGE_FRAGMENT_BIT+ SPV_REFLECT_SHADER_STAGE_COMPUTE_BIT = 0x00000020, // = VK_SHADER_STAGE_COMPUTE_BIT+ SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV = 0x00000040, // = VK_SHADER_STAGE_TASK_BIT_NV+ SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV = 0x00000080, // = VK_SHADER_STAGE_MESH_BIT_NV+ SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, // = VK_SHADER_STAGE_RAYGEN_BIT_KHR+ SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, // = VK_SHADER_STAGE_ANY_HIT_BIT_KHR+ SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, // = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR+ SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, // = VK_SHADER_STAGE_MISS_BIT_KHR+ SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, // = VK_SHADER_STAGE_INTERSECTION_BIT_KHR+ SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, // = VK_SHADER_STAGE_CALLABLE_BIT_KHR++} SpvReflectShaderStageFlagBits;++/*! @enum SpvReflectGenerator++*/+typedef enum SpvReflectGenerator {+ SPV_REFLECT_GENERATOR_KHRONOS_LLVM_SPIRV_TRANSLATOR = 6,+ SPV_REFLECT_GENERATOR_KHRONOS_SPIRV_TOOLS_ASSEMBLER = 7,+ SPV_REFLECT_GENERATOR_KHRONOS_GLSLANG_REFERENCE_FRONT_END = 8,+ SPV_REFLECT_GENERATOR_GOOGLE_SHADERC_OVER_GLSLANG = 13,+ SPV_REFLECT_GENERATOR_GOOGLE_SPIREGG = 14,+ SPV_REFLECT_GENERATOR_GOOGLE_RSPIRV = 15,+ SPV_REFLECT_GENERATOR_X_LEGEND_MESA_MESAIR_SPIRV_TRANSLATOR = 16,+ SPV_REFLECT_GENERATOR_KHRONOS_SPIRV_TOOLS_LINKER = 17,+ SPV_REFLECT_GENERATOR_WINE_VKD3D_SHADER_COMPILER = 18,+ SPV_REFLECT_GENERATOR_CLAY_CLAY_SHADER_COMPILER = 19,+} SpvReflectGenerator;++enum {+ SPV_REFLECT_MAX_ARRAY_DIMS = 32,+ SPV_REFLECT_MAX_DESCRIPTOR_SETS = 64,+};++enum {+ SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE = ~0,+ SPV_REFLECT_SET_NUMBER_DONT_CHANGE = ~0+};++typedef struct SpvReflectNumericTraits {+ struct Scalar {+ uint32_t width;+ uint32_t signedness;+ } scalar;++ struct Vector {+ uint32_t component_count;+ } vector;++ struct Matrix {+ uint32_t column_count;+ uint32_t row_count;+ uint32_t stride; // Measured in bytes+ } matrix;+} SpvReflectNumericTraits;++typedef struct SpvReflectImageTraits {+ SpvDim dim;+ uint32_t depth;+ uint32_t arrayed;+ uint32_t ms; // 0: single-sampled; 1: multisampled+ uint32_t sampled;+ SpvImageFormat image_format;+} SpvReflectImageTraits;++typedef struct SpvReflectArrayTraits {+ uint32_t dims_count;+ // Each entry is: 0xFFFFFFFF for a specialization constant dimension,+ // 0 for a runtime array dimension, and the array length otherwise.+ uint32_t dims[SPV_REFLECT_MAX_ARRAY_DIMS];+ // Stores Ids for dimensions that are specialization constants+ uint32_t spec_constant_op_ids[SPV_REFLECT_MAX_ARRAY_DIMS];+ uint32_t stride; // Measured in bytes+} SpvReflectArrayTraits;++typedef struct SpvReflectBindingArrayTraits {+ uint32_t dims_count;+ uint32_t dims[SPV_REFLECT_MAX_ARRAY_DIMS];+} SpvReflectBindingArrayTraits;++/*! @struct SpvReflectTypeDescription++*/+typedef struct SpvReflectTypeDescription {+ uint32_t id;+ SpvOp op;+ const char* type_name;+ const char* struct_member_name;+ SpvStorageClass storage_class;+ SpvReflectTypeFlags type_flags;+ SpvReflectDecorationFlags decoration_flags;++ struct Traits {+ SpvReflectNumericTraits numeric;+ SpvReflectImageTraits image;+ SpvReflectArrayTraits array;+ } traits;++ uint32_t member_count;+ struct SpvReflectTypeDescription* members;+} SpvReflectTypeDescription;+++/*! @struct SpvReflectInterfaceVariable++*/+typedef struct SpvReflectInterfaceVariable {+ uint32_t spirv_id;+ const char* name;+ uint32_t location;+ SpvStorageClass storage_class;+ const char* semantic;+ SpvReflectDecorationFlags decoration_flags;+ SpvBuiltIn built_in;+ SpvReflectNumericTraits numeric;+ SpvReflectArrayTraits array;++ uint32_t member_count;+ struct SpvReflectInterfaceVariable* members;++ SpvReflectFormat format;++ // NOTE: SPIR-V shares type references for variables+ // that have the same underlying type. This means+ // that the same type name will appear for multiple+ // variables.+ SpvReflectTypeDescription* type_description;++ struct {+ uint32_t location;+ } word_offset;+} SpvReflectInterfaceVariable;++/*! @struct SpvReflectBlockVariable++*/+typedef struct SpvReflectBlockVariable {+ uint32_t spirv_id;+ const char* name;+ uint32_t offset; // Measured in bytes+ uint32_t absolute_offset; // Measured in bytes+ uint32_t size; // Measured in bytes+ uint32_t padded_size; // Measured in bytes+ SpvReflectDecorationFlags decoration_flags;+ SpvReflectNumericTraits numeric;+ SpvReflectArrayTraits array;+ SpvReflectVariableFlags flags;++ uint32_t member_count;+ struct SpvReflectBlockVariable* members;++ SpvReflectTypeDescription* type_description;+} SpvReflectBlockVariable;++/*! @struct SpvReflectDescriptorBinding++*/+typedef struct SpvReflectDescriptorBinding {+ uint32_t spirv_id;+ const char* name;+ uint32_t binding;+ uint32_t input_attachment_index;+ uint32_t set;+ SpvReflectDescriptorType descriptor_type;+ SpvReflectResourceType resource_type;+ SpvReflectImageTraits image;+ SpvReflectBlockVariable block;+ SpvReflectBindingArrayTraits array;+ uint32_t count;+ uint32_t accessed;+ uint32_t uav_counter_id;+ struct SpvReflectDescriptorBinding* uav_counter_binding;++ SpvReflectTypeDescription* type_description;++ struct {+ uint32_t binding;+ uint32_t set;+ } word_offset;++ SpvReflectDecorationFlags decoration_flags;+} SpvReflectDescriptorBinding;++/*! @struct SpvReflectDescriptorSet++*/+typedef struct SpvReflectDescriptorSet {+ uint32_t set;+ uint32_t binding_count;+ SpvReflectDescriptorBinding** bindings;+} SpvReflectDescriptorSet;++/*! @struct SpvReflectEntryPoint++ */+typedef struct SpvReflectEntryPoint {+ const char* name;+ uint32_t id;++ SpvExecutionModel spirv_execution_model;+ SpvReflectShaderStageFlagBits shader_stage;++ uint32_t input_variable_count; + SpvReflectInterfaceVariable** input_variables; + uint32_t output_variable_count; + SpvReflectInterfaceVariable** output_variables; + uint32_t interface_variable_count;+ SpvReflectInterfaceVariable* interface_variables;++ uint32_t descriptor_set_count;+ SpvReflectDescriptorSet* descriptor_sets;++ uint32_t used_uniform_count;+ uint32_t* used_uniforms;+ uint32_t used_push_constant_count;+ uint32_t* used_push_constants;++ uint32_t execution_mode_count;+ SpvExecutionMode* execution_modes;++ struct LocalSize {+ uint32_t x;+ uint32_t y;+ uint32_t z;+ } local_size;+ uint32_t invocations; // valid for geometry+ uint32_t output_vertices; // valid for geometry, tesselation+} SpvReflectEntryPoint;++/*! @struct SpvReflectCapability++*/+typedef struct SpvReflectCapability {+ SpvCapability value;+ uint32_t word_offset;+} SpvReflectCapability;++/*! @struct SpvReflectShaderModule++*/+typedef struct SpvReflectShaderModule {+ SpvReflectGenerator generator;+ const char* entry_point_name;+ uint32_t entry_point_id;+ uint32_t entry_point_count;+ SpvReflectEntryPoint* entry_points;+ SpvSourceLanguage source_language;+ uint32_t source_language_version;+ const char* source_file;+ const char* source_source;+ uint32_t capability_count;+ SpvReflectCapability* capabilities;+ SpvExecutionModel spirv_execution_model; // Uses value(s) from first entry point+ SpvReflectShaderStageFlagBits shader_stage; // Uses value(s) from first entry point+ uint32_t descriptor_binding_count; // Uses value(s) from first entry point+ SpvReflectDescriptorBinding* descriptor_bindings; // Uses value(s) from first entry point+ uint32_t descriptor_set_count; // Uses value(s) from first entry point+ SpvReflectDescriptorSet descriptor_sets[SPV_REFLECT_MAX_DESCRIPTOR_SETS]; // Uses value(s) from first entry point+ uint32_t input_variable_count; // Uses value(s) from first entry point+ SpvReflectInterfaceVariable** input_variables; // Uses value(s) from first entry point+ uint32_t output_variable_count; // Uses value(s) from first entry point+ SpvReflectInterfaceVariable** output_variables; // Uses value(s) from first entry point+ uint32_t interface_variable_count; // Uses value(s) from first entry point+ SpvReflectInterfaceVariable* interface_variables; // Uses value(s) from first entry point+ uint32_t push_constant_block_count; // Uses value(s) from first entry point+ SpvReflectBlockVariable* push_constant_blocks; // Uses value(s) from first entry point++ struct Internal {+ SpvReflectModuleFlags module_flags;+ size_t spirv_size;+ uint32_t* spirv_code;+ uint32_t spirv_word_count;++ size_t type_description_count;+ SpvReflectTypeDescription* type_descriptions;+ } * _internal;++} SpvReflectShaderModule;++#if defined(__cplusplus)+extern "C" {+#endif++/*! @fn spvReflectCreateShaderModule++ @param size Size in bytes of SPIR-V code.+ @param p_code Pointer to SPIR-V code.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @return SPV_REFLECT_RESULT_SUCCESS on success.++*/+SpvReflectResult spvReflectCreateShaderModule(+ size_t size,+ const void* p_code,+ SpvReflectShaderModule* p_module+);++/*! @fn spvReflectCreateShaderModule2++ @param flags Flags for module creations.+ @param size Size in bytes of SPIR-V code.+ @param p_code Pointer to SPIR-V code.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @return SPV_REFLECT_RESULT_SUCCESS on success.++*/+SpvReflectResult spvReflectCreateShaderModule2(+ SpvReflectModuleFlags flags,+ size_t size,+ const void* p_code,+ SpvReflectShaderModule* p_module+);++SPV_REFLECT_DEPRECATED("renamed to spvReflectCreateShaderModule")+SpvReflectResult spvReflectGetShaderModule(+ size_t size,+ const void* p_code,+ SpvReflectShaderModule* p_module+);+++/*! @fn spvReflectDestroyShaderModule++ @param p_module Pointer to an instance of SpvReflectShaderModule.++*/+void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module);+++/*! @fn spvReflectGetCodeSize++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @return Returns the size of the SPIR-V in bytes++*/+uint32_t spvReflectGetCodeSize(const SpvReflectShaderModule* p_module);+++/*! @fn spvReflectGetCode++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @return Returns a const pointer to the compiled SPIR-V bytecode.++*/+const uint32_t* spvReflectGetCode(const SpvReflectShaderModule* p_module);++/*! @fn spvReflectGetEntryPoint++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point Name of the requested entry point.+ @return Returns a const pointer to the requested entry point,+ or NULL if it's not found.+*/+const SpvReflectEntryPoint* spvReflectGetEntryPoint(+ const SpvReflectShaderModule* p_module,+ const char* entry_point+);++/*! @fn spvReflectEnumerateDescriptorBindings++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_count If pp_bindings is NULL, the module's descriptor binding+ count (across all descriptor sets) will be stored here.+ If pp_bindings is not NULL, *p_count must contain the+ module's descriptor binding count.+ @param pp_bindings If NULL, the module's total descriptor binding count+ will be written to *p_count.+ If non-NULL, pp_bindings must point to an array with+ *p_count entries, where pointers to the module's+ descriptor bindings will be written. The caller must not+ free the binding pointers written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateDescriptorBindings(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectDescriptorBinding** pp_bindings+);++/*! @fn spvReflectEnumerateEntryPointDescriptorBindings+ @brief Creates a listing of all descriptor bindings that are used in the+ static call tree of the given entry point.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The name of the entry point to get the descriptor bindings for.+ @param p_count If pp_bindings is NULL, the entry point's descriptor binding+ count (across all descriptor sets) will be stored here.+ If pp_bindings is not NULL, *p_count must contain the+ entry points's descriptor binding count.+ @param pp_bindings If NULL, the entry point's total descriptor binding count+ will be written to *p_count.+ If non-NULL, pp_bindings must point to an array with+ *p_count entries, where pointers to the entry point's+ descriptor bindings will be written. The caller must not+ free the binding pointers written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateEntryPointDescriptorBindings(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectDescriptorBinding** pp_bindings+);++/*! @fn spvReflectEnumerateDescriptorSets++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_count If pp_sets is NULL, the module's descriptor set+ count will be stored here.+ If pp_sets is not NULL, *p_count must contain the+ module's descriptor set count.+ @param pp_sets If NULL, the module's total descriptor set count+ will be written to *p_count.+ If non-NULL, pp_sets must point to an array with+ *p_count entries, where pointers to the module's+ descriptor sets will be written. The caller must not+ free the descriptor set pointers written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateDescriptorSets(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectDescriptorSet** pp_sets+);++/*! @fn spvReflectEnumerateEntryPointDescriptorSets+ @brief Creates a listing of all descriptor sets and their bindings that are+ used in the static call tree of a given entry point.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The name of the entry point to get the descriptor bindings for.+ @param p_count If pp_sets is NULL, the module's descriptor set+ count will be stored here.+ If pp_sets is not NULL, *p_count must contain the+ module's descriptor set count.+ @param pp_sets If NULL, the module's total descriptor set count+ will be written to *p_count.+ If non-NULL, pp_sets must point to an array with+ *p_count entries, where pointers to the module's+ descriptor sets will be written. The caller must not+ free the descriptor set pointers written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateEntryPointDescriptorSets(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectDescriptorSet** pp_sets+);+++/*! @fn spvReflectEnumerateInterfaceVariables+ @brief If the module contains multiple entry points, this will only get+ the interface variables for the first one.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_count If pp_variables is NULL, the module's interface variable+ count will be stored here.+ If pp_variables is not NULL, *p_count must contain+ the module's interface variable count.+ @param pp_variables If NULL, the module's interface variable count will be+ written to *p_count.+ If non-NULL, pp_variables must point to an array with+ *p_count entries, where pointers to the module's+ interface variables will be written. The caller must not+ free the interface variables written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateInterfaceVariables(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+);++/*! @fn spvReflectEnumerateEntryPointInterfaceVariables+ @brief Enumerate the interface variables for a given entry point.+ @param entry_point The name of the entry point to get the interface variables for.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_count If pp_variables is NULL, the entry point's interface variable+ count will be stored here.+ If pp_variables is not NULL, *p_count must contain+ the entry point's interface variable count.+ @param pp_variables If NULL, the entry point's interface variable count will be+ written to *p_count.+ If non-NULL, pp_variables must point to an array with+ *p_count entries, where pointers to the entry point's+ interface variables will be written. The caller must not+ free the interface variables written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+);+++/*! @fn spvReflectEnumerateInputVariables+ @brief If the module contains multiple entry points, this will only get+ the input variables for the first one.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_count If pp_variables is NULL, the module's input variable+ count will be stored here.+ If pp_variables is not NULL, *p_count must contain+ the module's input variable count.+ @param pp_variables If NULL, the module's input variable count will be+ written to *p_count.+ If non-NULL, pp_variables must point to an array with+ *p_count entries, where pointers to the module's+ input variables will be written. The caller must not+ free the interface variables written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateInputVariables(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+);++/*! @fn spvReflectEnumerateEntryPointInputVariables+ @brief Enumerate the input variables for a given entry point.+ @param entry_point The name of the entry point to get the input variables for.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_count If pp_variables is NULL, the entry point's input variable+ count will be stored here.+ If pp_variables is not NULL, *p_count must contain+ the entry point's input variable count.+ @param pp_variables If NULL, the entry point's input variable count will be+ written to *p_count.+ If non-NULL, pp_variables must point to an array with+ *p_count entries, where pointers to the entry point's+ input variables will be written. The caller must not+ free the interface variables written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateEntryPointInputVariables(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+);+++/*! @fn spvReflectEnumerateOutputVariables+ @brief Note: If the module contains multiple entry points, this will only get+ the output variables for the first one.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_count If pp_variables is NULL, the module's output variable+ count will be stored here.+ If pp_variables is not NULL, *p_count must contain+ the module's output variable count.+ @param pp_variables If NULL, the module's output variable count will be+ written to *p_count.+ If non-NULL, pp_variables must point to an array with+ *p_count entries, where pointers to the module's+ output variables will be written. The caller must not+ free the interface variables written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateOutputVariables(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+);++/*! @fn spvReflectEnumerateEntryPointOutputVariables+ @brief Enumerate the output variables for a given entry point.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The name of the entry point to get the output variables for.+ @param p_count If pp_variables is NULL, the entry point's output variable+ count will be stored here.+ If pp_variables is not NULL, *p_count must contain+ the entry point's output variable count.+ @param pp_variables If NULL, the entry point's output variable count will be+ written to *p_count.+ If non-NULL, pp_variables must point to an array with+ *p_count entries, where pointers to the entry point's+ output variables will be written. The caller must not+ free the interface variables written to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateEntryPointOutputVariables(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+);+++/*! @fn spvReflectEnumeratePushConstantBlocks+ @brief Note: If the module contains multiple entry points, this will only get+ the push constant blocks for the first one.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_count If pp_blocks is NULL, the module's push constant+ block count will be stored here.+ If pp_blocks is not NULL, *p_count must+ contain the module's push constant block count.+ @param pp_blocks If NULL, the module's push constant block count+ will be written to *p_count.+ If non-NULL, pp_blocks must point to an+ array with *p_count entries, where pointers to+ the module's push constant blocks will be written.+ The caller must not free the block variables written+ to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumeratePushConstantBlocks(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectBlockVariable** pp_blocks+);+SPV_REFLECT_DEPRECATED("renamed to spvReflectEnumeratePushConstantBlocks")+SpvReflectResult spvReflectEnumeratePushConstants(+ const SpvReflectShaderModule* p_module,+ uint32_t* p_count,+ SpvReflectBlockVariable** pp_blocks+);++/*! @fn spvReflectEnumerateEntryPointPushConstantBlocks+ @brief Enumerate the push constant blocks used in the static call tree of a+ given entry point.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_count If pp_blocks is NULL, the entry point's push constant+ block count will be stored here.+ If pp_blocks is not NULL, *p_count must+ contain the entry point's push constant block count.+ @param pp_blocks If NULL, the entry point's push constant block count+ will be written to *p_count.+ If non-NULL, pp_blocks must point to an+ array with *p_count entries, where pointers to+ the entry point's push constant blocks will be written.+ The caller must not free the block variables written+ to this array.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of the+ failure.++*/+SpvReflectResult spvReflectEnumerateEntryPointPushConstantBlocks(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectBlockVariable** pp_blocks+);+++/*! @fn spvReflectGetDescriptorBinding++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param binding_number The "binding" value of the requested descriptor+ binding.+ @param set_number The "set" value of the requested descriptor binding.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the module contains a descriptor binding that+ matches the provided [binding_number, set_number]+ values, a pointer to that binding is returned. The+ caller must not free this pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note If the module contains multiple desriptor bindings+ with the same set and binding numbers, there are+ no guarantees about which binding will be returned.++*/+const SpvReflectDescriptorBinding* spvReflectGetDescriptorBinding(+ const SpvReflectShaderModule* p_module,+ uint32_t binding_number,+ uint32_t set_number,+ SpvReflectResult* p_result+);++/*! @fn spvReflectGetEntryPointDescriptorBinding+ @brief Get the descriptor binding with the given binding number and set+ number that is used in the static call tree of a certain entry+ point.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The entry point to get the binding from.+ @param binding_number The "binding" value of the requested descriptor+ binding.+ @param set_number The "set" value of the requested descriptor binding.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the entry point contains a descriptor binding that+ matches the provided [binding_number, set_number]+ values, a pointer to that binding is returned. The+ caller must not free this pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note If the entry point contains multiple desriptor bindings+ with the same set and binding numbers, there are+ no guarantees about which binding will be returned.++*/+const SpvReflectDescriptorBinding* spvReflectGetEntryPointDescriptorBinding(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t binding_number,+ uint32_t set_number,+ SpvReflectResult* p_result+);+++/*! @fn spvReflectGetDescriptorSet++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param set_number The "set" value of the requested descriptor set.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the module contains a descriptor set with the+ provided set_number, a pointer to that set is+ returned. The caller must not free this pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.++*/+const SpvReflectDescriptorSet* spvReflectGetDescriptorSet(+ const SpvReflectShaderModule* p_module,+ uint32_t set_number,+ SpvReflectResult* p_result+);++/*! @fn spvReflectGetEntryPointDescriptorSet++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The entry point to get the descriptor set from.+ @param set_number The "set" value of the requested descriptor set.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the entry point contains a descriptor set with the+ provided set_number, a pointer to that set is+ returned. The caller must not free this pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.++*/+const SpvReflectDescriptorSet* spvReflectGetEntryPointDescriptorSet(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t set_number,+ SpvReflectResult* p_result+);+++/* @fn spvReflectGetInputVariableByLocation++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param location The "location" value of the requested input variable.+ A location of 0xFFFFFFFF will always return NULL+ with *p_result == ELEMENT_NOT_FOUND.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the module contains an input interface variable+ with the provided location value, a pointer to that+ variable is returned. The caller must not free this+ pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note++*/+const SpvReflectInterfaceVariable* spvReflectGetInputVariableByLocation(+ const SpvReflectShaderModule* p_module,+ uint32_t location,+ SpvReflectResult* p_result+);+SPV_REFLECT_DEPRECATED("renamed to spvReflectGetInputVariableByLocation")+const SpvReflectInterfaceVariable* spvReflectGetInputVariable(+ const SpvReflectShaderModule* p_module,+ uint32_t location,+ SpvReflectResult* p_result+);++/* @fn spvReflectGetEntryPointInputVariableByLocation++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The entry point to get the input variable from.+ @param location The "location" value of the requested input variable.+ A location of 0xFFFFFFFF will always return NULL+ with *p_result == ELEMENT_NOT_FOUND.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the entry point contains an input interface variable+ with the provided location value, a pointer to that+ variable is returned. The caller must not free this+ pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note++*/+const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableByLocation(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t location,+ SpvReflectResult* p_result+);++/* @fn spvReflectGetInputVariableBySemantic++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param semantic The "semantic" value of the requested input variable.+ A semantic of NULL will return NULL.+ A semantic of "" will always return NULL with+ *p_result == ELEMENT_NOT_FOUND.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the module contains an input interface variable+ with the provided semantic, a pointer to that+ variable is returned. The caller must not free this+ pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note++*/+const SpvReflectInterfaceVariable* spvReflectGetInputVariableBySemantic(+ const SpvReflectShaderModule* p_module,+ const char* semantic,+ SpvReflectResult* p_result+);++/* @fn spvReflectGetEntryPointInputVariableBySemantic++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The entry point to get the input variable from.+ @param semantic The "semantic" value of the requested input variable.+ A semantic of NULL will return NULL.+ A semantic of "" will always return NULL with+ *p_result == ELEMENT_NOT_FOUND.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the entry point contains an input interface variable+ with the provided semantic, a pointer to that+ variable is returned. The caller must not free this+ pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note++*/+const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableBySemantic(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ const char* semantic,+ SpvReflectResult* p_result+);++/* @fn spvReflectGetOutputVariableByLocation++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param location The "location" value of the requested output variable.+ A location of 0xFFFFFFFF will always return NULL+ with *p_result == ELEMENT_NOT_FOUND.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the module contains an output interface variable+ with the provided location value, a pointer to that+ variable is returned. The caller must not free this+ pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note++*/+const SpvReflectInterfaceVariable* spvReflectGetOutputVariableByLocation(+ const SpvReflectShaderModule* p_module,+ uint32_t location,+ SpvReflectResult* p_result+);+SPV_REFLECT_DEPRECATED("renamed to spvReflectGetOutputVariableByLocation")+const SpvReflectInterfaceVariable* spvReflectGetOutputVariable(+ const SpvReflectShaderModule* p_module,+ uint32_t location,+ SpvReflectResult* p_result+);++/* @fn spvReflectGetEntryPointOutputVariableByLocation++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The entry point to get the output variable from.+ @param location The "location" value of the requested output variable.+ A location of 0xFFFFFFFF will always return NULL+ with *p_result == ELEMENT_NOT_FOUND.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the entry point contains an output interface variable+ with the provided location value, a pointer to that+ variable is returned. The caller must not free this+ pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note++*/+const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableByLocation(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ uint32_t location,+ SpvReflectResult* p_result+);++/* @fn spvReflectGetOutputVariableBySemantic++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param semantic The "semantic" value of the requested output variable.+ A semantic of NULL will return NULL.+ A semantic of "" will always return NULL with+ *p_result == ELEMENT_NOT_FOUND.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the module contains an output interface variable+ with the provided semantic, a pointer to that+ variable is returned. The caller must not free this+ pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note++*/+const SpvReflectInterfaceVariable* spvReflectGetOutputVariableBySemantic(+ const SpvReflectShaderModule* p_module,+ const char* semantic,+ SpvReflectResult* p_result+);++/* @fn spvReflectGetEntryPointOutputVariableBySemantic++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The entry point to get the output variable from.+ @param semantic The "semantic" value of the requested output variable.+ A semantic of NULL will return NULL.+ A semantic of "" will always return NULL with+ *p_result == ELEMENT_NOT_FOUND.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the entry point contains an output interface variable+ with the provided semantic, a pointer to that+ variable is returned. The caller must not free this+ pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.+@note++*/+const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableBySemantic(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ const char* semantic,+ SpvReflectResult* p_result+);++/*! @fn spvReflectGetPushConstantBlock++ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param index The index of the desired block within the module's+ array of push constant blocks.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the provided index is within range, a pointer to+ the corresponding push constant block is returned.+ The caller must not free this pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.++*/+const SpvReflectBlockVariable* spvReflectGetPushConstantBlock(+ const SpvReflectShaderModule* p_module,+ uint32_t index,+ SpvReflectResult* p_result+);+SPV_REFLECT_DEPRECATED("renamed to spvReflectGetPushConstantBlock")+const SpvReflectBlockVariable* spvReflectGetPushConstant(+ const SpvReflectShaderModule* p_module,+ uint32_t index,+ SpvReflectResult* p_result+);++/*! @fn spvReflectGetEntryPointPushConstantBlock+ @brief Get the push constant block corresponding to the given entry point.+ As by the Vulkan specification there can be no more than one push+ constant block used by a given entry point, so if there is one it will+ be returned, otherwise NULL will be returned.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param entry_point The entry point to get the push constant block from.+ @param p_result If successful, SPV_REFLECT_RESULT_SUCCESS will be+ written to *p_result. Otherwise, a error code+ indicating the cause of the failure will be stored+ here.+ @return If the provided index is within range, a pointer to+ the corresponding push constant block is returned.+ The caller must not free this pointer.+ If no match can be found, or if an unrelated error+ occurs, the return value will be NULL. Detailed+ error results are written to *pResult.++*/+const SpvReflectBlockVariable* spvReflectGetEntryPointPushConstantBlock(+ const SpvReflectShaderModule* p_module,+ const char* entry_point,+ SpvReflectResult* p_result+);+++/*! @fn spvReflectChangeDescriptorBindingNumbers+ @brief Assign new set and/or binding numbers to a descriptor binding.+ In addition to updating the reflection data, this function modifies+ the underlying SPIR-V bytecode. The updated code can be retrieved+ with spvReflectGetCode(). If the binding is used in multiple+ entry points within the module, it will be changed in all of them.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_binding Pointer to the descriptor binding to modify.+ @param new_binding_number The new binding number to assign to the+ provided descriptor binding.+ To leave the binding number unchanged, pass+ SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE.+ @param new_set_number The new set number to assign to the+ provided descriptor binding. Successfully changing+ a descriptor binding's set number invalidates all+ existing SpvReflectDescriptorBinding and+ SpvReflectDescriptorSet pointers from this module.+ To leave the set number unchanged, pass+ SPV_REFLECT_SET_NUMBER_DONT_CHANGE.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of+ the failure.+*/+SpvReflectResult spvReflectChangeDescriptorBindingNumbers(+ SpvReflectShaderModule* p_module,+ const SpvReflectDescriptorBinding* p_binding,+ uint32_t new_binding_number,+ uint32_t new_set_number+);+SPV_REFLECT_DEPRECATED("Renamed to spvReflectChangeDescriptorBindingNumbers")+SpvReflectResult spvReflectChangeDescriptorBindingNumber(+ SpvReflectShaderModule* p_module,+ const SpvReflectDescriptorBinding* p_descriptor_binding,+ uint32_t new_binding_number,+ uint32_t optional_new_set_number+);++/*! @fn spvReflectChangeDescriptorSetNumber+ @brief Assign a new set number to an entire descriptor set (including+ all descriptor bindings in that set).+ In addition to updating the reflection data, this function modifies+ the underlying SPIR-V bytecode. The updated code can be retrieved+ with spvReflectGetCode(). If the descriptor set is used in+ multiple entry points within the module, it will be modified in all+ of them.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_set Pointer to the descriptor binding to modify.+ @param new_set_number The new set number to assign to the+ provided descriptor set, and all its descriptor+ bindings. Successfully changing a descriptor+ binding's set number invalidates all existing+ SpvReflectDescriptorBinding and+ SpvReflectDescriptorSet pointers from this module.+ To leave the set number unchanged, pass+ SPV_REFLECT_SET_NUMBER_DONT_CHANGE.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of+ the failure.+*/+SpvReflectResult spvReflectChangeDescriptorSetNumber(+ SpvReflectShaderModule* p_module,+ const SpvReflectDescriptorSet* p_set,+ uint32_t new_set_number+);++/*! @fn spvReflectChangeInputVariableLocation+ @brief Assign a new location to an input interface variable.+ In addition to updating the reflection data, this function modifies+ the underlying SPIR-V bytecode. The updated code can be retrieved+ with spvReflectGetCode().+ It is the caller's responsibility to avoid assigning the same+ location to multiple input variables. If the input variable is used+ by multiple entry points in the module, it will be changed in all of+ them.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_input_variable Pointer to the input variable to update.+ @param new_location The new location to assign to p_input_variable.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of+ the failure.++*/+SpvReflectResult spvReflectChangeInputVariableLocation(+ SpvReflectShaderModule* p_module,+ const SpvReflectInterfaceVariable* p_input_variable,+ uint32_t new_location+);+++/*! @fn spvReflectChangeOutputVariableLocation+ @brief Assign a new location to an output interface variable.+ In addition to updating the reflection data, this function modifies+ the underlying SPIR-V bytecode. The updated code can be retrieved+ with spvReflectGetCode().+ It is the caller's responsibility to avoid assigning the same+ location to multiple output variables. If the output variable is used+ by multiple entry points in the module, it will be changed in all of+ them.+ @param p_module Pointer to an instance of SpvReflectShaderModule.+ @param p_output_variable Pointer to the output variable to update.+ @param new_location The new location to assign to p_output_variable.+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.+ Otherwise, the error code indicates the cause of+ the failure.++*/+SpvReflectResult spvReflectChangeOutputVariableLocation(+ SpvReflectShaderModule* p_module,+ const SpvReflectInterfaceVariable* p_output_variable,+ uint32_t new_location+);+++/*! @fn spvReflectSourceLanguage++ @param source_lang The source language code.+ @return Returns string of source language specified in \a source_lang.+ The caller must not free the memory associated with this string.+*/+const char* spvReflectSourceLanguage(SpvSourceLanguage source_lang);++/*! @fn spvReflectBlockVariableTypeName++ @param p_var Pointer to block variable.+ @return Returns string of block variable's type description type name+ or NULL if p_var is NULL.+*/+const char* spvReflectBlockVariableTypeName(+ const SpvReflectBlockVariable* p_var+);++#if defined(__cplusplus)+};+#endif++#if defined(__cplusplus)+#include <cstdlib>+#include <string>+#include <vector>++namespace spv_reflect {++/*! \class ShaderModule++*/+class ShaderModule {+public:+ ShaderModule();+ ShaderModule(size_t size, const void* p_code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE);+ ShaderModule(const std::vector<uint8_t>& code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE);+ ShaderModule(const std::vector<uint32_t>& code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE);+ ~ShaderModule();++ ShaderModule(ShaderModule&& other);+ ShaderModule& operator=(ShaderModule&& other);++ SpvReflectResult GetResult() const;++ const SpvReflectShaderModule& GetShaderModule() const;++ uint32_t GetCodeSize() const;+ const uint32_t* GetCode() const;++ const char* GetEntryPointName() const;++ const char* GetSourceFile() const;++ uint32_t GetEntryPointCount() const;+ const char* GetEntryPointName(uint32_t index) const;+ SpvReflectShaderStageFlagBits GetEntryPointShaderStage(uint32_t index) const;++ SpvReflectShaderStageFlagBits GetShaderStage() const;+ SPV_REFLECT_DEPRECATED("Renamed to GetShaderStage")+ SpvReflectShaderStageFlagBits GetVulkanShaderStage() const {+ return GetShaderStage();+ }++ SpvReflectResult EnumerateDescriptorBindings(uint32_t* p_count, SpvReflectDescriptorBinding** pp_bindings) const;+ SpvReflectResult EnumerateEntryPointDescriptorBindings(const char* entry_point, uint32_t* p_count, SpvReflectDescriptorBinding** pp_bindings) const;+ SpvReflectResult EnumerateDescriptorSets( uint32_t* p_count, SpvReflectDescriptorSet** pp_sets) const ;+ SpvReflectResult EnumerateEntryPointDescriptorSets(const char* entry_point, uint32_t* p_count, SpvReflectDescriptorSet** pp_sets) const ;+ SpvReflectResult EnumerateInterfaceVariables(uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const;+ SpvReflectResult EnumerateEntryPointInterfaceVariables(const char* entry_point, uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const;+ SpvReflectResult EnumerateInputVariables(uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const;+ SpvReflectResult EnumerateEntryPointInputVariables(const char* entry_point, uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const;+ SpvReflectResult EnumerateOutputVariables(uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const;+ SpvReflectResult EnumerateEntryPointOutputVariables(const char* entry_point, uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const;+ SpvReflectResult EnumeratePushConstantBlocks(uint32_t* p_count, SpvReflectBlockVariable** pp_blocks) const;+ SpvReflectResult EnumerateEntryPointPushConstantBlocks(const char* entry_point, uint32_t* p_count, SpvReflectBlockVariable** pp_blocks) const;+ SPV_REFLECT_DEPRECATED("Renamed to EnumeratePushConstantBlocks")+ SpvReflectResult EnumeratePushConstants(uint32_t* p_count, SpvReflectBlockVariable** pp_blocks) const {+ return EnumeratePushConstantBlocks(p_count, pp_blocks);+ }++ const SpvReflectDescriptorBinding* GetDescriptorBinding(uint32_t binding_number, uint32_t set_number, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectDescriptorBinding* GetEntryPointDescriptorBinding(const char* entry_point, uint32_t binding_number, uint32_t set_number, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectDescriptorSet* GetDescriptorSet(uint32_t set_number, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectDescriptorSet* GetEntryPointDescriptorSet(const char* entry_point, uint32_t set_number, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectInterfaceVariable* GetInputVariableByLocation(uint32_t location, SpvReflectResult* p_result = nullptr) const;+ SPV_REFLECT_DEPRECATED("Renamed to GetInputVariableByLocation")+ const SpvReflectInterfaceVariable* GetInputVariable(uint32_t location, SpvReflectResult* p_result = nullptr) const {+ return GetInputVariableByLocation(location, p_result);+ }+ const SpvReflectInterfaceVariable* GetEntryPointInputVariableByLocation(const char* entry_point, uint32_t location, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectInterfaceVariable* GetInputVariableBySemantic(const char* semantic, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectInterfaceVariable* GetEntryPointInputVariableBySemantic(const char* entry_point, const char* semantic, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectInterfaceVariable* GetOutputVariableByLocation(uint32_t location, SpvReflectResult* p_result = nullptr) const;+ SPV_REFLECT_DEPRECATED("Renamed to GetOutputVariableByLocation")+ const SpvReflectInterfaceVariable* GetOutputVariable(uint32_t location, SpvReflectResult* p_result = nullptr) const {+ return GetOutputVariableByLocation(location, p_result);+ }+ const SpvReflectInterfaceVariable* GetEntryPointOutputVariableByLocation(const char* entry_point, uint32_t location, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectInterfaceVariable* GetOutputVariableBySemantic(const char* semantic, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectInterfaceVariable* GetEntryPointOutputVariableBySemantic(const char* entry_point, const char* semantic, SpvReflectResult* p_result = nullptr) const;+ const SpvReflectBlockVariable* GetPushConstantBlock(uint32_t index, SpvReflectResult* p_result = nullptr) const;+ SPV_REFLECT_DEPRECATED("Renamed to GetPushConstantBlock")+ const SpvReflectBlockVariable* GetPushConstant(uint32_t index, SpvReflectResult* p_result = nullptr) const {+ return GetPushConstantBlock(index, p_result);+ }+ const SpvReflectBlockVariable* GetEntryPointPushConstantBlock(const char* entry_point, SpvReflectResult* p_result = nullptr) const;++ SpvReflectResult ChangeDescriptorBindingNumbers(const SpvReflectDescriptorBinding* p_binding,+ uint32_t new_binding_number = SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE,+ uint32_t optional_new_set_number = SPV_REFLECT_SET_NUMBER_DONT_CHANGE);+ SPV_REFLECT_DEPRECATED("Renamed to ChangeDescriptorBindingNumbers")+ SpvReflectResult ChangeDescriptorBindingNumber(const SpvReflectDescriptorBinding* p_binding, uint32_t new_binding_number = SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE,+ uint32_t new_set_number = SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {+ return ChangeDescriptorBindingNumbers(p_binding, new_binding_number, new_set_number);+ }+ SpvReflectResult ChangeDescriptorSetNumber(const SpvReflectDescriptorSet* p_set, uint32_t new_set_number = SPV_REFLECT_SET_NUMBER_DONT_CHANGE);+ SpvReflectResult ChangeInputVariableLocation(const SpvReflectInterfaceVariable* p_input_variable, uint32_t new_location);+ SpvReflectResult ChangeOutputVariableLocation(const SpvReflectInterfaceVariable* p_output_variable, uint32_t new_location);++private:+ // Make noncopyable+ ShaderModule(const ShaderModule&);+ ShaderModule& operator=(const ShaderModule&);++private:+ mutable SpvReflectResult m_result = SPV_REFLECT_RESULT_NOT_READY;+ SpvReflectShaderModule m_module = {};+};+++// =================================================================================================+// ShaderModule+// =================================================================================================++/*! @fn ShaderModule++*/+inline ShaderModule::ShaderModule() {}+++/*! @fn ShaderModule++ @param size+ @param p_code++*/+inline ShaderModule::ShaderModule(size_t size, const void* p_code, SpvReflectModuleFlags flags) {+ m_result = spvReflectCreateShaderModule2(+ flags,+ size,+ p_code,+ &m_module);+}++/*! @fn ShaderModule++ @param code+ +*/+inline ShaderModule::ShaderModule(const std::vector<uint8_t>& code, SpvReflectModuleFlags flags) {+ m_result = spvReflectCreateShaderModule2(+ flags,+ code.size(),+ code.data(),+ &m_module);+}++/*! @fn ShaderModule++ @param code+ +*/+inline ShaderModule::ShaderModule(const std::vector<uint32_t>& code, SpvReflectModuleFlags flags) {+ m_result = spvReflectCreateShaderModule2(+ flags,+ code.size() * sizeof(uint32_t),+ code.data(),+ &m_module);+}++/*! @fn ~ShaderModule++*/+inline ShaderModule::~ShaderModule() {+ spvReflectDestroyShaderModule(&m_module);+}+++inline ShaderModule::ShaderModule(ShaderModule&& other)+{+ *this = std::move(other);+}++inline ShaderModule& ShaderModule::operator=(ShaderModule&& other)+{+ m_result = std::move(other.m_result);+ m_module = std::move(other.m_module);++ other.m_module = {};+ return *this;+}++/*! @fn GetResult++ @return++*/+inline SpvReflectResult ShaderModule::GetResult() const {+ return m_result;+}+++/*! @fn GetShaderModule++ @return++*/+inline const SpvReflectShaderModule& ShaderModule::GetShaderModule() const {+ return m_module;+}+++/*! @fn GetCodeSize++ @return++ */+inline uint32_t ShaderModule::GetCodeSize() const {+ return spvReflectGetCodeSize(&m_module);+}+++/*! @fn GetCode++ @return++*/+inline const uint32_t* ShaderModule::GetCode() const {+ return spvReflectGetCode(&m_module);+}+++/*! @fn GetEntryPoint++ @return Returns entry point++*/+inline const char* ShaderModule::GetEntryPointName() const {+ return this->GetEntryPointName(0);+}++/*! @fn GetEntryPoint++ @return Returns entry point++*/+inline const char* ShaderModule::GetSourceFile() const {+ return m_module.source_file;+}++/*! @fn GetEntryPointCount++ @param+ @return+*/+inline uint32_t ShaderModule::GetEntryPointCount() const {+ return m_module.entry_point_count;+}++/*! @fn GetEntryPointName++ @param index+ @return+*/+inline const char* ShaderModule::GetEntryPointName(uint32_t index) const {+ return m_module.entry_points[index].name;+}++/*! @fn GetEntryPointShaderStage++ @param index+ @return Returns the shader stage for the entry point at \b index+*/+inline SpvReflectShaderStageFlagBits ShaderModule::GetEntryPointShaderStage(uint32_t index) const {+ return m_module.entry_points[index].shader_stage;+}++/*! @fn GetShaderStage++ @return Returns shader stage for the first entry point++*/+inline SpvReflectShaderStageFlagBits ShaderModule::GetShaderStage() const {+ return m_module.shader_stage;+}++/*! @fn EnumerateDescriptorBindings++ @param count+ @param p_binding_numbers+ @param pp_bindings+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateDescriptorBindings(+ uint32_t* p_count,+ SpvReflectDescriptorBinding** pp_bindings+) const+{+ m_result = spvReflectEnumerateDescriptorBindings(+ &m_module,+ p_count,+ pp_bindings);+ return m_result;+}++/*! @fn EnumerateEntryPointDescriptorBindings++ @param entry_point+ @param count+ @param pp_bindings+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateEntryPointDescriptorBindings(+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectDescriptorBinding** pp_bindings+) const+{+ m_result = spvReflectEnumerateEntryPointDescriptorBindings(+ &m_module,+ entry_point,+ p_count,+ pp_bindings);+ return m_result;+}+++/*! @fn EnumerateDescriptorSets++ @param count+ @param pp_sets+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateDescriptorSets(+ uint32_t* p_count,+ SpvReflectDescriptorSet** pp_sets+) const+{+ m_result = spvReflectEnumerateDescriptorSets(+ &m_module,+ p_count,+ pp_sets);+ return m_result;+}++/*! @fn EnumerateEntryPointDescriptorSets++ @param entry_point+ @param count+ @param pp_sets+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateEntryPointDescriptorSets(+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectDescriptorSet** pp_sets+) const+{+ m_result = spvReflectEnumerateEntryPointDescriptorSets(+ &m_module,+ entry_point,+ p_count,+ pp_sets);+ return m_result;+}+++/*! @fn EnumerateInterfaceVariables++ @param count+ @param pp_variables+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateInterfaceVariables(+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+) const+{+ m_result = spvReflectEnumerateInterfaceVariables(+ &m_module,+ p_count,+ pp_variables);+ return m_result;+}++/*! @fn EnumerateEntryPointInterfaceVariables++ @param entry_point+ @param count+ @param pp_variables+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateEntryPointInterfaceVariables(+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+) const+{+ m_result = spvReflectEnumerateEntryPointInterfaceVariables(+ &m_module,+ entry_point,+ p_count,+ pp_variables);+ return m_result;+}+++/*! @fn EnumerateInputVariables++ @param count+ @param pp_variables+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateInputVariables(+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+) const+{+ m_result = spvReflectEnumerateInputVariables(+ &m_module,+ p_count,+ pp_variables);+ return m_result;+}++/*! @fn EnumerateEntryPointInputVariables++ @param entry_point+ @param count+ @param pp_variables+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateEntryPointInputVariables(+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+) const+{+ m_result = spvReflectEnumerateEntryPointInputVariables(+ &m_module,+ entry_point,+ p_count,+ pp_variables);+ return m_result;+}+++/*! @fn EnumerateOutputVariables++ @param count+ @param pp_variables+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateOutputVariables(+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+) const+{+ m_result = spvReflectEnumerateOutputVariables(+ &m_module,+ p_count,+ pp_variables);+ return m_result;+}++/*! @fn EnumerateEntryPointOutputVariables++ @param entry_point+ @param count+ @param pp_variables+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateEntryPointOutputVariables(+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectInterfaceVariable** pp_variables+) const+{+ m_result = spvReflectEnumerateEntryPointOutputVariables(+ &m_module,+ entry_point,+ p_count,+ pp_variables);+ return m_result;+}+++/*! @fn EnumeratePushConstantBlocks++ @param count+ @param pp_blocks+ @return++*/+inline SpvReflectResult ShaderModule::EnumeratePushConstantBlocks(+ uint32_t* p_count,+ SpvReflectBlockVariable** pp_blocks+) const+{+ m_result = spvReflectEnumeratePushConstantBlocks(+ &m_module,+ p_count,+ pp_blocks);+ return m_result;+}++/*! @fn EnumerateEntryPointPushConstantBlocks++ @param entry_point+ @param count+ @param pp_blocks+ @return++*/+inline SpvReflectResult ShaderModule::EnumerateEntryPointPushConstantBlocks(+ const char* entry_point,+ uint32_t* p_count,+ SpvReflectBlockVariable** pp_blocks+) const+{+ m_result = spvReflectEnumerateEntryPointPushConstantBlocks(+ &m_module,+ entry_point,+ p_count,+ pp_blocks);+ return m_result;+}+++/*! @fn GetDescriptorBinding++ @param binding_number+ @param set_number+ @param p_result+ @return++*/+inline const SpvReflectDescriptorBinding* ShaderModule::GetDescriptorBinding(+ uint32_t binding_number,+ uint32_t set_number,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetDescriptorBinding(+ &m_module,+ binding_number,+ set_number,+ p_result);+}++/*! @fn GetEntryPointDescriptorBinding++ @param entry_point+ @param binding_number+ @param set_number+ @param p_result+ @return++*/+inline const SpvReflectDescriptorBinding* ShaderModule::GetEntryPointDescriptorBinding(+ const char* entry_point,+ uint32_t binding_number,+ uint32_t set_number,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetEntryPointDescriptorBinding(+ &m_module,+ entry_point,+ binding_number,+ set_number,+ p_result);+}+++/*! @fn GetDescriptorSet++ @param set_number+ @param p_result+ @return++*/+inline const SpvReflectDescriptorSet* ShaderModule::GetDescriptorSet(+ uint32_t set_number,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetDescriptorSet(+ &m_module,+ set_number,+ p_result);+}++/*! @fn GetEntryPointDescriptorSet++ @param entry_point+ @param set_number+ @param p_result+ @return++*/+inline const SpvReflectDescriptorSet* ShaderModule::GetEntryPointDescriptorSet(+ const char* entry_point,+ uint32_t set_number,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetEntryPointDescriptorSet(+ &m_module,+ entry_point,+ set_number,+ p_result);+}+++/*! @fn GetInputVariable++ @param location+ @param p_result+ @return++*/+inline const SpvReflectInterfaceVariable* ShaderModule::GetInputVariableByLocation(+ uint32_t location,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetInputVariableByLocation(+ &m_module,+ location,+ p_result);+}+inline const SpvReflectInterfaceVariable* ShaderModule::GetInputVariableBySemantic(+ const char* semantic,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetInputVariableBySemantic(+ &m_module,+ semantic,+ p_result);+}++/*! @fn GetEntryPointInputVariable++ @param entry_point+ @param location+ @param p_result+ @return++*/+inline const SpvReflectInterfaceVariable* ShaderModule::GetEntryPointInputVariableByLocation(+ const char* entry_point,+ uint32_t location,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetEntryPointInputVariableByLocation(+ &m_module,+ entry_point,+ location,+ p_result);+}+inline const SpvReflectInterfaceVariable* ShaderModule::GetEntryPointInputVariableBySemantic(+ const char* entry_point,+ const char* semantic,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetEntryPointInputVariableBySemantic(+ &m_module,+ entry_point,+ semantic,+ p_result);+}+++/*! @fn GetOutputVariable++ @param location+ @param p_result+ @return++*/+inline const SpvReflectInterfaceVariable* ShaderModule::GetOutputVariableByLocation(+ uint32_t location,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetOutputVariableByLocation(+ &m_module,+ location,+ p_result);+}+inline const SpvReflectInterfaceVariable* ShaderModule::GetOutputVariableBySemantic(+ const char* semantic,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetOutputVariableBySemantic(&m_module,+ semantic,+ p_result);+}++/*! @fn GetEntryPointOutputVariable++ @param entry_point+ @param location+ @param p_result+ @return++*/+inline const SpvReflectInterfaceVariable* ShaderModule::GetEntryPointOutputVariableByLocation(+ const char* entry_point,+ uint32_t location,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetEntryPointOutputVariableByLocation(+ &m_module,+ entry_point,+ location,+ p_result);+}+inline const SpvReflectInterfaceVariable* ShaderModule::GetEntryPointOutputVariableBySemantic(+ const char* entry_point,+ const char* semantic,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetEntryPointOutputVariableBySemantic(+ &m_module,+ entry_point,+ semantic,+ p_result);+}+++/*! @fn GetPushConstant++ @param index+ @param p_result+ @return++*/+inline const SpvReflectBlockVariable* ShaderModule::GetPushConstantBlock(+ uint32_t index,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetPushConstantBlock(+ &m_module,+ index,+ p_result);+}++/*! @fn GetEntryPointPushConstant++ @param entry_point+ @param index+ @param p_result+ @return++*/+inline const SpvReflectBlockVariable* ShaderModule::GetEntryPointPushConstantBlock(+ const char* entry_point,+ SpvReflectResult* p_result+) const+{+ return spvReflectGetEntryPointPushConstantBlock(+ &m_module,+ entry_point,+ p_result);+}+++/*! @fn ChangeDescriptorBindingNumbers++ @param p_binding+ @param new_binding_number+ @param new_set_number+ @return++*/+inline SpvReflectResult ShaderModule::ChangeDescriptorBindingNumbers(+ const SpvReflectDescriptorBinding* p_binding,+ uint32_t new_binding_number,+ uint32_t new_set_number+)+{+ return spvReflectChangeDescriptorBindingNumbers(+ &m_module,+ p_binding,+ new_binding_number,+ new_set_number);+}+++/*! @fn ChangeDescriptorSetNumber++ @param p_set+ @param new_set_number+ @return++*/+inline SpvReflectResult ShaderModule::ChangeDescriptorSetNumber(+ const SpvReflectDescriptorSet* p_set,+ uint32_t new_set_number+)+{+ return spvReflectChangeDescriptorSetNumber(+ &m_module,+ p_set,+ new_set_number);+}+++/*! @fn ChangeInputVariableLocation++ @param p_input_variable+ @param new_location+ @return++*/+inline SpvReflectResult ShaderModule::ChangeInputVariableLocation(+ const SpvReflectInterfaceVariable* p_input_variable,+ uint32_t new_location)+{+ return spvReflectChangeInputVariableLocation(+ &m_module,+ p_input_variable,+ new_location);+}+++/*! @fn ChangeOutputVariableLocation++ @param p_input_variable+ @param new_location+ @return++*/+inline SpvReflectResult ShaderModule::ChangeOutputVariableLocation(+ const SpvReflectInterfaceVariable* p_output_variable,+ uint32_t new_location)+{+ return spvReflectChangeOutputVariableLocation(+ &m_module,+ p_output_variable,+ new_location);+}++} // namespace spv_reflect+#endif // defined(__cplusplus)+#endif // SPIRV_REFLECT_H
+ lib/Data/SpirV/Reflect/FFI.hs view
@@ -0,0 +1,34 @@+module Data.SpirV.Reflect.FFI+ ( Module+ , load+ , loadBytes+ ) where++import Control.Exception (finally)+import Control.Monad.IO.Class (MonadIO(..))+import Data.ByteString (ByteString)+import Data.ByteString qualified as ByteString+import Data.ByteString.Unsafe (unsafeUseAsCStringLen)+import Data.SpirV.Reflect.FFI.Internal qualified as C+import Foreign (allocaBytes, castPtr)++import Data.SpirV.Reflect.Module (Module)++load :: MonadIO io => FilePath -> io Module+load path = liftIO $+ ByteString.readFile path >>= loadBytes++loadBytes :: MonadIO io => ByteString -> io Module+loadBytes bytes = liftIO do+ unsafeUseAsCStringLen bytes \(code, size) -> do+ allocaBytes C.shaderModuleSize \smPtr -> do+ res <- C.createShaderModule2+ C.SpvReflectModuleFlagNoCopy+ (fromIntegral size)+ (castPtr code)+ smPtr+ case res of+ C.SpvReflectResultSuccess ->+ C.inflateModule smPtr `finally` C.destroyShaderModule smPtr+ err ->+ error $ "spvReflectCreateShaderModule2:" <> show err
+ lib/Data/SpirV/Reflect/FFI/Internal.chs view
@@ -0,0 +1,494 @@+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Data.SpirV.Reflect.FFI.Internal where++import Data.Coerce (Coercible, coerce)+import Data.Text (Text)+import Data.Text qualified as Text+import Data.Vector (Vector)+import Data.Vector qualified as Vector+import Data.Word (Word32)+import Foreign.C.String (CString)+import Foreign.C.Types (CULong)+import Foreign.Marshal.Utils (maybePeek)+import Foreign.Ptr (Ptr, castPtr, plusPtr, nullPtr)+import Foreign.Storable (peek)+import GHC.Ptr qualified as GHC++import Data.SpirV.Reflect.BlockVariable (BlockVariable)+import Data.SpirV.Reflect.BlockVariable qualified as BlockVariable+import Data.SpirV.Reflect.DescriptorBinding (DescriptorBinding)+import Data.SpirV.Reflect.DescriptorBinding qualified as DescriptorBinding+import Data.SpirV.Reflect.DescriptorSet (DescriptorSet)+import Data.SpirV.Reflect.DescriptorSet qualified as DescriptorSet+import Data.SpirV.Reflect.Enums qualified as Enums+import Data.SpirV.Reflect.InterfaceVariable (InterfaceVariable)+import Data.SpirV.Reflect.InterfaceVariable qualified as InterfaceVariable+import Data.SpirV.Reflect.Module (Module)+import Data.SpirV.Reflect.Module qualified as Module+import Data.SpirV.Reflect.Traits qualified as Traits+import Data.SpirV.Reflect.TypeDescription (TypeDescription)+import Data.SpirV.Reflect.TypeDescription qualified as TypeDescription++#include "spirv_reflect.h"++-- * Loader interface++{#pointer *SpvReflectShaderModule as ShaderModulePtr #}++{#enum+ SpvReflectResult as Result+ {underscoreToCase}+ deriving (Eq, Ord, Show)+#}++{#fun unsafe+ spvReflectCreateShaderModule as createShaderModule+ { id `CULong'+ , `Ptr ()'+ , `ShaderModulePtr'+ } -> `Result'+#}++{#enum+ SpvReflectModuleFlagBits as ModuleFlags+ {underscoreToCase}+ deriving (Eq, Ord, Show)+#}++{#fun unsafe+ spvReflectCreateShaderModule2 as createShaderModule2+ { `ModuleFlags'+ , id `CULong'+ , `Ptr ()'+ , `ShaderModulePtr'+ } -> `Result'+#}++{#fun unsafe+ spvReflectDestroyShaderModule as destroyShaderModule+ { `ShaderModulePtr'+ } -> `()'+#}++-- TODO: inflateEntryPoints :: ShaderModulePtr -> IO [EntryPoint]++-- * Module++shaderModuleSize :: Int+shaderModuleSize = {#sizeof SpvReflectShaderModule #}++inflateModule :: ShaderModulePtr -> IO Module+inflateModule smp = do+ let sm = castPtr smp++ generator <- inflateEnum $+ {#get SpvReflectShaderModule->generator #} sm++ entry_point_name <- inflateText $+ {#get SpvReflectShaderModule->entry_point_name #} sm++ entry_point_id <- inflateIntegral $+ {#get SpvReflectShaderModule->entry_point_id #} sm++ -- TODO: enums+ source_language <- inflateIntegral $+ {#get SpvReflectShaderModule->source_language #} sm++ source_language_version <- inflateIntegral $+ {#get SpvReflectShaderModule->source_language_version #} sm++ -- XXX: Uses value(s) from first entry point++ -- TODO: flags+ spirv_execution_model <- inflateIntegral $+ {#get SpvReflectShaderModule->spirv_execution_model #} sm++ -- TODO: flags+ shader_stage <- inflateIntegral $+ {#get SpvReflectShaderModule->shader_stage #} sm++ descriptor_bindings <-+ inflateVector+ ({#get SpvReflectShaderModule->descriptor_binding_count #} sm)+ ({#get SpvReflectShaderModule->descriptor_bindings #} sm)+ {#sizeof SpvReflectDescriptorBinding #}+ inflateDescriptorBinding++ descriptor_sets <-+ inflateVector+ ({#get SpvReflectShaderModule->descriptor_set_count #} sm)+ ({#get SpvReflectShaderModule->descriptor_sets #} sm)+ {#sizeof SpvReflectDescriptorSet #}+ inflateDescriptorSet++ inputPtr <- {#get SpvReflectShaderModule->input_variables #} sm+ input_variables <-+ if inputPtr == nullPtr then+ pure mempty+ else+ inflateVector+ ({#get SpvReflectShaderModule->input_variable_count #} sm)+ (peek inputPtr)+ {#sizeof SpvReflectInterfaceVariable #}+ inflateInterfaceVariable++ outputPtr <- {#get SpvReflectShaderModule->output_variables #} sm+ output_variables <-+ if outputPtr == nullPtr then+ pure mempty+ else+ inflateVector+ ({#get SpvReflectShaderModule->output_variable_count #} sm)+ (peek outputPtr)+ {#sizeof SpvReflectInterfaceVariable #}+ inflateInterfaceVariable++ push_constants <-+ inflateVector+ ({#get SpvReflectShaderModule->push_constant_block_count #} sm)+ ({#get SpvReflectShaderModule->push_constant_blocks #} sm)+ {#sizeof SpvReflectBlockVariable #}+ inflateBlockVariable++ pure Module.Module{..}++inflateVector :: Integral i => IO i -> IO (Ptr p) -> Int -> (Ptr p -> IO a) -> IO (Vector a)+inflateVector getCount getItems itemSize inflate = do+ count <- getCount+ itemsPtr <- getItems+ Vector.generateM (fromIntegral count) \pos -> do+ inflate $ itemsPtr `plusPtr` (itemSize * pos)++{#pointer *SpvReflectDescriptorBinding as DescriptorBindingPtr #}++inflateDescriptorBinding :: DescriptorBindingPtr -> IO DescriptorBinding+inflateDescriptorBinding db = do+ spirv_id <- fmap Just . inflateIntegral $+ {#get SpvReflectDescriptorBinding->spirv_id #} db++ name <- inflateText $+ {#get SpvReflectDescriptorBinding->name #} db++ binding <- inflateIntegral $+ {#get SpvReflectDescriptorBinding->binding #} db++ input_attachment_index <- inflateIntegral $+ {#get SpvReflectDescriptorBinding->input_attachment_index #} db++ set <- inflateIntegral $+ {#get SpvReflectDescriptorBinding->set #} db++ descriptor_type <- inflateEnum $+ {#get SpvReflectDescriptorBinding->descriptor_type #} db++ resource_type <- inflateFlags32 $+ {#get SpvReflectDescriptorBinding->resource_type #} db++ image <-+ inflateImageTraits+ db+ {#offsetof SpvReflectDescriptorBinding->image #}++ block <-+ {#get SpvReflectDescriptorBinding->block #} db >>=+ maybePeek inflateBlockVariable++ array <-+ inflateArrayTraits+ db+ {#offsetof SpvReflectDescriptorBinding->array #}++ count <- fmap Just . inflateIntegral $+ {#get SpvReflectDescriptorBinding->count #} db++ accessed <- inflateIntegral $+ {#get SpvReflectDescriptorBinding->accessed #} db++ uav_counter_id <- inflateIntegral $+ {#get SpvReflectDescriptorBinding->uav_counter_id #} db++ uav_counter_binding <-+ {#get SpvReflectDescriptorBinding->uav_counter_binding #} db >>=+ maybePeek inflateDescriptorBinding++ type_description <-+ {#get SpvReflectDescriptorBinding->type_description #} db >>=+ maybePeek inflateTypeDescription++ let word_offset = DescriptorBinding.WordOffset{..}++ decoration_flags <- inflateFlags32 $+ {#get SpvReflectDescriptorBinding->decoration_flags #} db++ pure DescriptorBinding.DescriptorBinding{..}++{#pointer *SpvReflectBlockVariable as BlockVariablePtr #}++inflateBlockVariable :: BlockVariablePtr -> IO BlockVariable+inflateBlockVariable bv = do+ spirv_id <- fmap Just . inflateIntegral $+ {#get SpvReflectBlockVariable->spirv_id #} bv++ name <- fmap Just . inflateText $+ {#get SpvReflectBlockVariable->name #} bv++ offset <- inflateIntegral $+ {#get SpvReflectBlockVariable->offset #} bv++ absolute_offset <- inflateIntegral $+ {#get SpvReflectBlockVariable->absolute_offset #} bv++ size <- inflateIntegral $+ {#get SpvReflectBlockVariable->size #} bv++ padded_size <- inflateIntegral $+ {#get SpvReflectBlockVariable->padded_size #} bv++ decorations <- inflateFlags32 $+ {#get SpvReflectBlockVariable->decoration_flags #} bv++ numeric <-+ inflateNumericTraits+ bv+ {#offsetof SpvReflectBlockVariable->numeric #}++ array <-+ inflateArrayTraits+ bv+ {#offsetof SpvReflectBlockVariable->array #}++ members <-+ inflateVector+ ({#get SpvReflectBlockVariable->member_count #} bv)+ ({#get SpvReflectBlockVariable->members #} bv)+ {#sizeof SpvReflectBlockVariable #}+ inflateBlockVariable++ type_description <-+ {#get SpvReflectBlockVariable->members #} bv >>=+ maybePeek inflateTypeDescription++ pure BlockVariable.BlockVariable{..}++{#pointer *SpvReflectTypeDescription as TypeDescriptionPtr #}++inflateTypeDescription :: TypeDescriptionPtr -> IO TypeDescription+inflateTypeDescription td = do+ id_ <- fmap Just . inflateIntegral $+ {#get SpvReflectTypeDescription->id #} td++ op <- fmap Just . inflateEnum $+ {#get SpvReflectTypeDescription->op #} td++ type_name <- fmap Just . inflateText $+ {#get SpvReflectTypeDescription->type_name #} td++ struct_member_name <- fmap Just . inflateText $+ {#get SpvReflectTypeDescription->struct_member_name #} td++ storage_class <- inflateEnum $+ {#get SpvReflectTypeDescription->storage_class #} td++ type_flags <- inflateFlags32 $+ {#get SpvReflectTypeDescription->type_flags #} td++ numeric <-+ inflateNumericTraits+ td+ {#offsetof SpvReflectTypeDescription->traits.numeric #}++ image <-+ inflateImageTraits+ td+ {#offsetof SpvReflectTypeDescription->traits.image #}++ array <-+ inflateArrayTraits+ td+ {#offsetof SpvReflectTypeDescription->traits.array #}++ let traits = Just TypeDescription.Traits{..}++ members <-+ inflateVector+ ({#get SpvReflectTypeDescription->member_count #} td)+ ({#get SpvReflectTypeDescription->members #} td)+ {#sizeof SpvReflectTypeDescription #}+ inflateTypeDescription++ pure TypeDescription.TypeDescription{id=id_, ..}++{#pointer *SpvReflectDescriptorSet as DescriptorSetPtr #}++inflateDescriptorSet :: DescriptorSetPtr -> IO DescriptorSet+inflateDescriptorSet ds = do+ set <- inflateIntegral $+ {#get SpvReflectDescriptorSet->set #} ds++ bindingsPtr <- {#get SpvReflectDescriptorSet->bindings #} ds+ bindings <-+ inflateVector+ ({#get SpvReflectDescriptorSet->binding_count #} ds)+ (peek bindingsPtr)+ {#sizeof SpvReflectDescriptorBinding #}+ inflateDescriptorBinding++ pure DescriptorSet.DescriptorSet{..}++{#pointer *SpvReflectInterfaceVariable as InterfaceVariablePtr #}++inflateInterfaceVariable :: InterfaceVariablePtr -> IO InterfaceVariable+inflateInterfaceVariable iv = do+ spirv_id <- fmap Just . inflateIntegral $+ {#get SpvReflectInterfaceVariable->spirv_id #} iv++ name <- fmap Just . inflateText $+ {#get SpvReflectInterfaceVariable->name #} iv++ location <- inflateIntegral $+ {#get SpvReflectInterfaceVariable->location #} iv++ storage_class <- inflateEnum $+ {#get SpvReflectInterfaceVariable->storage_class #} iv++ semantic <- fmap Just . inflateText $+ {#get SpvReflectInterfaceVariable->semantic #} iv++ decoration_flags <- inflateFlags32 $+ {#get SpvReflectInterfaceVariable->decoration_flags #} iv++ built_in <- inflateEnum $+ {#get SpvReflectInterfaceVariable->built_in #} iv++ numeric <-+ inflateNumericTraits+ iv+ {#offsetof SpvReflectInterfaceVariable->numeric #}++ array <-+ inflateArrayTraits+ iv+ {#offsetof SpvReflectInterfaceVariable->array #}++ members <-+ inflateVector+ ({#get SpvReflectInterfaceVariable->member_count #} iv)+ ({#get SpvReflectInterfaceVariable->members #} iv)+ {#sizeof SpvReflectInterfaceVariable #}+ inflateInterfaceVariable++ format <- inflateEnum $+ {#get SpvReflectInterfaceVariable->format #} iv++ type_description <-+ {#get SpvReflectInterfaceVariable->type_description #} iv >>=+ maybePeek inflateTypeDescription++ wo_location <- inflateIntegral $+ {#get SpvReflectInterfaceVariable->word_offset.location #} iv+ let word_offset = InterfaceVariable.WordOffset{location=wo_location}++ pure InterfaceVariable.InterfaceVariable{..}++-- * Traits++{#pointer *SpvReflectImageTraits as ImageTraitsPtr #}++inflateImageTraits :: Ptr struct -> Int -> IO Traits.Image+inflateImageTraits src offset = do+ let it = castPtr src `plusPtr` offset++ dim <- inflateEnum $+ {#get SpvReflectImageTraits->dim #} it++ depth <- inflateIntegral $+ {#get SpvReflectImageTraits->depth #} it++ arrayed <- inflateIntegral $+ {#get SpvReflectImageTraits->arrayed #} it++ ms <- inflateIntegral $+ {#get SpvReflectImageTraits->ms #} it++ sampled <- inflateIntegral $+ {#get SpvReflectImageTraits->sampled #} it++ image_format <- inflateEnum $+ {#get SpvReflectImageTraits->image_format #} it++ pure Traits.Image{..}++{#pointer *SpvReflectNumericTraits as NumericTraitsPtr #}++inflateNumericTraits :: Ptr struct -> Int -> IO Traits.Numeric+inflateNumericTraits src offset = do+ let nt = castPtr src `plusPtr` offset++ width <- inflateIntegral $+ {#get SpvReflectNumericTraits.scalar.width #} nt+ signedness <- inflateIntegral $+ {#get SpvReflectNumericTraits.scalar.signedness #} nt+ let scalar = Traits.Scalar{..}++ component_count <- inflateIntegral $+ {#get SpvReflectNumericTraits->vector.component_count #} nt+ let vector = Traits.Vector{..}++ column_count <- inflateIntegral $+ {#get SpvReflectNumericTraits->matrix.column_count #} nt+ row_count <- inflateIntegral $+ {#get SpvReflectNumericTraits->matrix.row_count #} nt+ stride <- inflateIntegral $+ {#get SpvReflectNumericTraits->matrix.stride #} nt+ let matrix = Traits.Matrix{..}++ pure Traits.Numeric{..}++{#pointer *SpvReflectArrayTraits as ArrayTraitsPtr #}++inflateArrayTraits :: Ptr struct -> Int -> IO Traits.Array+inflateArrayTraits src offset = do+ let at = castPtr src `plusPtr` offset++ dims_count <- inflateIntegral $+ {#get SpvReflectArrayTraits->dims_count #} at++ dims <- fmap Vector.convert $ inflateVector+ ({#get SpvReflectArrayTraits->dims_count #} at)+ ({#get SpvReflectArrayTraits->dims #} at)+ {#sizeof uint32_t #}+ (fmap fromIntegral . peek)++ stride <- fmap Just . inflateIntegral $+ {#get SpvReflectArrayTraits->stride #} at++ pure Traits.Array{..}++-- * Atomic types++inflateIntegral :: (Integral a, Num b) => IO a -> IO b+inflateIntegral getIntegral =+ getIntegral >>=+ pure . fromIntegral++inflateEnum :: (Integral a, Enum b) => IO a -> IO b+inflateEnum getEnum =+ getEnum >>=+ pure . toEnum . fromIntegral++inflateFlags32 :: forall a b . (Integral a, Coercible Word32 b) => IO a -> IO b+inflateFlags32 gitBits =+ gitBits >>=+ pure . coerce @Word32 @b . fromIntegral++inflateText :: IO CString -> IO Text+inflateText getPtr =+ getPtr >>= \ptr ->+ if nullPtr == ptr then+ pure mempty+ else+ case ptr of+ GHC.Ptr addr ->+ pure $! Text.unpackCString# addr
+ spirv-reflect-ffi.cabal view
@@ -0,0 +1,99 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.34.4.+--+-- see: https://github.com/sol/hpack++name: spirv-reflect-ffi+version: 0.1+synopsis: C-library loader for spirv-reflect tool.+category: Graphics+author: IC Rainbow+maintainer: ic.rbow@gmail.com+copyright: 2022 IC Rainbow+license: BSD3+license-file: LICENSE+build-type: Simple+extra-source-files:+ cbits/include/spirv/unified1/spirv.h+ cbits/spirv_reflect.c+ cbits/spirv_reflect.h+ ChangeLog.md++source-repository head+ type: git+ location: https://gitlab.com/dpwiz/spirv-reflect++flag tests+ manual: True+ default: False++library+ exposed-modules:+ Data.SpirV.Reflect.FFI+ Data.SpirV.Reflect.FFI.Internal+ other-modules:+ Paths_spirv_reflect_ffi+ hs-source-dirs:+ lib+ default-extensions:+ ApplicativeDo+ BlockArguments+ DeriveGeneric+ DerivingStrategies+ DuplicateRecordFields+ FlexibleContexts+ GeneralizedNewtypeDeriving+ ImportQualifiedPost+ LambdaCase+ OverloadedStrings+ PatternSynonyms+ RecordWildCards+ StrictData+ TypeApplications+ include-dirs:+ cbits+ c-sources:+ cbits/spirv_reflect.c+ build-tools:+ c2hs+ build-depends:+ base >=4.7 && <5+ , bytestring+ , spirv-reflect-types >=0.2+ , text+ , vector+ default-language: Haskell2010++test-suite spirv-reflect-yaml-test+ type: exitcode-stdio-1.0+ main-is: Main.hs+ other-modules:+ Paths_spirv_reflect_ffi+ hs-source-dirs:+ test+ default-extensions:+ ApplicativeDo+ BlockArguments+ DeriveGeneric+ DerivingStrategies+ DuplicateRecordFields+ FlexibleContexts+ GeneralizedNewtypeDeriving+ ImportQualifiedPost+ LambdaCase+ OverloadedStrings+ PatternSynonyms+ RecordWildCards+ StrictData+ TypeApplications+ build-depends:+ base >=4.7 && <5+ , directory+ , filepath+ , spirv-reflect-ffi+ , tasty+ , tasty-hunit+ if !flag(tests)+ buildable: False+ default-language: Haskell2010
+ test/Main.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE BangPatterns #-}++module Main where++import Control.Monad (guard)+import System.Directory (doesDirectoryExist, listDirectory)+import System.FilePath (splitExtensions, takeFileName, (</>))+import Test.Tasty (TestTree, defaultMain, testGroup)+import Test.Tasty.HUnit (testCase)++import Data.SpirV.Reflect.FFI qualified as FFI++main :: IO ()+main = discover >>= defaultMain++discover :: IO TestTree+discover = do+ groupDirs <- listDirectory UPSTREAM_PATH >>= traverse \path -> do+ let groupPath = UPSTREAM_PATH </> path+ isDir <- doesDirectoryExist groupPath+ if not isDir then+ pure mempty+ else do+ groupContents <- listDirectory groupPath+ let+ files = do+ filePath <- groupContents+ case splitExtensions filePath of+ (name, ".spv") ->+ pure+ ( takeFileName name+ , groupPath </> filePath+ )+ _skip ->+ mempty+ pure (path, files)++ let+ groups = do+ (name, yamls) <- groupDirs+ guard $ not (null yamls)+ pure $ testGroup name (map mkTest yamls)++ pure $ testGroup "upstream" groups++mkTest :: (String, FilePath) -> TestTree+mkTest (name, file) =+ testCase name do+ -- putStrLn $ file <> " >>>>"+ !_loaded <- FFI.load file+ pure ()+ -- print loaded+ -- putStrLn $ file <> " <<<<"++pattern UPSTREAM_PATH :: FilePath+pattern UPSTREAM_PATH = "../SPIRV-Reflect/tests/"