diff --git a/WickedEngine/CommonInclude.h b/WickedEngine/CommonInclude.h index df44338f9..3a5e03623 100644 --- a/WickedEngine/CommonInclude.h +++ b/WickedEngine/CommonInclude.h @@ -115,12 +115,15 @@ struct StackVector constexpr void push_back(T&& item) { items[last++] = static_cast(item); } constexpr void pop_back() { if (!empty()) items[--last] = {}; } constexpr void clear() { for (unsigned i = 0; i < count; ++i) items[i] = {}; last = 0; } + constexpr T* data() { return items; } + constexpr const T* data() const { return items; } constexpr T* begin() { return items; } constexpr T* end() { return items + last; } constexpr const T& back() const { return items[last - 1]; } - constexpr T& back() { return items[0]; } - constexpr const T& front() const { return items[last - 1]; } + constexpr T& back() { return items[last - 1]; } + constexpr const T& front() const { return items[0]; } constexpr T& front() { return items[0]; } + constexpr T& emplace_back() { push_back({}); return back(); } constexpr const T& operator[](unsigned index) const { return items[index]; } constexpr T& operator[](unsigned index) { return items[index]; } }; diff --git a/WickedEngine/Utility/include/spirv/unified1/spirv.h b/WickedEngine/Utility/include/spirv/unified1/spirv.h deleted file mode 100644 index 65becfd76..000000000 --- a/WickedEngine/Utility/include/spirv/unified1/spirv.h +++ /dev/null @@ -1,4890 +0,0 @@ -/* -** 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, Beef -** -** - 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 -** - Beef will use enum classes in the Specification class located in the "Spv" -*namespace, -** e.g.: Spv.Specification.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, - SpvSourceLanguageHERO_C = 8, - SpvSourceLanguageNZSL = 9, - 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, - SpvExecutionModelTaskEXT = 5364, - SpvExecutionModelMeshEXT = 5365, - 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, - SpvExecutionModeNonCoherentColorAttachmentReadEXT = 4169, - SpvExecutionModeNonCoherentDepthAttachmentReadEXT = 4170, - SpvExecutionModeNonCoherentStencilAttachmentReadEXT = 4171, - SpvExecutionModeSubgroupUniformControlFlowKHR = 4421, - SpvExecutionModePostDepthCoverage = 4446, - SpvExecutionModeDenormPreserve = 4459, - SpvExecutionModeDenormFlushToZero = 4460, - SpvExecutionModeSignedZeroInfNanPreserve = 4461, - SpvExecutionModeRoundingModeRTE = 4462, - SpvExecutionModeRoundingModeRTZ = 4463, - SpvExecutionModeEarlyAndLateFragmentTestsAMD = 5017, - SpvExecutionModeStencilRefReplacingEXT = 5027, - SpvExecutionModeStencilRefUnchangedFrontAMD = 5079, - SpvExecutionModeStencilRefGreaterFrontAMD = 5080, - SpvExecutionModeStencilRefLessFrontAMD = 5081, - SpvExecutionModeStencilRefUnchangedBackAMD = 5082, - SpvExecutionModeStencilRefGreaterBackAMD = 5083, - SpvExecutionModeStencilRefLessBackAMD = 5084, - SpvExecutionModeOutputLinesEXT = 5269, - SpvExecutionModeOutputLinesNV = 5269, - SpvExecutionModeOutputPrimitivesEXT = 5270, - SpvExecutionModeOutputPrimitivesNV = 5270, - SpvExecutionModeDerivativeGroupQuadsNV = 5289, - SpvExecutionModeDerivativeGroupLinearNV = 5290, - SpvExecutionModeOutputTrianglesEXT = 5298, - 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, - SpvExecutionModeStreamingInterfaceINTEL = 6154, - SpvExecutionModeRegisterMapInterfaceINTEL = 6160, - 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, - SpvStorageClassTileImageEXT = 4172, - 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, - SpvStorageClassHitObjectAttributeNV = 5385, - SpvStorageClassTaskPayloadWorkgroupEXT = 5402, - 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, - SpvDimTileImageDataEXT = 4173, - 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, - SpvImageChannelDataTypeUnsignedIntRaw10EXT = 19, - SpvImageChannelDataTypeUnsignedIntRaw12EXT = 20, - 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, - SpvFunctionParameterAttributeRuntimeAlignedINTEL = 5940, - 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, - SpvDecorationWeightTextureQCOM = 4487, - SpvDecorationBlockMatchTextureQCOM = 4488, - SpvDecorationExplicitInterpAMD = 4999, - SpvDecorationOverrideCoverageNV = 5248, - SpvDecorationPassthroughNV = 5250, - SpvDecorationViewportRelativeNV = 5252, - SpvDecorationSecondaryViewportRelativeNV = 5256, - SpvDecorationPerPrimitiveEXT = 5271, - SpvDecorationPerPrimitiveNV = 5271, - SpvDecorationPerViewNV = 5272, - SpvDecorationPerTaskNV = 5273, - SpvDecorationPerVertexKHR = 5285, - SpvDecorationPerVertexNV = 5285, - SpvDecorationNonUniform = 5300, - SpvDecorationNonUniformEXT = 5300, - SpvDecorationRestrictPointer = 5355, - SpvDecorationRestrictPointerEXT = 5355, - SpvDecorationAliasedPointer = 5356, - SpvDecorationAliasedPointerEXT = 5356, - SpvDecorationHitObjectShaderRecordBufferNV = 5386, - 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, - SpvDecorationMathOpDSPModeINTEL = 5909, - SpvDecorationAliasScopeINTEL = 5914, - SpvDecorationNoAliasINTEL = 5915, - SpvDecorationInitiationIntervalINTEL = 5917, - SpvDecorationMaxConcurrencyINTEL = 5918, - SpvDecorationPipelineEnableINTEL = 5919, - SpvDecorationBufferLocationINTEL = 5921, - SpvDecorationIOPipeStorageINTEL = 5944, - SpvDecorationFunctionFloatingPointModeINTEL = 6080, - SpvDecorationSingleElementVectorINTEL = 6085, - SpvDecorationVectorComputeCallableFunctionINTEL = 6087, - SpvDecorationMediaBlockIOINTEL = 6140, - SpvDecorationLatencyControlLabelINTEL = 6172, - SpvDecorationLatencyControlConstraintINTEL = 6173, - SpvDecorationConduitKernelArgumentINTEL = 6175, - SpvDecorationRegisterMapKernelArgumentINTEL = 6176, - SpvDecorationMMHostInterfaceAddressWidthINTEL = 6177, - SpvDecorationMMHostInterfaceDataWidthINTEL = 6178, - SpvDecorationMMHostInterfaceLatencyINTEL = 6179, - SpvDecorationMMHostInterfaceReadWriteModeINTEL = 6180, - SpvDecorationMMHostInterfaceMaxBurstINTEL = 6181, - SpvDecorationMMHostInterfaceWaitRequestINTEL = 6182, - SpvDecorationStableKernelArgumentINTEL = 6183, - 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, - SpvBuiltInCoreIDARM = 4160, - SpvBuiltInCoreCountARM = 4161, - SpvBuiltInCoreMaxIDARM = 4162, - SpvBuiltInWarpIDARM = 4163, - SpvBuiltInWarpMaxIDARM = 4164, - 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, - SpvBuiltInPrimitivePointIndicesEXT = 5294, - SpvBuiltInPrimitiveLineIndicesEXT = 5295, - SpvBuiltInPrimitiveTriangleIndicesEXT = 5296, - SpvBuiltInCullPrimitiveEXT = 5299, - 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, - SpvBuiltInHitTriangleVertexPositionsKHR = 5335, - 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, - SpvLoopControlLoopCountINTELShift = 24, - SpvLoopControlMaxReinvocationDelayINTELShift = 25, - 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, - SpvLoopControlLoopCountINTELMask = 0x01000000, - SpvLoopControlMaxReinvocationDelayINTELMask = 0x02000000, -} 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, - SpvCapabilityCoreBuiltinsARM = 4165, - SpvCapabilityTileImageColorReadAccessEXT = 4166, - SpvCapabilityTileImageDepthReadAccessEXT = 4167, - SpvCapabilityTileImageStencilReadAccessEXT = 4168, - 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, - SpvCapabilityTextureSampleWeightedQCOM = 4484, - SpvCapabilityTextureBoxFilterQCOM = 4485, - SpvCapabilityTextureBlockMatchQCOM = 4486, - 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, - SpvCapabilityMeshShadingEXT = 5283, - 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, - SpvCapabilityRayTracingPositionFetchKHR = 5336, - 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, - SpvCapabilityRayTracingOpacityMicromapEXT = 5381, - SpvCapabilityShaderInvocationReorderNV = 5383, - SpvCapabilityBindlessTextureNV = 5390, - SpvCapabilityRayQueryPositionFetchKHR = 5391, - 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, - SpvCapabilityFPGADSPControlINTEL = 5908, - SpvCapabilityMemoryAccessAliasingINTEL = 5910, - SpvCapabilityFPGAInvocationPipeliningAttributesINTEL = 5916, - SpvCapabilityFPGABufferLocationINTEL = 5920, - SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922, - SpvCapabilityUSMStorageClassesINTEL = 5935, - SpvCapabilityRuntimeAlignedAttributeINTEL = 5939, - SpvCapabilityIOPipesINTEL = 5943, - SpvCapabilityBlockingPipesINTEL = 5945, - SpvCapabilityFPGARegINTEL = 5948, - SpvCapabilityDotProductInputAll = 6016, - SpvCapabilityDotProductInputAllKHR = 6016, - SpvCapabilityDotProductInput4x8Bit = 6017, - SpvCapabilityDotProductInput4x8BitKHR = 6017, - SpvCapabilityDotProductInput4x8BitPacked = 6018, - SpvCapabilityDotProductInput4x8BitPackedKHR = 6018, - SpvCapabilityDotProduct = 6019, - SpvCapabilityDotProductKHR = 6019, - SpvCapabilityRayCullMaskKHR = 6020, - SpvCapabilityCooperativeMatrixKHR = 6022, - SpvCapabilityBitInstructions = 6025, - SpvCapabilityGroupNonUniformRotateKHR = 6026, - SpvCapabilityAtomicFloat32AddEXT = 6033, - SpvCapabilityAtomicFloat64AddEXT = 6034, - SpvCapabilityLongConstantCompositeINTEL = 6089, - SpvCapabilityOptNoneINTEL = 6094, - SpvCapabilityAtomicFloat16AddEXT = 6095, - SpvCapabilityDebugInfoModuleINTEL = 6114, - SpvCapabilityBFloat16ConversionINTEL = 6115, - SpvCapabilitySplitBarrierINTEL = 6141, - SpvCapabilityFPGAKernelAttributesv2INTEL = 6161, - SpvCapabilityFPGALatencyControlINTEL = 6171, - SpvCapabilityFPGAArgumentInterfacesINTEL = 6174, - 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, - SpvRayFlagsForceOpacityMicromap2StateEXTShift = 10, - 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, - SpvRayFlagsForceOpacityMicromap2StateEXTMask = 0x00000400, -} 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 SpvCooperativeMatrixOperandsShift_ { - SpvCooperativeMatrixOperandsMatrixASignedComponentsShift = 0, - SpvCooperativeMatrixOperandsMatrixBSignedComponentsShift = 1, - SpvCooperativeMatrixOperandsMatrixCSignedComponentsShift = 2, - SpvCooperativeMatrixOperandsMatrixResultSignedComponentsShift = 3, - SpvCooperativeMatrixOperandsSaturatingAccumulationShift = 4, - SpvCooperativeMatrixOperandsMax = 0x7fffffff, -} SpvCooperativeMatrixOperandsShift; - -typedef enum SpvCooperativeMatrixOperandsMask_ { - SpvCooperativeMatrixOperandsMaskNone = 0, - SpvCooperativeMatrixOperandsMatrixASignedComponentsMask = 0x00000001, - SpvCooperativeMatrixOperandsMatrixBSignedComponentsMask = 0x00000002, - SpvCooperativeMatrixOperandsMatrixCSignedComponentsMask = 0x00000004, - SpvCooperativeMatrixOperandsMatrixResultSignedComponentsMask = 0x00000008, - SpvCooperativeMatrixOperandsSaturatingAccumulationMask = 0x00000010, -} SpvCooperativeMatrixOperandsMask; - -typedef enum SpvCooperativeMatrixLayout_ { - SpvCooperativeMatrixLayoutRowMajorKHR = 0, - SpvCooperativeMatrixLayoutColumnMajorKHR = 1, - SpvCooperativeMatrixLayoutMax = 0x7fffffff, -} SpvCooperativeMatrixLayout; - -typedef enum SpvCooperativeMatrixUse_ { - SpvCooperativeMatrixUseMatrixAKHR = 0, - SpvCooperativeMatrixUseMatrixBKHR = 1, - SpvCooperativeMatrixUseMatrixAccumulatorKHR = 2, - SpvCooperativeMatrixUseMax = 0x7fffffff, -} SpvCooperativeMatrixUse; - -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, - SpvOpColorAttachmentReadEXT = 4160, - SpvOpDepthAttachmentReadEXT = 4161, - SpvOpStencilAttachmentReadEXT = 4162, - 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, - SpvOpTypeCooperativeMatrixKHR = 4456, - SpvOpCooperativeMatrixLoadKHR = 4457, - SpvOpCooperativeMatrixStoreKHR = 4458, - SpvOpCooperativeMatrixMulAddKHR = 4459, - SpvOpCooperativeMatrixLengthKHR = 4460, - SpvOpTypeRayQueryKHR = 4472, - SpvOpRayQueryInitializeKHR = 4473, - SpvOpRayQueryTerminateKHR = 4474, - SpvOpRayQueryGenerateIntersectionKHR = 4475, - SpvOpRayQueryConfirmIntersectionKHR = 4476, - SpvOpRayQueryProceedKHR = 4477, - SpvOpRayQueryGetIntersectionTypeKHR = 4479, - SpvOpImageSampleWeightedQCOM = 4480, - SpvOpImageBoxFilterQCOM = 4481, - SpvOpImageBlockMatchSSDQCOM = 4482, - SpvOpImageBlockMatchSADQCOM = 4483, - SpvOpGroupIAddNonUniformAMD = 5000, - SpvOpGroupFAddNonUniformAMD = 5001, - SpvOpGroupFMinNonUniformAMD = 5002, - SpvOpGroupUMinNonUniformAMD = 5003, - SpvOpGroupSMinNonUniformAMD = 5004, - SpvOpGroupFMaxNonUniformAMD = 5005, - SpvOpGroupUMaxNonUniformAMD = 5006, - SpvOpGroupSMaxNonUniformAMD = 5007, - SpvOpFragmentMaskFetchAMD = 5011, - SpvOpFragmentFetchAMD = 5012, - SpvOpReadClockKHR = 5056, - SpvOpHitObjectRecordHitMotionNV = 5249, - SpvOpHitObjectRecordHitWithIndexMotionNV = 5250, - SpvOpHitObjectRecordMissMotionNV = 5251, - SpvOpHitObjectGetWorldToObjectNV = 5252, - SpvOpHitObjectGetObjectToWorldNV = 5253, - SpvOpHitObjectGetObjectRayDirectionNV = 5254, - SpvOpHitObjectGetObjectRayOriginNV = 5255, - SpvOpHitObjectTraceRayMotionNV = 5256, - SpvOpHitObjectGetShaderRecordBufferHandleNV = 5257, - SpvOpHitObjectGetShaderBindingTableRecordIndexNV = 5258, - SpvOpHitObjectRecordEmptyNV = 5259, - SpvOpHitObjectTraceRayNV = 5260, - SpvOpHitObjectRecordHitNV = 5261, - SpvOpHitObjectRecordHitWithIndexNV = 5262, - SpvOpHitObjectRecordMissNV = 5263, - SpvOpHitObjectExecuteShaderNV = 5264, - SpvOpHitObjectGetCurrentTimeNV = 5265, - SpvOpHitObjectGetAttributesNV = 5266, - SpvOpHitObjectGetHitKindNV = 5267, - SpvOpHitObjectGetPrimitiveIndexNV = 5268, - SpvOpHitObjectGetGeometryIndexNV = 5269, - SpvOpHitObjectGetInstanceIdNV = 5270, - SpvOpHitObjectGetInstanceCustomIndexNV = 5271, - SpvOpHitObjectGetWorldRayDirectionNV = 5272, - SpvOpHitObjectGetWorldRayOriginNV = 5273, - SpvOpHitObjectGetRayTMaxNV = 5274, - SpvOpHitObjectGetRayTMinNV = 5275, - SpvOpHitObjectIsEmptyNV = 5276, - SpvOpHitObjectIsHitNV = 5277, - SpvOpHitObjectIsMissNV = 5278, - SpvOpReorderThreadWithHitObjectNV = 5279, - SpvOpReorderThreadWithHintNV = 5280, - SpvOpTypeHitObjectNV = 5281, - SpvOpImageSampleFootprintNV = 5283, - SpvOpEmitMeshTasksEXT = 5294, - SpvOpSetMeshOutputsEXT = 5295, - SpvOpGroupNonUniformPartitionNV = 5296, - SpvOpWritePackedPrimitiveIndices4x8NV = 5299, - SpvOpReportIntersectionKHR = 5334, - SpvOpReportIntersectionNV = 5334, - SpvOpIgnoreIntersectionNV = 5335, - SpvOpTerminateRayNV = 5336, - SpvOpTraceNV = 5337, - SpvOpTraceMotionNV = 5338, - SpvOpTraceRayMotionNV = 5339, - SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, - 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, - SpvOpConvertFToBF16INTEL = 6116, - SpvOpConvertBF16ToFINTEL = 6117, - 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 -#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 SpvOpColorAttachmentReadEXT: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpDepthAttachmentReadEXT: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpStencilAttachmentReadEXT: - *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 SpvOpTypeCooperativeMatrixKHR: - *hasResult = true; - *hasResultType = false; - break; - case SpvOpCooperativeMatrixLoadKHR: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpCooperativeMatrixStoreKHR: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpCooperativeMatrixMulAddKHR: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpCooperativeMatrixLengthKHR: - *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 SpvOpImageSampleWeightedQCOM: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpImageBoxFilterQCOM: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpImageBlockMatchSSDQCOM: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpImageBlockMatchSADQCOM: - *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 SpvOpHitObjectRecordHitMotionNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectRecordHitWithIndexMotionNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectRecordMissMotionNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectGetWorldToObjectNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetObjectToWorldNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetObjectRayDirectionNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetObjectRayOriginNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectTraceRayMotionNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectGetShaderRecordBufferHandleNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetShaderBindingTableRecordIndexNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectRecordEmptyNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectTraceRayNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectRecordHitNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectRecordHitWithIndexNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectRecordMissNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectExecuteShaderNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectGetCurrentTimeNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetAttributesNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpHitObjectGetHitKindNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetPrimitiveIndexNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetGeometryIndexNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetInstanceIdNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetInstanceCustomIndexNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetWorldRayDirectionNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetWorldRayOriginNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetRayTMaxNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectGetRayTMinNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectIsEmptyNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectIsHitNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpHitObjectIsMissNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpReorderThreadWithHitObjectNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpReorderThreadWithHintNV: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpTypeHitObjectNV: - *hasResult = true; - *hasResultType = false; - break; - case SpvOpImageSampleFootprintNV: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpEmitMeshTasksEXT: - *hasResult = false; - *hasResultType = false; - break; - case SpvOpSetMeshOutputsEXT: - *hasResult = false; - *hasResultType = false; - 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 SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR: - *hasResult = true; - *hasResultType = true; - 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 SpvOpConvertFToBF16INTEL: - *hasResult = true; - *hasResultType = true; - break; - case SpvOpConvertBF16ToFINTEL: - *hasResult = true; - *hasResultType = true; - 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 diff --git a/WickedEngine/Utility/spirv_reflect.c b/WickedEngine/Utility/spirv_reflect.c deleted file mode 100644 index 50986b52d..000000000 --- a/WickedEngine/Utility/spirv_reflect.c +++ /dev/null @@ -1,5491 +0,0 @@ -/* - 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 -#include -#include - -#if defined(WIN32) -#define _CRTDBG_MAP_ALLOC -#include -#include -#else -#include -#endif - -#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 7) || defined(__APPLE_CC__) -#define FALLTHROUGH __attribute__((fallthrough)) -#else -#define FALLTHROUGH -#endif - -#if defined(SPIRV_REFLECT_ENABLE_ASSERTS) -#define SPV_REFLECT_ASSERT(COND) assert(COND); -#else -#define SPV_REFLECT_ASSERT(COND) -#endif - -// 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, - SPIRV_PHYSICAL_STORAGE_POINTER_SIZE = 8, // Pointers are defined as 64-bit -}; - -enum { - INVALID_VALUE = 0xFFFFFFFF, -}; - -enum { - MAX_NODE_NAME_LENGTH = 1024, - // Number of unique PhysicalStorageBuffer structs tracked to detect recursion - MAX_RECURSIVE_PHYSICAL_POINTER_CHECK = 128, -}; - -enum { - IMAGE_SAMPLED = 1, - IMAGE_STORAGE = 2, -}; - -typedef struct SpvReflectPrvArrayTraits { - uint32_t element_type_id; - uint32_t length_id; -} SpvReflectPrvArrayTraits; - -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; - -typedef struct SpvReflectPrvNumberDecoration { - uint32_t word_offset; - uint32_t value; -} SpvReflectPrvNumberDecoration; - -typedef struct SpvReflectPrvStringDecoration { - uint32_t word_offset; - const char* value; -} SpvReflectPrvStringDecoration; - -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; - bool is_patch; - bool is_per_vertex; - bool is_per_task; - bool is_weight_texture; - bool is_block_match_texture; - SpvReflectUserType user_type; - SpvReflectPrvNumberDecoration set; - SpvReflectPrvNumberDecoration binding; - SpvReflectPrvNumberDecoration input_attachment_index; - SpvReflectPrvNumberDecoration location; - SpvReflectPrvNumberDecoration component; - SpvReflectPrvNumberDecoration offset; - SpvReflectPrvNumberDecoration uav_counter_buffer; - SpvReflectPrvStringDecoration semantic; - uint32_t array_stride; - uint32_t matrix_stride; - uint32_t spec_id; - SpvBuiltIn built_in; -} SpvReflectPrvDecorations; - -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; - -typedef struct SpvReflectPrvString { - uint32_t result_id; - const char* string; -} SpvReflectPrvString; - -// There are a limit set of instructions that can touch an OpVariable, -// these are represented here with how it was accessed -// Examples: -// OpImageRead -> OpLoad -> OpVariable -// OpImageWrite -> OpLoad -> OpVariable -// OpStore -> OpAccessChain -> OpAccessChain -> OpVariable -// OpAtomicIAdd -> OpAccessChain -> OpVariable -// OpAtomicLoad -> OpImageTexelPointer -> OpVariable -typedef struct SpvReflectPrvAccessedVariable { - SpvReflectPrvNode* p_node; - uint32_t result_id; - uint32_t variable_ptr; - uint32_t function_id; - uint32_t function_parameter_index; -} SpvReflectPrvAccessedVariable; - -typedef struct SpvReflectPrvFunction { - uint32_t id; - uint32_t parameter_count; - uint32_t* parameters; - uint32_t callee_count; - uint32_t* callees; - struct SpvReflectPrvFunction** callee_ptrs; - uint32_t accessed_variable_count; - SpvReflectPrvAccessedVariable* accessed_variables; -} SpvReflectPrvFunction; - -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; - // - // Block variable ac is pointing to (for block references) - SpvReflectBlockVariable* block_var; -} SpvReflectPrvAccessChain; - -// To prevent infinite recursion, we never walk down a -// PhysicalStorageBuffer struct twice, but incase a 2nd variable -// needs to use that struct, save a copy -typedef struct SpvReflectPrvPhysicalPointerStruct { - uint32_t struct_id; - // first variable to see the PhysicalStorageBuffer struct - SpvReflectBlockVariable* p_var; -} SpvReflectPrvPhysicalPointerStruct; - -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; - - SpvReflectTypeDescription* physical_pointer_check[MAX_RECURSIVE_PHYSICAL_POINTER_CHECK]; - uint32_t physical_pointer_count; - - SpvReflectPrvPhysicalPointerStruct* physical_pointer_structs; - uint32_t physical_pointer_struct_count; -} SpvReflectPrvParser; -// clang-format on - -static uint32_t Max(uint32_t a, uint32_t b) { return a > b ? a : b; } -static uint32_t Min(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; -} - -static int SortCompareAccessedVariable(const void* a, const void* b) { - const SpvReflectPrvAccessedVariable* p_a = (const SpvReflectPrvAccessedVariable*)a; - const SpvReflectPrvAccessedVariable* p_b = (const SpvReflectPrvAccessedVariable*)b; - - return (int)p_a->variable_ptr - (int)p_b->variable_ptr; -} - -// -// 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 IntersectSortedAccessedVariable(const SpvReflectPrvAccessedVariable* 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 SpvReflectPrvAccessedVariable* p_arr0_end = p_arr0 + arr0_size; - const uint32_t* p_arr1_end = p_arr1 + arr1_size; - - const SpvReflectPrvAccessedVariable* p_idx0 = p_arr0; - const uint32_t* p_idx1 = p_arr1; - while (p_idx0 != p_arr0_end && p_idx1 != p_arr1_end) { - if (p_idx0->variable_ptr < *p_idx1) { - ++p_idx0; - } else if (p_idx0->variable_ptr > *p_idx1) { - ++p_idx1; - } else { - ++*res_size; - ++p_idx0; - ++p_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* p_idxr = *pp_res; - p_idx0 = p_arr0; - p_idx1 = p_arr1; - while (p_idx0 != p_arr0_end && p_idx1 != p_arr1_end) { - if (p_idx0->variable_ptr < *p_idx1) { - ++p_idx0; - } else if (p_idx0->variable_ptr > *p_idx1) { - ++p_idx1; - } else { - *(p_idxr++) = p_idx0->variable_ptr; - ++p_idx0; - ++p_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 UNCHECKED_READU32(parser, word_offset, value) \ - { (void)ReadU32(parser, word_offset, (uint32_t*)&(value)); } - -#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; - } - if (p_decoration_fields->is_patch) { - decorations |= SPV_REFLECT_DECORATION_PATCH; - } - if (p_decoration_fields->is_per_vertex) { - decorations |= SPV_REFLECT_DECORATION_PER_VERTEX; - } - if (p_decoration_fields->is_per_task) { - decorations |= SPV_REFLECT_DECORATION_PER_TASK; - } - if (p_decoration_fields->is_weight_texture) { - decorations |= SPV_REFLECT_DECORATION_WEIGHT_TEXTURE; - } - if (p_decoration_fields->is_block_match_texture) { - decorations |= SPV_REFLECT_DECORATION_BLOCK_MATCH_TEXTURE; - } - 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 bool IsSpecConstant(const SpvReflectPrvNode* p_node) { - return (p_node->op == SpvOpSpecConstant || p_node->op == SpvOpSpecConstantOp || p_node->op == SpvOpSpecConstantTrue || - p_node->op == SpvOpSpecConstantFalse); -} - -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 SpvReflectPrvAccessChain* FindAccessChain(SpvReflectPrvParser* p_parser, uint32_t id) { - const uint32_t ac_count = p_parser->access_chain_count; - for (uint32_t i = 0; i < ac_count; i++) { - if (p_parser->access_chains[i].result_id == id) { - return &p_parser->access_chains[i]; - } - } - return 0; -} - -// Access Chains mostly have their Base ID pointed directly to a OpVariable, but sometimes -// it will be through a load and this funciton handles the edge cases how to find that -static uint32_t FindAccessChainBaseVariable(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* p_access_chain) { - uint32_t base_id = p_access_chain->base_id; - SpvReflectPrvNode* base_node = FindNode(p_parser, base_id); - // TODO - This is just a band-aid to fix crashes. - // Need to understand why here and hopefully remove - // https://github.com/KhronosGroup/SPIRV-Reflect/pull/206 - if (IsNull(base_node)) { - return 0; - } - while (base_node->op != SpvOpVariable) { - switch (base_node->op) { - case SpvOpLoad: { - UNCHECKED_READU32(p_parser, base_node->word_offset + 3, base_id); - } break; - case SpvOpFunctionParameter: { - UNCHECKED_READU32(p_parser, base_node->word_offset + 2, base_id); - } break; - case SpvOpBitcast: - // This can be caused by something like GL_EXT_buffer_reference_uvec2 trying to load a pointer. - // We currently call from a push constant, so no way to have a reference loop back into the PC block - return 0; - default: { - assert(false); - } break; - } - - SpvReflectPrvAccessChain* base_ac = FindAccessChain(p_parser, base_id); - if (base_ac == 0) { - return 0; - } - base_id = base_ac->base_id; - base_node = FindNode(p_parser, base_id); - if (IsNull(base_node)) { - return 0; - } - } - return base_id; -} - -static SpvReflectBlockVariable* GetRefBlkVar(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* p_access_chain) { - uint32_t base_id = p_access_chain->base_id; - SpvReflectPrvNode* base_node = FindNode(p_parser, base_id); - assert(base_node->op == SpvOpLoad); - UNCHECKED_READU32(p_parser, base_node->word_offset + 3, base_id); - SpvReflectPrvAccessChain* base_ac = FindAccessChain(p_parser, base_id); - assert(base_ac != 0); - SpvReflectBlockVariable* base_var = base_ac->block_var; - assert(base_var != 0); - return base_var; -} - -bool IsPointerToPointer(SpvReflectPrvParser* p_parser, uint32_t type_id) { - SpvReflectPrvNode* ptr_node = FindNode(p_parser, type_id); - if (IsNull(ptr_node) || (ptr_node->op != SpvOpTypePointer)) { - return false; - } - uint32_t pte_id = 0; - UNCHECKED_READU32(p_parser, ptr_node->word_offset + 3, pte_id); - SpvReflectPrvNode* pte_node = FindNode(p_parser, pte_id); - if (IsNull(pte_node)) { - return false; - } - return pte_node->op == SpvOpTypePointer; -} - -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].parameters); - SafeFree(p_parser->functions[i].callees); - SafeFree(p_parser->functions[i].callee_ptrs); - SafeFree(p_parser->functions[i].accessed_variables); - } - - // 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); - - if (IsNotNull(p_parser->physical_pointer_structs)) { - SafeFree(p_parser->physical_pointer_structs); - } - 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.component.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.spec_id = (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 - - SafeFree(p_parser->source_embedded); - 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, embedded_source_len + 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; - FALLTHROUGH; - } // Fall through - - // This is all the rest of OpType* that need to be tracked - // Possible new extensions might expose new type, will need to be added - // here - 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: - case SpvOpTypeHitObjectNV: - case SpvOpTypeCooperativeMatrixNV: - case SpvOpTypeCooperativeMatrixKHR: { - 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: { - uint32_t result_id; - CHECKED_READU32(p_parser, p_node->word_offset + 1, result_id); - // Look for forward pointer. Clear result id if found - SpvReflectPrvNode* p_fwd_node = FindNode(p_parser, result_id); - if (p_fwd_node) { - p_fwd_node->result_id = 0; - } - // Register pointer type - p_node->result_id = 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, ] - // - 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 || p_index_value_node->op == SpvOpSpecConstant)) { - // 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); - } - FALLTHROUGH; - } // Fall through - - case SpvOpFunctionEnd: { - function_node = (uint32_t)INVALID_VALUE; - } break; - case SpvOpFunctionParameter: { - CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id); - } break; - case SpvOpBitcast: - case SpvOpShiftRightLogical: - case SpvOpIAdd: - case SpvOpISub: - case SpvOpIMul: - case SpvOpUDiv: - case SpvOpSDiv: { - CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id); - } 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->parameter_count = 0; - p_func->callee_count = 0; - p_func->accessed_variable_count = 0; - - // First get count to know how much to allocate - 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 SpvOpFunctionParameter: { - ++(p_func->parameter_count); - } break; - case SpvOpFunctionCall: { - p_func->accessed_variable_count += p_node->word_count - 4; - ++(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_variable_count); - } break; - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: { - p_func->accessed_variable_count += 2; - } break; - default: - break; - } - } - - if (p_func->parameter_count > 0) { - p_func->parameters = (uint32_t*)calloc(p_func->parameter_count, sizeof(*(p_func->parameters))); - if (IsNull(p_func->parameters)) { - return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; - } - } - - 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_variable_count > 0) { - p_func->accessed_variables = - (SpvReflectPrvAccessedVariable*)calloc(p_func->accessed_variable_count, sizeof(*(p_func->accessed_variables))); - if (IsNull(p_func->accessed_variables)) { - return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; - } - } - - p_func->parameter_count = 0; - p_func->callee_count = 0; - p_func->accessed_variable_count = 0; - // Now have allocation, fill in values - 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 SpvOpFunctionParameter: { - CHECKED_READU32(p_parser, p_node->word_offset + 2, p_func->parameters[p_func->parameter_count]); - (++p_func->parameter_count); - } break; - case SpvOpFunctionCall: { - CHECKED_READU32(p_parser, p_node->word_offset + 3, p_func->callees[p_func->callee_count]); - const uint32_t result_index = p_node->word_offset + 2; - for (uint32_t j = 0, parameter_count = p_node->word_count - 4; j < parameter_count; j++) { - const uint32_t ptr_index = p_node->word_offset + 4 + j; - SpvReflectPrvAccessedVariable* access_ptr = &p_func->accessed_variables[p_func->accessed_variable_count]; - - access_ptr->p_node = p_node; - // Need to track Result ID as not sure there has been any memory access through here yet - CHECKED_READU32(p_parser, result_index, access_ptr->result_id); - CHECKED_READU32(p_parser, ptr_index, access_ptr->variable_ptr); - access_ptr->function_id = p_func->callees[p_func->callee_count]; - access_ptr->function_parameter_index = j; - (++p_func->accessed_variable_count); - } - (++p_func->callee_count); - } break; - case SpvOpLoad: - case SpvOpAccessChain: - case SpvOpInBoundsAccessChain: - case SpvOpPtrAccessChain: - case SpvOpArrayLength: - case SpvOpGenericPtrMemSemantics: - case SpvOpInBoundsPtrAccessChain: - case SpvOpImageTexelPointer: { - const uint32_t result_index = p_node->word_offset + 2; - const uint32_t ptr_index = p_node->word_offset + 3; - SpvReflectPrvAccessedVariable* access_ptr = &p_func->accessed_variables[p_func->accessed_variable_count]; - - access_ptr->p_node = p_node; - // Need to track Result ID as not sure there has been any memory access through here yet - CHECKED_READU32(p_parser, result_index, access_ptr->result_id); - CHECKED_READU32(p_parser, ptr_index, access_ptr->variable_ptr); - (++p_func->accessed_variable_count); - } break; - case SpvOpStore: { - const uint32_t result_index = p_node->word_offset + 2; - CHECKED_READU32(p_parser, result_index, p_func->accessed_variables[p_func->accessed_variable_count].variable_ptr); - p_func->accessed_variables[p_func->accessed_variable_count].p_node = p_node; - (++p_func->accessed_variable_count); - } break; - case SpvOpCopyMemory: - case SpvOpCopyMemorySized: { - // There is no result_id or node, being zero is same as being invalid - CHECKED_READU32(p_parser, p_node->word_offset + 1, - p_func->accessed_variables[p_func->accessed_variable_count].variable_ptr); - (++p_func->accessed_variable_count); - CHECKED_READU32(p_parser, p_node->word_offset + 2, - p_func->accessed_variables[p_func->accessed_variable_count].variable_ptr); - (++p_func->accessed_variable_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_variable_count > 0) { - qsort(p_func->accessed_variables, p_func->accessed_variable_count, sizeof(*(p_func->accessed_variables)), - SortCompareAccessedVariable); - } - - 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; - for (size_t j = i; j < p_parser->node_count; ++j) { - if (p_parser->nodes[j].op == SpvOpLabel) { - func_definition = true; - break; - } - if (p_parser->nodes[j].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; -} - -// Returns true if user_type matches pattern or if user_type begins with pattern and the next character is ':' -// For example, UserTypeMatches("rwbuffer", "rwbuffer") will be true, UserTypeMatches("rwbuffer", "rwbuffer:") will be true, and -// UserTypeMatches("rwbuffer", "rwbufferfoo") will be false. -static bool UserTypeMatches(const char* user_type, const char* pattern) { - const size_t pattern_length = strlen(pattern); - if (strncmp(user_type, pattern, pattern_length) == 0) { - if (user_type[pattern_length] == ':' || user_type[pattern_length] == '\0') { - return true; - } - } - return false; -} - -static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser, SpvReflectShaderModule* p_module) { - uint32_t spec_constant_count = 0; - for (uint32_t i = 0; i < p_parser->node_count; ++i) { - SpvReflectPrvNode* p_node = &(p_parser->nodes[i]); - - if ((p_node->op != SpvOpDecorate) && (p_node->op != SpvOpMemberDecorate) && (p_node->op != SpvOpDecorateId) && - (p_node->op != SpvOpDecorateString) && (p_node->op != SpvOpMemberDecorateString)) { - 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 SpvDecorationPatch: - case SpvDecorationPerVertexKHR: - case SpvDecorationPerTaskNV: - case SpvDecorationLocation: - case SpvDecorationComponent: - case SpvDecorationBinding: - case SpvDecorationDescriptorSet: - case SpvDecorationOffset: - case SpvDecorationInputAttachmentIndex: - case SpvDecorationSpecId: - case SpvDecorationWeightTextureQCOM: - case SpvDecorationBlockMatchTextureQCOM: - case SpvDecorationUserTypeGOOGLE: - case SpvDecorationHlslCounterBufferGOOGLE: - case SpvDecorationHlslSemanticGOOGLE: { - skip = false; - } break; - } - if (skip) { - continue; - } - - // Find 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 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 SpvDecorationPatch: { - p_target_decorations->is_patch = true; - } break; - - case SpvDecorationPerVertexKHR: { - p_target_decorations->is_per_vertex = true; - } break; - - case SpvDecorationPerTaskNV: { - p_target_decorations->is_per_task = 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 SpvDecorationComponent: { - uint32_t word_offset = p_node->word_offset + member_offset + 3; - CHECKED_READU32(p_parser, word_offset, p_target_decorations->component.value); - p_target_decorations->component.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 SpvDecorationSpecId: { - spec_constant_count++; - } break; - - case SpvDecorationHlslCounterBufferGOOGLE: { - 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 SpvDecorationHlslSemanticGOOGLE: { - 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; - - case SpvDecorationWeightTextureQCOM: { - p_target_decorations->is_weight_texture = true; - } break; - - case SpvDecorationBlockMatchTextureQCOM: { - p_target_decorations->is_block_match_texture = true; - } break; - } - - if (p_node->op == SpvOpDecorateString && decoration == SpvDecorationUserTypeGOOGLE) { - uint32_t terminator = 0; - SpvReflectResult result = ReadStr(p_parser, p_node->word_offset + 3, 0, p_node->word_count, &terminator, NULL); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - return result; - } - const char* name = (const char*)(p_parser->spirv_code + p_node->word_offset + 3); - if (UserTypeMatches(name, "cbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_CBUFFER; - } else if (UserTypeMatches(name, "tbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TBUFFER; - } else if (UserTypeMatches(name, "appendstructuredbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_APPEND_STRUCTURED_BUFFER; - } else if (UserTypeMatches(name, "buffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_BUFFER; - } else if (UserTypeMatches(name, "byteaddressbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_BYTE_ADDRESS_BUFFER; - } else if (UserTypeMatches(name, "constantbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_CONSTANT_BUFFER; - } else if (UserTypeMatches(name, "consumestructuredbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_CONSUME_STRUCTURED_BUFFER; - } else if (UserTypeMatches(name, "inputpatch")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_INPUT_PATCH; - } else if (UserTypeMatches(name, "outputpatch")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_OUTPUT_PATCH; - } else if (UserTypeMatches(name, "rasterizerorderedbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_BUFFER; - } else if (UserTypeMatches(name, "rasterizerorderedbyteaddressbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_BYTE_ADDRESS_BUFFER; - } else if (UserTypeMatches(name, "rasterizerorderedstructuredbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_STRUCTURED_BUFFER; - } else if (UserTypeMatches(name, "rasterizerorderedtexture1d")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_1D; - } else if (UserTypeMatches(name, "rasterizerorderedtexture1darray")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_1D_ARRAY; - } else if (UserTypeMatches(name, "rasterizerorderedtexture2d")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_2D; - } else if (UserTypeMatches(name, "rasterizerorderedtexture2darray")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_2D_ARRAY; - } else if (UserTypeMatches(name, "rasterizerorderedtexture3d")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_3D; - } else if (UserTypeMatches(name, "raytracingaccelerationstructure")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RAYTRACING_ACCELERATION_STRUCTURE; - } else if (UserTypeMatches(name, "rwbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_BUFFER; - } else if (UserTypeMatches(name, "rwbyteaddressbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_BYTE_ADDRESS_BUFFER; - } else if (UserTypeMatches(name, "rwstructuredbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_STRUCTURED_BUFFER; - } else if (UserTypeMatches(name, "rwtexture1d")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D; - } else if (UserTypeMatches(name, "rwtexture1darray")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D_ARRAY; - } else if (UserTypeMatches(name, "rwtexture2d")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D; - } else if (UserTypeMatches(name, "rwtexture2darray")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D_ARRAY; - } else if (UserTypeMatches(name, "rwtexture3d")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_3D; - } else if (UserTypeMatches(name, "structuredbuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_STRUCTURED_BUFFER; - } else if (UserTypeMatches(name, "subpassinput")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_SUBPASS_INPUT; - } else if (UserTypeMatches(name, "subpassinputms")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_SUBPASS_INPUT_MS; - } else if (UserTypeMatches(name, "texture1d")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_1D; - } else if (UserTypeMatches(name, "texture1darray")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_1D_ARRAY; - } else if (UserTypeMatches(name, "texture2d")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_2D; - } else if (UserTypeMatches(name, "texture2darray")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_2D_ARRAY; - } else if (UserTypeMatches(name, "texture2dms")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_2DMS; - } else if (UserTypeMatches(name, "texture2dmsarray")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_2DMS_ARRAY; - } else if (UserTypeMatches(name, "texture3d")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_3D; - } else if (UserTypeMatches(name, "texturebuffer")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_BUFFER; - } else if (UserTypeMatches(name, "texturecube")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_CUBE; - } else if (UserTypeMatches(name, "texturecubearray")) { - p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_CUBE_ARRAY; - } - } - } - - if (spec_constant_count > 0) { - p_module->spec_constants = (SpvReflectSpecializationConstant*)calloc(spec_constant_count, sizeof(*p_module->spec_constants)); - if (IsNull(p_module->spec_constants)) { - return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; - } - } - for (uint32_t i = 0; i < p_parser->node_count; ++i) { - SpvReflectPrvNode* p_node = &(p_parser->nodes[i]); - if (p_node->op == SpvOpDecorate) { - uint32_t decoration = (uint32_t)INVALID_VALUE; - CHECKED_READU32(p_parser, p_node->word_offset + 2, decoration); - if (decoration == SpvDecorationSpecId) { - const uint32_t count = p_module->spec_constant_count; - CHECKED_READU32(p_parser, p_node->word_offset + 1, p_module->spec_constants[count].spirv_id); - CHECKED_READU32(p_parser, p_node->word_offset + 3, p_module->spec_constants[count].constant_id); - // If being used for a OpSpecConstantComposite (ex. LocalSizeId), there won't be a name - SpvReflectPrvNode* target_node = FindNode(p_parser, p_module->spec_constants[count].spirv_id); - if (IsNotNull(target_node)) { - p_module->spec_constants[count].name = target_node->name; - } - p_module->spec_constant_count++; - } - } - } - - 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->struct_type_description = FindType(p_module, p_node->result_id); - 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; - uint32_t length = 0; - IF_READU32(result, p_parser, p_length_node->word_offset + 3, length); - if (result == SPV_REFLECT_RESULT_SUCCESS) { - p_type->traits.array.dims[dim_index] = length; - p_type->traits.array.dims_count += 1; - p_type->traits.array.spec_constant_op_ids[dim_index] = - IsSpecConstant(p_length_node) ? p_length_node->decorations.spec_id : (uint32_t)INVALID_VALUE; - } 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] = (uint32_t)SPV_REFLECT_ARRAY_DIM_RUNTIME; - p_type->traits.array.spec_constant_op_ids[dim_index] = (uint32_t)INVALID_VALUE; - 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: { - p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_REF; - IF_READU32_CAST(result, p_parser, p_node->word_offset + 2, SpvStorageClass, p_type->storage_class); - - SpvReflectPrvNode* p_next_node = FindNode(p_parser, p_node->type_id); - if (IsNull(p_next_node)) { - result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - SPV_REFLECT_ASSERT(false); - break; - } - - bool found_recursion = false; - if (p_type->storage_class == SpvStorageClassPhysicalStorageBuffer) { - // Need to make sure we haven't started an infinite recursive loop - for (uint32_t i = 0; i < p_parser->physical_pointer_count; i++) { - if (p_type->id == p_parser->physical_pointer_check[i]->id) { - found_recursion = true; - memcpy(p_type, p_parser->physical_pointer_check[i], sizeof(SpvReflectTypeDescription)); - p_type->copied = 1; - return SPV_REFLECT_RESULT_SUCCESS; - } - } - if (!found_recursion && p_next_node->op == SpvOpTypeStruct) { - p_parser->physical_pointer_struct_count++; - p_parser->physical_pointer_check[p_parser->physical_pointer_count] = p_type; - p_parser->physical_pointer_count++; - if (p_parser->physical_pointer_count >= MAX_RECURSIVE_PHYSICAL_POINTER_CHECK) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED; - } - } - } - - if (!found_recursion) { - if (p_next_node->op == SpvOpTypeStruct) { - p_type->struct_type_description = FindType(p_module, p_next_node->result_id); - } - - result = ParseType(p_parser, p_next_node, NULL, p_module, p_type); - } - } 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]); - p_parser->physical_pointer_count = 0; - SpvReflectResult result = ParseType(p_parser, p_node, NULL, p_module, p_type); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - return result; - } - ++type_index; - } - - // allocate now and fill in when parsing struct variable later - if (p_parser->physical_pointer_struct_count > 0) { - p_parser->physical_pointer_structs = (SpvReflectPrvPhysicalPointerStruct*)calloc(p_parser->physical_pointer_struct_count, - sizeof(*(p_parser->physical_pointer_structs))); - if (IsNull(p_parser->physical_pointer_structs)) { - return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; - } - } - 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) { - assert(p_type->storage_class != -1 && "Pointer types must have a valid storage class."); - pointer_storage_class = (SpvStorageClass)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); - p_descriptor->user_type = p_node->decorations.user_type; - - // Flags like non-writable and non-readable are found as member decorations only. - // If all members have one of those decorations set, promote the decoration up - // to the whole descriptor. - const SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id); - if (IsNotNull(p_type_node) && p_type_node->member_count) { - SpvReflectPrvDecorations common_flags = p_type_node->member_decorations[0]; - - for (uint32_t m = 1; m < p_type_node->member_count; ++m) { - common_flags.is_relaxed_precision &= p_type_node->member_decorations[m].is_relaxed_precision; - common_flags.is_block &= p_type_node->member_decorations[m].is_block; - common_flags.is_buffer_block &= p_type_node->member_decorations[m].is_buffer_block; - common_flags.is_row_major &= p_type_node->member_decorations[m].is_row_major; - common_flags.is_column_major &= p_type_node->member_decorations[m].is_column_major; - common_flags.is_built_in &= p_type_node->member_decorations[m].is_built_in; - common_flags.is_noperspective &= p_type_node->member_decorations[m].is_noperspective; - common_flags.is_flat &= p_type_node->member_decorations[m].is_flat; - common_flags.is_non_writable &= p_type_node->member_decorations[m].is_non_writable; - common_flags.is_non_readable &= p_type_node->member_decorations[m].is_non_readable; - common_flags.is_patch &= p_type_node->member_decorations[m].is_patch; - common_flags.is_per_vertex &= p_type_node->member_decorations[m].is_per_vertex; - common_flags.is_per_task &= p_type_node->member_decorations[m].is_per_task; - common_flags.is_weight_texture &= p_type_node->member_decorations[m].is_weight_texture; - common_flags.is_block_match_texture &= p_type_node->member_decorations[m].is_block_match_texture; - } - - p_descriptor->decoration_flags |= ApplyDecorations(&common_flags); - } - - // 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]; - // If pointer type, treat like reference and resolve to pointee type - SpvReflectTypeDescription* p_member_ptr_type = 0; - bool found_recursion = false; - - if ((p_member_type->storage_class == SpvStorageClassPhysicalStorageBuffer) && - (p_member_type->type_flags & SPV_REFLECT_TYPE_FLAG_REF)) { - // Remember the original type - p_member_ptr_type = p_member_type; - - // strip array - if (p_member_type->op == SpvOpTypeArray || p_member_type->op == SpvOpTypeRuntimeArray) { - SpvReflectPrvNode* p_node = FindNode(p_parser, p_member_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; - p_member_type = FindType(p_module, element_type_id); - if (p_member_type == NULL) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - } - } - - // Need to make sure we haven't started an infinite recursive loop - for (uint32_t i = 0; i < p_parser->physical_pointer_count; i++) { - if (p_member_type->id == p_parser->physical_pointer_check[i]->id) { - found_recursion = true; - break; // still need to fill in p_member_type values - } - } - if (!found_recursion) { - SpvReflectTypeDescription* struct_type = FindType(p_module, p_member_type->id); - // could be pointer directly to non-struct type here - if (struct_type->struct_type_description) { - uint32_t struct_id = struct_type->struct_type_description->id; - p_parser->physical_pointer_structs[p_parser->physical_pointer_struct_count].struct_id = struct_id; - p_parser->physical_pointer_structs[p_parser->physical_pointer_struct_count].p_var = p_member_var; - p_parser->physical_pointer_struct_count++; - - p_parser->physical_pointer_check[p_parser->physical_pointer_count] = p_member_type; - p_parser->physical_pointer_count++; - if (p_parser->physical_pointer_count >= MAX_RECURSIVE_PHYSICAL_POINTER_CHECK) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED; - } - } - } - - SpvReflectPrvNode* p_member_type_node = FindNode(p_parser, p_member_type->id); - if (IsNull(p_member_type_node)) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - } - // Should be the pointee type - p_member_type = FindType(p_module, p_member_type_node->type_id); - if (IsNull(p_member_type)) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - } - } - bool is_struct = (p_member_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) == SPV_REFLECT_TYPE_FLAG_STRUCT; - if (is_struct) { - if (!found_recursion) { - SpvReflectResult result = ParseDescriptorBlockVariable(p_parser, p_module, p_member_type, p_member_var); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - return result; - } - } else { - // if 2 member of structs are same PhysicalPointer type, copy the - // members values that aren't found skipping the recursion call - for (uint32_t i = 0; i < p_parser->physical_pointer_struct_count; i++) { - if (p_parser->physical_pointer_structs[i].struct_id == p_member_type->id) { - p_member_var->members = p_parser->physical_pointer_structs[i].p_var->members; - p_member_var->member_count = p_parser->physical_pointer_structs[i].p_var->member_count; - // Set here as it is the first time we need to walk down structs - p_member_var->flags |= SPV_REFLECT_VARIABLE_FLAGS_PHYSICAL_POINTER_COPY; - } - } - } - } - - if (p_type_node->storage_class == SpvStorageClassPhysicalStorageBuffer && !p_type_node->member_names) { - // TODO 212 - If a buffer ref has an array of itself, all members are null - continue; - } - - 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->word_offset.offset = p_type_node->member_decorations[member_index].offset.word_offset; - p_member_var->type_description = p_member_ptr_type ? p_member_ptr_type : 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 uint32_t GetPhysicalPointerStructSize(SpvReflectPrvParser* p_parser, uint32_t id) { - for (uint32_t i = 0; i < p_parser->physical_pointer_struct_count; i++) { - if (p_parser->physical_pointer_structs[i].struct_id == id) { - return p_parser->physical_pointer_structs[i].p_var->size; - } - } - return 0; -} - -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; - } - - bool is_parent_ref = p_var->type_description->op == SpvOpTypePointer; - - // 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 : (is_parent_ref ? p_member_var->offset : 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; - - if (!p_member_type) { - // TODO 212 - If a buffer ref has an array of itself, all members are null - continue; - } - 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) { - if (p_member_var->flags & SPV_REFLECT_VARIABLE_FLAGS_PHYSICAL_POINTER_COPY) { - p_member_var->size = GetPhysicalPointerStructSize(p_parser, p_member_type->id); - } else { - 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 SpvOpTypePointer: { - // Reference. Get to underlying struct type. - SpvReflectPrvNode* p_member_type_node = FindNode(p_parser, p_member_type->id); - if (IsNull(p_member_type_node)) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - } - // Get the pointee type - p_member_type = FindType(p_module, p_member_type_node->type_id); - if (IsNull(p_member_type)) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - } - - // If we found a struct, we need to fall through and get the size of it or else we grab the size here - if (p_member_type->op != SpvOpTypeStruct) { - // If we hit this, we are seeing a POD pointer and the size is fixed - p_member_var->size = SPIRV_PHYSICAL_STORAGE_POINTER_SIZE; - break; - } - FALLTHROUGH; - } - - case SpvOpTypeStruct: { - if (p_member_var->flags & SPV_REFLECT_VARIABLE_FLAGS_PHYSICAL_POINTER_COPY) { - p_member_var->size = GetPhysicalPointerStructSize(p_parser, p_member_type->id); - } else { - 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; - } - } - - // Structs can offset order don't need to match the index order, so first order by offset - // example: - // OpMemberDecorate %struct 0 Offset 4 - // OpMemberDecorate %struct 1 Offset 0 - SpvReflectBlockVariable** pp_member_offset_order = - (SpvReflectBlockVariable**)calloc(p_var->member_count, sizeof(SpvReflectBlockVariable*)); - if (IsNull(pp_member_offset_order)) { - return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; - } - - uint32_t bottom_bound = 0; - for (uint32_t i = 0; i < p_var->member_count; ++i) { - uint32_t lowest_offset = UINT32_MAX; - uint32_t member_index = 0; - for (uint32_t j = 0; j < p_var->member_count; ++j) { - const uint32_t offset = p_var->members[j].offset; - if (offset < lowest_offset && offset >= bottom_bound) { - member_index = j; - lowest_offset = offset; - } - } - pp_member_offset_order[i] = &p_var->members[member_index]; - bottom_bound = lowest_offset + 1; // 2 index can't share the same offset - } - - // Parse padded size using offset difference for all member except for the last entry... - for (uint32_t i = 0; i < (p_var->member_count - 1); ++i) { - SpvReflectBlockVariable* p_member_var = pp_member_offset_order[i]; - SpvReflectBlockVariable* p_next_member_var = pp_member_offset_order[i + 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. - // last entry == entry with largest offset value - SpvReflectBlockVariable* p_last_member_var = pp_member_offset_order[p_var->member_count - 1]; - p_last_member_var->padded_size = - RoundUp(p_last_member_var->offset + p_last_member_var->size, SPIRV_DATA_ALIGNMENT) - p_last_member_var->offset; - if (p_last_member_var->size > p_last_member_var->padded_size) { - p_last_member_var->size = p_last_member_var->padded_size; - } - if (is_parent_rta) { - p_last_member_var->padded_size = p_last_member_var->size; - } - - SafeFree(pp_member_offset_order); - - // If buffer ref, sizes are same as uint64_t - if (is_parent_ref) { - p_var->size = p_var->padded_size = 8; - return SPV_REFLECT_RESULT_SUCCESS; - } - - // @TODO validate this with assertion - p_var->size = p_last_member_var->offset + p_last_member_var->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 UNUSED flag - p_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED; - - SpvOp op_type = p_var->type_description->op; - if (op_type == SpvOpTypeStruct) { - for (uint32_t i = 0; i < p_var->member_count; ++i) { - SpvReflectBlockVariable* p_member_var = &p_var->members[i]; - MarkSelfAndAllMemberVarsAsUsed(p_member_var); - } - } -} - -static SpvReflectResult ParseDescriptorBlockVariableUsage(SpvReflectPrvParser* p_parser, SpvReflectShaderModule* p_module, - SpvReflectPrvAccessChain* p_access_chain, uint32_t index_index, - SpvOp override_op_type, SpvReflectBlockVariable* 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. - SpvReflectTypeDescription* p_type = p_var->type_description; - SpvOp op_type = p_type->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 - 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 reached 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 SpvOpTypePointer: { - // Reference. Get to underlying struct type. - SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id); - if (IsNull(p_type_node)) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - } - // Get the pointee type - p_type = FindType(p_module, p_type_node->type_id); - if (IsNull(p_type)) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - } - if (p_type->op != SpvOpTypeStruct) { - break; - } - FALLTHROUGH; - } - - case SpvOpTypeStruct: { - assert(p_var->member_count > 0); - if (p_var->member_count == 0) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA; - } - - // The access chain can have zero indexes, if used for a runtime array - if (p_access_chain->index_count == 0) { - return SPV_REFLECT_RESULT_SUCCESS; - } - - // 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]; - - bool is_pointer_to_pointer = IsPointerToPointer(p_parser, p_access_chain->result_type_id); - if (is_pointer_to_pointer) { - // Remember block var for this access chain for downstream dereference - p_access_chain->block_var = p_member_var; - } - - // 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 if (is_pointer_to_pointer) { - // Clear UNUSED flag, but only for the pointer - p_member_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED; - } else { - // Clear UNUSED flag for remaining variables - MarkSelfAndAllMemberVarsAsUsed(p_member_var); - } - } 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; - } - - p_parser->physical_pointer_struct_count = 0; - - 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; - p_parser->physical_pointer_count = 0; - // 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 16: { - switch (component_count) { - case 2: - *p_format = SPV_REFLECT_FORMAT_R16G16_SFLOAT; - break; - case 3: - *p_format = SPV_REFLECT_FORMAT_R16G16B16_SFLOAT; - break; - case 4: - *p_format = SPV_REFLECT_FORMAT_R16G16B16A16_SFLOAT; - break; - } - } break; - - 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 16: { - switch (component_count) { - case 2: - *p_format = signedness ? SPV_REFLECT_FORMAT_R16G16_SINT : SPV_REFLECT_FORMAT_R16G16_UINT; - break; - case 3: - *p_format = signedness ? SPV_REFLECT_FORMAT_R16G16B16_SINT : SPV_REFLECT_FORMAT_R16G16B16_UINT; - break; - case 4: - *p_format = signedness ? SPV_REFLECT_FORMAT_R16G16B16A16_SINT : SPV_REFLECT_FORMAT_R16G16B16A16_UINT; - break; - } - } break; - - 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 16: - *p_format = SPV_REFLECT_FORMAT_R16_SFLOAT; - break; - 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 16: - *p_format = signedness ? SPV_REFLECT_FORMAT_R16_SINT : SPV_REFLECT_FORMAT_R16_UINT; - break; - break; - 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]; - - // Storage class is the same throughout the whole struct - p_member_var->storage_class = p_var->storage_class; - - 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); - } else { - // Apply member decoration values to struct members - p_var->location = p_type_node_decorations->location.value; - p_var->component = p_type_node_decorations->component.value; - } - - 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) || IsNull(p_type)) { - 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->component = p_node->decorations.component.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 uint32_t GetUint32Constant(SpvReflectPrvParser* p_parser, uint32_t id) { - uint32_t result = (uint32_t)INVALID_VALUE; - SpvReflectPrvNode* p_node = FindNode(p_parser, id); - if (p_node && p_node->op == SpvOpConstant) { - UNCHECKED_READU32(p_parser, p_node->word_offset + 3, result); - } - return result; -} - -static bool HasByteAddressBufferOffset(SpvReflectPrvNode* p_node, SpvReflectDescriptorBinding* p_binding) { - return IsNotNull(p_node) && IsNotNull(p_binding) && p_node->op == SpvOpAccessChain && p_node->word_count == 6 && - (p_binding->user_type == SPV_REFLECT_USER_TYPE_BYTE_ADDRESS_BUFFER || - p_binding->user_type == SPV_REFLECT_USER_TYPE_RW_BYTE_ADDRESS_BUFFER); -} - -static SpvReflectResult ParseByteAddressBuffer(SpvReflectPrvParser* p_parser, SpvReflectPrvNode* p_node, - SpvReflectDescriptorBinding* p_binding) { - const SpvReflectResult not_found = SPV_REFLECT_RESULT_SUCCESS; - if (!HasByteAddressBufferOffset(p_node, p_binding)) { - return not_found; - } - - uint32_t offset = 0; // starting offset - - uint32_t base_id = 0; - // expect first index of 2D access is zero - UNCHECKED_READU32(p_parser, p_node->word_offset + 4, base_id); - if (GetUint32Constant(p_parser, base_id) != 0) { - return not_found; - } - UNCHECKED_READU32(p_parser, p_node->word_offset + 5, base_id); - SpvReflectPrvNode* p_next_node = FindNode(p_parser, base_id); - if (IsNull(p_next_node)) { - return not_found; - } else if (p_next_node->op == SpvOpConstant) { - // The access chain might just be a constant right to the offset - offset = GetUint32Constant(p_parser, base_id); - p_binding->byte_address_buffer_offsets[p_binding->byte_address_buffer_offset_count] = offset; - p_binding->byte_address_buffer_offset_count++; - return SPV_REFLECT_RESULT_SUCCESS; - } - - // there is usually 2 (sometimes 3) instrucitons that make up the arithmetic logic to calculate the offset - SpvReflectPrvNode* arithmetic_node_stack[8]; - uint32_t arithmetic_count = 0; - - while (IsNotNull(p_next_node)) { - if (p_next_node->op == SpvOpLoad || p_next_node->op == SpvOpBitcast || p_next_node->op == SpvOpConstant) { - break; // arithmetic starts here - } - arithmetic_node_stack[arithmetic_count++] = p_next_node; - if (arithmetic_count >= 8) { - return not_found; - } - - UNCHECKED_READU32(p_parser, p_next_node->word_offset + 3, base_id); - p_next_node = FindNode(p_parser, base_id); - } - - const uint32_t count = arithmetic_count; - for (uint32_t i = 0; i < count; i++) { - p_next_node = arithmetic_node_stack[--arithmetic_count]; - // All arithmetic ops takes 2 operands, assumption is the 2nd operand has the constant - UNCHECKED_READU32(p_parser, p_next_node->word_offset + 4, base_id); - uint32_t value = GetUint32Constant(p_parser, base_id); - if (value == INVALID_VALUE) { - return not_found; - } - - switch (p_next_node->op) { - case SpvOpShiftRightLogical: - offset >>= value; - break; - case SpvOpIAdd: - offset += value; - break; - case SpvOpISub: - offset -= value; - break; - case SpvOpIMul: - offset *= value; - break; - case SpvOpUDiv: - offset /= value; - break; - case SpvOpSDiv: - // OpConstant might be signed, but value should never be negative - assert((int32_t)value > 0); - offset /= value; - break; - default: - return not_found; - } - } - - p_binding->byte_address_buffer_offsets[p_binding->byte_address_buffer_offset_count] = offset; - p_binding->byte_address_buffer_offset_count++; - return SPV_REFLECT_RESULT_SUCCESS; -} - -static SpvReflectResult ParseFunctionParameterAccess(SpvReflectPrvParser* p_parser, uint32_t callee_function_id, - uint32_t function_parameter_index, uint32_t* p_accessed) { - SpvReflectPrvFunction* p_func = NULL; - for (size_t i = 0; i < p_parser->function_count; ++i) { - if (p_parser->functions[i].id == callee_function_id) { - p_func = &(p_parser->functions[i]); - break; - } - } - if (p_func == NULL) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - } - - assert(function_parameter_index < p_func->parameter_count); - - for (size_t i = 0; i < p_func->accessed_variable_count; ++i) { - if (p_func->parameters[function_parameter_index] == p_func->accessed_variables[i].variable_ptr) { - SpvReflectPrvAccessedVariable* p_var = &p_func->accessed_variables[i]; - if (p_var->function_id > 0) { - SpvReflectResult result = - ParseFunctionParameterAccess(p_parser, p_var->function_id, p_var->function_parameter_index, p_accessed); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - return result; - } - } else { - *p_accessed = 1; - } - // Early out as soon as p_accessed is true - if (*p_accessed) { - return SPV_REFLECT_RESULT_SUCCESS; - } - } - } - - *p_accessed = 0; - 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) { - SafeFree(p_called_functions); - 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_acessed_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_acessed_count += p_parser->functions[j].accessed_variable_count; - } - SpvReflectPrvAccessedVariable* p_used_accesses = NULL; - if (used_acessed_count > 0) { - p_used_accesses = (SpvReflectPrvAccessedVariable*)calloc(used_acessed_count, sizeof(SpvReflectPrvAccessedVariable)); - if (IsNull(p_used_accesses)) { - SafeFree(p_called_functions); - return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; - } - } - used_acessed_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(&p_used_accesses[used_acessed_count], p_parser->functions[j].accessed_variables, - p_parser->functions[j].accessed_variable_count * sizeof(SpvReflectPrvAccessedVariable)); - used_acessed_count += p_parser->functions[j].accessed_variable_count; - } - SafeFree(p_called_functions); - - if (used_acessed_count > 0) { - qsort(p_used_accesses, used_acessed_count, sizeof(*p_used_accesses), SortCompareAccessedVariable); - } - - // Do set intersection to find the used uniform and push constants - size_t used_uniform_count = 0; - result = IntersectSortedAccessedVariable(p_used_accesses, used_acessed_count, uniforms, uniform_count, &p_entry->used_uniforms, - &used_uniform_count); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - SafeFree(p_used_accesses); - return result; - } - - size_t used_push_constant_count = 0; - result = IntersectSortedAccessedVariable(p_used_accesses, used_acessed_count, push_constants, push_constant_count, - &p_entry->used_push_constants, &used_push_constant_count); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - SafeFree(p_used_accesses); - return result; - } - - for (uint32_t i = 0; i < p_module->descriptor_binding_count; ++i) { - SpvReflectDescriptorBinding* p_binding = &p_module->descriptor_bindings[i]; - uint32_t byte_address_buffer_offset_count = 0; - - for (uint32_t j = 0; j < used_acessed_count; j++) { - SpvReflectPrvAccessedVariable* p_var = &p_used_accesses[j]; - if (p_var->variable_ptr == p_binding->spirv_id) { - if (p_var->function_id > 0) { - result = - ParseFunctionParameterAccess(p_parser, p_var->function_id, p_var->function_parameter_index, &p_binding->accessed); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - SafeFree(p_used_accesses); - return result; - } - } else { - p_binding->accessed = 1; - } - - if (HasByteAddressBufferOffset(p_used_accesses[j].p_node, p_binding)) { - byte_address_buffer_offset_count++; - } - } - } - - // only if SPIR-V has ByteAddressBuffer user type - if (byte_address_buffer_offset_count > 0) { - bool multi_entrypoint = p_binding->byte_address_buffer_offset_count > 0; - if (multi_entrypoint) { - // If there is a 2nd entrypoint, we can have multiple entry points, in this case we want to just combine the accessed - // offsets and then de-duplicate it - uint32_t* prev_byte_address_buffer_offsets = p_binding->byte_address_buffer_offsets; - p_binding->byte_address_buffer_offsets = - (uint32_t*)calloc(byte_address_buffer_offset_count + p_binding->byte_address_buffer_offset_count, sizeof(uint32_t)); - memcpy(p_binding->byte_address_buffer_offsets, prev_byte_address_buffer_offsets, - sizeof(uint32_t) * p_binding->byte_address_buffer_offset_count); - SafeFree(prev_byte_address_buffer_offsets); - } else { - // possible not all allocated offset slots are used, but this will be a max per binding - p_binding->byte_address_buffer_offsets = (uint32_t*)calloc(byte_address_buffer_offset_count, sizeof(uint32_t)); - } - - if (IsNull(p_binding->byte_address_buffer_offsets)) { - SafeFree(p_used_accesses); - return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; - } - - for (uint32_t j = 0; j < used_acessed_count; j++) { - if (p_used_accesses[j].variable_ptr == p_binding->spirv_id) { - result = ParseByteAddressBuffer(p_parser, p_used_accesses[j].p_node, p_binding); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - SafeFree(p_used_accesses); - return result; - } - } - } - - if (multi_entrypoint) { - qsort(p_binding->byte_address_buffer_offsets, p_binding->byte_address_buffer_offset_count, - sizeof(*(p_binding->byte_address_buffer_offsets)), SortCompareUint32); - p_binding->byte_address_buffer_offset_count = - (uint32_t)DedupSortedUint32(p_binding->byte_address_buffer_offsets, p_binding->byte_address_buffer_offset_count); - } - } - } - - SafeFree(p_used_accesses); - - 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 SpvExecutionModelTaskEXT: - p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TASK_BIT_EXT; - break; - case SpvExecutionModelMeshNV: - p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV; - break; - case SpvExecutionModelMeshEXT: - p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MESH_BIT_EXT; - 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 && p_node->op != SpvOpExecutionModeId) { - 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) { - case SpvExecutionModeInvocations: { - CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->invocations); - } 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 SpvExecutionModeLocalSizeId: { - uint32_t local_size_x_id = 0; - uint32_t local_size_y_id = 0; - uint32_t local_size_z_id = 0; - CHECKED_READU32(p_parser, p_node->word_offset + 3, local_size_x_id); - CHECKED_READU32(p_parser, p_node->word_offset + 4, local_size_y_id); - CHECKED_READU32(p_parser, p_node->word_offset + 5, local_size_z_id); - - SpvReflectPrvNode* x_node = FindNode(p_parser, local_size_x_id); - SpvReflectPrvNode* y_node = FindNode(p_parser, local_size_y_id); - SpvReflectPrvNode* z_node = FindNode(p_parser, local_size_z_id); - if (IsNotNull(x_node) && IsNotNull(y_node) && IsNotNull(z_node)) { - if (IsSpecConstant(x_node)) { - p_entry_point->local_size.x = (uint32_t)SPV_REFLECT_EXECUTION_MODE_SPEC_CONSTANT; - } else { - CHECKED_READU32(p_parser, x_node->word_offset + 3, p_entry_point->local_size.x); - } - - if (IsSpecConstant(y_node)) { - p_entry_point->local_size.y = (uint32_t)SPV_REFLECT_EXECUTION_MODE_SPEC_CONSTANT; - } else { - CHECKED_READU32(p_parser, y_node->word_offset + 3, p_entry_point->local_size.y); - } - - if (IsSpecConstant(z_node)) { - p_entry_point->local_size.z = (uint32_t)SPV_REFLECT_EXECUTION_MODE_SPEC_CONSTANT; - } else { - CHECKED_READU32(p_parser, z_node->word_offset + 3, p_entry_point->local_size.z); - } - } - } break; - - case SpvExecutionModeOutputVertices: { - CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->output_vertices); - } break; - - default: - 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]; - if (p_entry_point->execution_mode_count > 0) { - 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; - } - - p_parser->physical_pointer_struct_count = 0; - 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) || IsNull(p_type)) { - 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; - p_parser->physical_pointer_count = 0; - SpvReflectResult result = ParseDescriptorBlockVariable(p_parser, p_module, p_type, p_push_constant); - 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 push constant block - if (p_push_constant->spirv_id != FindAccessChainBaseVariable(p_parser, p_access_chain)) { - continue; - } - SpvReflectBlockVariable* p_var = - (p_access_chain->base_id == p_push_constant->spirv_id) ? p_push_constant : GetRefBlkVar(p_parser, p_access_chain); - result = ParseDescriptorBlockVariableUsage(p_parser, p_module, p_access_chain, 0, (SpvOp)INVALID_VALUE, p_var); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - return result; - } - } - - p_push_constant->name = p_node->name; - result = ParseDescriptorBlockVariableSizes(p_parser, p_module, true, false, true, p_push_constant); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - return result; - } - - // Get minimum offset for whole Push Constant block - // It is not valid SPIR-V to have an empty Push Constant Block - p_push_constant->offset = UINT32_MAX; - for (uint32_t k = 0; k < p_push_constant->member_count; ++k) { - const uint32_t member_offset = p_push_constant->members[k].offset; - p_push_constant->offset = Min(p_push_constant->offset, member_offset); - } - - ++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(static_cast(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); - } - - // Initialize everything to zero - SpvReflectPrvParser parser; - memset(&parser, 0, sizeof(SpvReflectPrvParser)); - - // Create parser - 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, p_module); - 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) || p_type->copied) { - 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; - } - - // We share pointers to Physical Pointer structs and don't want to double free - if (p_block->flags & SPV_REFLECT_VARIABLE_FLAGS_PHYSICAL_POINTER_COPY) { - 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]; - if (IsNotNull(p_descriptor->byte_address_buffer_offsets)) { - SafeFree(p_descriptor->byte_address_buffer_offsets); - } - 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); - SafeFree(p_module->spec_constants); - - // 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; -} - -SpvReflectResult spvReflectEnumerateSpecializationConstants(const SpvReflectShaderModule* p_module, uint32_t* p_count, - SpvReflectSpecializationConstant** pp_constants) { - 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_constants)) { - if (*p_count != p_module->spec_constant_count) { - return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH; - } - - for (uint32_t index = 0; index < *p_count; ++index) { - SpvReflectSpecializationConstant* p_constant = (SpvReflectSpecializationConstant*)&p_module->spec_constants[index]; - pp_constants[index] = p_constant; - } - } else { - *p_count = p_module->spec_constant_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 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 SpvSourceLanguageHERO_C: - return "Hero C"; - case SpvSourceLanguageNZSL: - return "NZSL"; - default: - break; - } - // The source language is SpvSourceLanguageUnknown, SpvSourceLanguageMax, or - // some other value that does not correspond to a knonwn language. - return "Unknown"; -} - -const char* spvReflectBlockVariableTypeName(const SpvReflectBlockVariable* p_var) { - if (p_var == NULL) { - return NULL; - } - return p_var->type_description->type_name; -} diff --git a/WickedEngine/Utility/spirv_reflect.h b/WickedEngine/Utility/spirv_reflect.h deleted file mode 100644 index eea30bd71..000000000 --- a/WickedEngine/Utility/spirv_reflect.h +++ /dev/null @@ -1,2451 +0,0 @@ -/* - 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 - -*/ - -// clang-format off -/*! - - @file spirv_reflect.h - -*/ -#ifndef SPIRV_REFLECT_H -#define SPIRV_REFLECT_H - -#if defined(SPIRV_REFLECT_USE_SYSTEM_SPIRV_H) -#include -#else -#include "./include/spirv/unified1/spirv.h" -#endif - - -#include -#include - -#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, - SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED, -} 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, - SPV_REFLECT_TYPE_FLAG_REF = 0x40000000, -} 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. - - The Patch, PerVertex, and PerTask are used for Interface - variables that can have array - -*/ -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, - SPV_REFLECT_DECORATION_PATCH = 0x00000400, - SPV_REFLECT_DECORATION_PER_VERTEX = 0x00000800, - SPV_REFLECT_DECORATION_PER_TASK = 0x00001000, - SPV_REFLECT_DECORATION_WEIGHT_TEXTURE = 0x00002000, - SPV_REFLECT_DECORATION_BLOCK_MATCH_TEXTURE = 0x00004000, -} SpvReflectDecorationFlagBits; - -typedef uint32_t SpvReflectDecorationFlags; - -// Based of SPV_GOOGLE_user_type -typedef enum SpvReflectUserType { - SPV_REFLECT_USER_TYPE_INVALID = 0, - SPV_REFLECT_USER_TYPE_CBUFFER, - SPV_REFLECT_USER_TYPE_TBUFFER, - SPV_REFLECT_USER_TYPE_APPEND_STRUCTURED_BUFFER, - SPV_REFLECT_USER_TYPE_BUFFER, - SPV_REFLECT_USER_TYPE_BYTE_ADDRESS_BUFFER, - SPV_REFLECT_USER_TYPE_CONSTANT_BUFFER, - SPV_REFLECT_USER_TYPE_CONSUME_STRUCTURED_BUFFER, - SPV_REFLECT_USER_TYPE_INPUT_PATCH, - SPV_REFLECT_USER_TYPE_OUTPUT_PATCH, - SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_BUFFER, - SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_BYTE_ADDRESS_BUFFER, - SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_STRUCTURED_BUFFER, - SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_1D, - SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_1D_ARRAY, - SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_2D, - SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_2D_ARRAY, - SPV_REFLECT_USER_TYPE_RASTERIZER_ORDERED_TEXTURE_3D, - SPV_REFLECT_USER_TYPE_RAYTRACING_ACCELERATION_STRUCTURE, - SPV_REFLECT_USER_TYPE_RW_BUFFER, - SPV_REFLECT_USER_TYPE_RW_BYTE_ADDRESS_BUFFER, - SPV_REFLECT_USER_TYPE_RW_STRUCTURED_BUFFER, - SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D, - SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D_ARRAY, - SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D, - SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D_ARRAY, - SPV_REFLECT_USER_TYPE_RW_TEXTURE_3D, - SPV_REFLECT_USER_TYPE_STRUCTURED_BUFFER, - SPV_REFLECT_USER_TYPE_SUBPASS_INPUT, - SPV_REFLECT_USER_TYPE_SUBPASS_INPUT_MS, - SPV_REFLECT_USER_TYPE_TEXTURE_1D, - SPV_REFLECT_USER_TYPE_TEXTURE_1D_ARRAY, - SPV_REFLECT_USER_TYPE_TEXTURE_2D, - SPV_REFLECT_USER_TYPE_TEXTURE_2D_ARRAY, - SPV_REFLECT_USER_TYPE_TEXTURE_2DMS, - SPV_REFLECT_USER_TYPE_TEXTURE_2DMS_ARRAY, - SPV_REFLECT_USER_TYPE_TEXTURE_3D, - SPV_REFLECT_USER_TYPE_TEXTURE_BUFFER, - SPV_REFLECT_USER_TYPE_TEXTURE_CUBE, - SPV_REFLECT_USER_TYPE_TEXTURE_CUBE_ARRAY, -} SpvReflectUserType; - -/*! @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_R16_UINT = 74, // = VK_FORMAT_R16_UINT - SPV_REFLECT_FORMAT_R16_SINT = 75, // = VK_FORMAT_R16_SINT - SPV_REFLECT_FORMAT_R16_SFLOAT = 76, // = VK_FORMAT_R16_SFLOAT - SPV_REFLECT_FORMAT_R16G16_UINT = 81, // = VK_FORMAT_R16G16_UINT - SPV_REFLECT_FORMAT_R16G16_SINT = 82, // = VK_FORMAT_R16G16_SINT - SPV_REFLECT_FORMAT_R16G16_SFLOAT = 83, // = VK_FORMAT_R16G16_SFLOAT - SPV_REFLECT_FORMAT_R16G16B16_UINT = 88, // = VK_FORMAT_R16G16B16_UINT - SPV_REFLECT_FORMAT_R16G16B16_SINT = 89, // = VK_FORMAT_R16G16B16_SINT - SPV_REFLECT_FORMAT_R16G16B16_SFLOAT = 90, // = VK_FORMAT_R16G16B16_SFLOAT - SPV_REFLECT_FORMAT_R16G16B16A16_UINT = 95, // = VK_FORMAT_R16G16B16A16_UINT - SPV_REFLECT_FORMAT_R16G16B16A16_SINT = 96, // = VK_FORMAT_R16G16B16A16_SINT - SPV_REFLECT_FORMAT_R16G16B16A16_SFLOAT = 97, // = VK_FORMAT_R16G16B16A16_SFLOAT - 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, - // If variable points to a copy of the PhysicalStorageBuffer struct - SPV_REFLECT_VARIABLE_FLAGS_PHYSICAL_POINTER_COPY = 0x00000002, -}; - -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_TASK_BIT_EXT = SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV, // = VK_SHADER_STAGE_CALLABLE_BIT_EXT - SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV = 0x00000080, // = VK_SHADER_STAGE_MESH_BIT_NV - SPV_REFLECT_SHADER_STAGE_MESH_BIT_EXT = SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV, // = VK_SHADER_STAGE_CALLABLE_BIT_EXT - 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 enum SpvReflectArrayDimType { - SPV_REFLECT_ARRAY_DIM_RUNTIME = 0, // OpTypeRuntimeArray -} SpvReflectArrayDimType; - -typedef struct SpvReflectArrayTraits { - uint32_t dims_count; - // Each entry is either: - // - specialization constant dimension - // - OpTypeRuntimeArray - // - 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 - @brief Information about an OpType* instruction -*/ -typedef struct SpvReflectTypeDescription { - uint32_t id; - SpvOp op; - const char* type_name; - // Non-NULL if type is member of a struct - const char* struct_member_name; - - // The storage class (SpvStorageClass) if the type, and -1 if it does not have a storage class. - int storage_class; - SpvReflectTypeFlags type_flags; - SpvReflectDecorationFlags decoration_flags; - - struct Traits { - SpvReflectNumericTraits numeric; - SpvReflectImageTraits image; - SpvReflectArrayTraits array; - } traits; - - // If underlying type is a struct (ex. array of structs) - // this gives access to the OpTypeStruct - struct SpvReflectTypeDescription* struct_type_description; - - // Some pointers to SpvReflectTypeDescription are really - // just copies of another reference to the same OpType - uint32_t copied; - - // @deprecated use struct_type_description instead - uint32_t member_count; - // @deprecated use struct_type_description instead - struct SpvReflectTypeDescription* members; -} SpvReflectTypeDescription; - - -/*! @struct SpvReflectInterfaceVariable - @brief The OpVariable that is either an Input or Output to the module -*/ -typedef struct SpvReflectInterfaceVariable { - uint32_t spirv_id; - const char* name; - uint32_t location; - uint32_t component; - SpvStorageClass storage_class; - const char* semantic; - SpvReflectDecorationFlags decoration_flags; - - // The builtin id (SpvBuiltIn) if the variable is a builtin, and -1 otherwise. - int 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; - // For Push Constants, this is the lowest offset of all memebers - 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; - - struct { - uint32_t offset; - } word_offset; - -} 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; - uint32_t byte_address_buffer_offset_count; - uint32_t* byte_address_buffer_offsets; - - SpvReflectTypeDescription* type_description; - - struct { - uint32_t binding; - uint32_t set; - } word_offset; - - SpvReflectDecorationFlags decoration_flags; - // Requires SPV_GOOGLE_user_type - SpvReflectUserType user_type; -} SpvReflectDescriptorBinding; - -/*! @struct SpvReflectDescriptorSet - -*/ -typedef struct SpvReflectDescriptorSet { - uint32_t set; - uint32_t binding_count; - SpvReflectDescriptorBinding** bindings; -} SpvReflectDescriptorSet; - -typedef enum SpvReflectExecutionModeValue { - SPV_REFLECT_EXECUTION_MODE_SPEC_CONSTANT = 0xFFFFFFFF // specialization constant -} SpvReflectExecutionModeValue; - -/*! @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 SpvReflectSpecId - -*/ -typedef struct SpvReflectSpecializationConstant { - uint32_t spirv_id; - uint32_t constant_id; - const char* name; -} SpvReflectSpecializationConstant; - -/*! @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 - uint32_t spec_constant_count; // Uses value(s) from first entry point - SpvReflectSpecializationConstant* spec_constants; // 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 spvReflectEnumerateSpecializationConstants - @param p_module Pointer to an instance of SpvReflectShaderModule. - @param p_count If pp_blocks is NULL, the module's specialization constant - count will be stored here. If pp_blocks is not NULL, *p_count - must contain the module's specialization constant count. - @param pp_constants If NULL, the module's specialization constant 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 specialization constant blocks will be written. - The caller must not free the variables written to this array. - @return If successful, returns SPV_REFLECT_RESULT_SUCCESS. - Otherwise, the error code indicates the cause of the failure. -*/ -SpvReflectResult spvReflectEnumerateSpecializationConstants( - const SpvReflectShaderModule* p_module, - uint32_t* p_count, - SpvReflectSpecializationConstant** pp_constants -); - -/*! @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) && !defined(SPIRV_REFLECT_DISABLE_CPP_BINDINGS) -#include -#include -#include - -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& code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE); - ShaderModule(const std::vector& 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); - } - SpvReflectResult EnumerateSpecializationConstants(uint32_t* p_count, SpvReflectSpecializationConstant** pp_constants) const; - - 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& code, SpvReflectModuleFlags flags) { - m_result = spvReflectCreateShaderModule2( - flags, - code.size(), - code.data(), - &m_module); -} - -/*! @fn ShaderModule - - @param code - -*/ -inline ShaderModule::ShaderModule(const std::vector& 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 GetSourceFile - - @return Returns source file - -*/ -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 EnumerateSpecializationConstants - @param p_count - @param pp_constants - @return -*/ -inline SpvReflectResult ShaderModule::EnumerateSpecializationConstants( - uint32_t* p_count, - SpvReflectSpecializationConstant** pp_constants -) const -{ - m_result = spvReflectEnumerateSpecializationConstants( - &m_module, - p_count, - pp_constants - ); - 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) && !defined(SPIRV_REFLECT_DISABLE_CPP_WRAPPER) -#endif // SPIRV_REFLECT_H - -// clang-format on diff --git a/WickedEngine/WickedEngine_SOURCE.vcxitems b/WickedEngine/WickedEngine_SOURCE.vcxitems index d58b3b1e5..b250f279c 100644 --- a/WickedEngine/WickedEngine_SOURCE.vcxitems +++ b/WickedEngine/WickedEngine_SOURCE.vcxitems @@ -345,9 +345,7 @@ - - @@ -629,16 +627,6 @@ - - false - false - false - false - false - false - false - false - false false diff --git a/WickedEngine/WickedEngine_SOURCE.vcxitems.filters b/WickedEngine/WickedEngine_SOURCE.vcxitems.filters index ac7e1a749..b2c2a13eb 100644 --- a/WickedEngine/WickedEngine_SOURCE.vcxitems.filters +++ b/WickedEngine/WickedEngine_SOURCE.vcxitems.filters @@ -399,12 +399,6 @@ ENGINE\Input - - UTILITY - - - UTILITY - UTILITY @@ -1697,9 +1691,6 @@ UTILITY - - UTILITY - ENGINE\Graphics\API diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index f8b708f47..bc5afe20c 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -14,8 +14,6 @@ #define VOLK_IMPLEMENTATION #include "Utility/volk.h" -#include "Utility/spirv_reflect.h" - #define VMA_IMPLEMENTATION #define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 @@ -48,6 +46,17 @@ namespace vulkan_internal VULKAN_BINDING_SHIFT_S = 3000, }; + // Note: limiting descriptors by constant amount is needed, because the bindless sets are bound to multiple slots to match DX12 layout + // And binding to multiple slot adds up towards limits, so the limits will be quickly reached for some descriptor types + // But not all descriptor types have this problem, like storage buffers that are not bound for multiple slots usually + // Ideally, this shouldn't be the case, because Vulkan could have it's own layout in shaders + static constexpr uint32_t limit_bindless_descriptors = 100000u; + + static constexpr uint32_t pushcosntant_count = 22; + + static constexpr uint32_t dynamic_cbv_count = 3; + static constexpr uint64_t dynamic_cbv_maxsize = 64 * 1024; + // Converters: constexpr VkFormat _ConvertFormat(Format value) { @@ -900,20 +909,6 @@ namespace vulkan_internal VkShaderModule shaderModule = VK_NULL_HANDLE; VkPipeline pipeline_cs = VK_NULL_HANDLE; VkPipelineShaderStageCreateInfo stageInfo = {}; - wi::allocator::shared_ptr layout_lifetime; // lifetime management only - VkPipelineLayout pipelineLayout_cs = VK_NULL_HANDLE; // no lifetime management here - VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; // no lifetime management here - wi::vector layoutBindings; - wi::vector imageViewTypes; - - wi::vector bindlessBindings; - wi::vector bindlessSets; - uint32_t bindlessFirstSet = 0; - - VkPushConstantRange pushconstants = {}; - - VkDeviceSize uniform_buffer_sizes[DESCRIPTORBINDER_CBV_COUNT] = {}; - wi::vector uniform_buffer_dynamic_slots; ~Shader_Vulkan() { @@ -930,20 +925,6 @@ namespace vulkan_internal { wi::allocator::shared_ptr allocationhandler; VkPipeline pipeline = VK_NULL_HANDLE; - wi::allocator::shared_ptr layout_lifetime; // lifetime management only - VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; // no lifetime management here - VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; // no lifetime management here - wi::vector layoutBindings; - wi::vector imageViewTypes; - - wi::vector bindlessBindings; - wi::vector bindlessSets; - uint32_t bindlessFirstSet = 0; - - VkPushConstantRange pushconstants = {}; - - VkDeviceSize uniform_buffer_sizes[DESCRIPTORBINDER_CBV_COUNT] = {}; - wi::vector uniform_buffer_dynamic_slots; VkGraphicsPipelineCreateInfo pipelineInfo = {}; VkPipelineShaderStageCreateInfo shaderStages[static_cast(ShaderStage::Count)] = {}; @@ -1563,56 +1544,21 @@ using namespace vulkan_internal; this->device = device; // Create descriptor pool: - VkDescriptorPoolSize poolSizes[10] = {}; - uint32_t count = 0; - - poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - poolSizes[0].descriptorCount = DESCRIPTORBINDER_CBV_COUNT * poolSize; - count++; - - poolSizes[1].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; - poolSizes[1].descriptorCount = DESCRIPTORBINDER_CBV_COUNT * poolSize; - count++; - - poolSizes[2].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - poolSizes[2].descriptorCount = DESCRIPTORBINDER_SRV_COUNT * poolSize; - count++; - - poolSizes[3].type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - poolSizes[3].descriptorCount = DESCRIPTORBINDER_SRV_COUNT * poolSize; - count++; - - poolSizes[4].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - poolSizes[4].descriptorCount = DESCRIPTORBINDER_SRV_COUNT * poolSize; - count++; - - poolSizes[5].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - poolSizes[5].descriptorCount = DESCRIPTORBINDER_UAV_COUNT * poolSize; - count++; - - poolSizes[6].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; - poolSizes[6].descriptorCount = DESCRIPTORBINDER_UAV_COUNT * poolSize; - count++; - - poolSizes[7].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - poolSizes[7].descriptorCount = DESCRIPTORBINDER_UAV_COUNT * poolSize; - count++; - - poolSizes[8].type = VK_DESCRIPTOR_TYPE_SAMPLER; - poolSizes[8].descriptorCount = DESCRIPTORBINDER_SAMPLER_COUNT * poolSize; - count++; - + StackVector poolSizes; + poolSizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, DESCRIPTORBINDER_CBV_COUNT * poolSize }); + poolSizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DESCRIPTORBINDER_CBV_COUNT * poolSize }); + poolSizes.push_back({ VK_DESCRIPTOR_TYPE_MUTABLE_EXT, DESCRIPTORBINDER_SRV_COUNT * poolSize }); + poolSizes.push_back({ VK_DESCRIPTOR_TYPE_MUTABLE_EXT, DESCRIPTORBINDER_UAV_COUNT * poolSize }); + poolSizes.push_back({ VK_DESCRIPTOR_TYPE_SAMPLER, DESCRIPTORBINDER_SAMPLER_COUNT * poolSize }); if (device->CheckCapability(GraphicsDeviceCapability::RAYTRACING)) { - poolSizes[9].type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR; - poolSizes[9].descriptorCount = DESCRIPTORBINDER_SRV_COUNT * poolSize; - count++; + poolSizes.push_back({ VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, DESCRIPTORBINDER_SRV_COUNT * poolSize }); } VkDescriptorPoolCreateInfo poolInfo = {}; poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - poolInfo.poolSizeCount = count; - poolInfo.pPoolSizes = poolSizes; + poolInfo.poolSizeCount = poolSizes.size(); + poolInfo.pPoolSizes = poolSizes.data(); poolInfo.maxSets = poolSize; destroy(); // issues destroy if already exists, nop otherwise @@ -1651,18 +1597,12 @@ using namespace vulkan_internal; void GraphicsDevice_Vulkan::DescriptorBinder::init(GraphicsDevice_Vulkan* device) { this->device = device; - - // Important that these don't reallocate themselves during writing descriptors! - descriptorWrites.reserve(128); - bufferInfos.reserve(128); - imageInfos.reserve(128); - texelBufferViews.reserve(128); - accelerationStructureViews.reserve(128); } void GraphicsDevice_Vulkan::DescriptorBinder::reset() { table = {}; dirty = true; + descriptorSet = VK_NULL_HANDLE; } void GraphicsDevice_Vulkan::DescriptorBinder::flush(bool graphics, CommandList cmd) { @@ -1674,34 +1614,13 @@ using namespace vulkan_internal; auto cs_internal = graphics ? nullptr : to_internal(commandlist.active_cs); VkCommandBuffer commandBuffer = commandlist.GetCommandBuffer(); - VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; - VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; - VkDescriptorSet descriptorSet = VK_NULL_HANDLE; - uint32_t uniform_buffer_dynamic_count = 0; - if (graphics) + uint32_t uniform_buffer_dynamic_offsets[dynamic_cbv_count] = {}; + for (size_t i = 0; i < arraysize(uniform_buffer_dynamic_offsets); ++i) { - pipelineLayout = pso_internal->pipelineLayout; - descriptorSetLayout = pso_internal->descriptorSetLayout; - descriptorSet = descriptorSet_graphics; - uniform_buffer_dynamic_count = (uint32_t)pso_internal->uniform_buffer_dynamic_slots.size(); - for (size_t i = 0; i < pso_internal->uniform_buffer_dynamic_slots.size(); ++i) - { - uniform_buffer_dynamic_offsets[i] = (uint32_t)table.CBV_offset[pso_internal->uniform_buffer_dynamic_slots[i]]; - } - } - else - { - pipelineLayout = cs_internal->pipelineLayout_cs; - descriptorSetLayout = cs_internal->descriptorSetLayout; - descriptorSet = descriptorSet_compute; - uniform_buffer_dynamic_count = (uint32_t)cs_internal->uniform_buffer_dynamic_slots.size(); - for (size_t i = 0; i < cs_internal->uniform_buffer_dynamic_slots.size(); ++i) - { - uniform_buffer_dynamic_offsets[i] = (uint32_t)table.CBV_offset[cs_internal->uniform_buffer_dynamic_slots[i]]; - } + uniform_buffer_dynamic_offsets[i] = table.CBV[i].IsValid() ? (uint32_t)table.CBV_offset[i] : 0; } - if (dirty & DIRTY_DESCRIPTOR) + if (descriptorSet == VK_NULL_HANDLE || (dirty & DIRTY_DESCRIPTOR)) { auto& binder_pool = commandlist.binder_pools[device->GetBufferIndex()]; @@ -1709,7 +1628,7 @@ using namespace vulkan_internal; allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; allocInfo.descriptorPool = binder_pool.descriptorPool; allocInfo.descriptorSetCount = 1; - allocInfo.pSetLayouts = &descriptorSetLayout; + allocInfo.pSetLayouts = &device->descriptor_set_layouts[DESCRIPTOR_SET_BINDINGS]; VkResult res = vkAllocateDescriptorSets(device->device, &allocInfo, &descriptorSet); while (res == VK_ERROR_OUT_OF_POOL_MEMORY) @@ -1721,353 +1640,178 @@ using namespace vulkan_internal; } vulkan_assert(res >= VK_SUCCESS, "vkAllocateDescriptorSets"); - descriptorWrites.clear(); - bufferInfos.clear(); - imageInfos.clear(); - texelBufferViews.clear(); - accelerationStructureViews.clear(); + StackVector descriptorWrites; + StackVector bufferInfos; + StackVector imageInfos; // samplers also here + StackVector accelerationStructureViews; + VkDescriptorBufferInfo nullBufferInfo = {}; + nullBufferInfo.buffer = device->nullBuffer; + nullBufferInfo.range = VK_WHOLE_SIZE; - const auto& layoutBindings = graphics ? pso_internal->layoutBindings : cs_internal->layoutBindings; - const auto& imageViewTypes = graphics ? pso_internal->imageViewTypes : cs_internal->imageViewTypes; - - - int i = 0; - for (auto& x : layoutBindings) + for (uint32_t i = 0; i < arraysize(table.CBV); ++i) { - if (x.pImmutableSamplers != nullptr) + const GPUBuffer& buffer = table.CBV[i]; + auto& info = bufferInfos.emplace_back(); + info = {}; + auto& write = descriptorWrites.emplace_back(); + write = {}; + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.descriptorType = i < dynamic_cbv_count ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + write.dstBinding = VULKAN_BINDING_SHIFT_B + i; + write.descriptorCount = 1; + write.dstSet = descriptorSet; + write.pBufferInfo = &info; + + if (buffer.IsValid()) { - i++; - continue; + auto internal_state = to_internal(&buffer); + info.buffer = internal_state->resource; + info.offset = i < dynamic_cbv_count ? 0 : table.CBV_offset[i]; + info.range = std::min(dynamic_cbv_maxsize, buffer.desc.size - table.CBV_offset[i]); + } + else + { + write.pBufferInfo = &nullBufferInfo; + } + } + + for (uint32_t i = 0; i < arraysize(table.SRV); ++i) + { + const GPUResource& res = table.SRV[i]; + auto& write = descriptorWrites.emplace_back(); + write = {}; + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.dstBinding = VULKAN_BINDING_SHIFT_T + i; + write.descriptorCount = 1; + write.dstSet = descriptorSet; + + if (res.IsValid()) + { + if (res.IsBuffer()) + { + auto internal_state = to_internal(&res); + int subresource = table.SRV_index[i]; + auto& descriptor = subresource >= 0 ? internal_state->subresources_srv[subresource] : internal_state->srv; + if (descriptor.is_typed) + { + write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + write.pTexelBufferView = &descriptor.buffer_view; + } + else + { + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write.pBufferInfo = &descriptor.buffer_info; + } + } + else if (res.IsTexture()) + { + auto internal_state = to_internal(&res); + int subresource = table.SRV_index[i]; + auto& descriptor = subresource >= 0 ? internal_state->subresources_srv[subresource] : internal_state->srv; + auto& info = imageInfos.emplace_back(); + info = {}; + info.imageView = descriptor.image_view; + info.imageLayout = internal_state->defaultLayout; + write.pImageInfo = &info; + write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + } + else if (res.IsAccelerationStructure()) + { + auto internal_state = to_internal(&res); + auto& info = accelerationStructureViews.emplace_back(); + info = {}; + info.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR; + info.accelerationStructureCount = 1; + info.pAccelerationStructures = &internal_state->resource; + write.pNext = &info; + write.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR; + } + } + else + { + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write.pBufferInfo = &nullBufferInfo; + } + } + + for (uint32_t i = 0; i < arraysize(table.UAV); ++i) + { + const GPUResource& res = table.UAV[i]; + auto& write = descriptorWrites.emplace_back(); + write = {}; + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.dstBinding = VULKAN_BINDING_SHIFT_U + i; + write.descriptorCount = 1; + write.dstSet = descriptorSet; + + if (res.IsValid()) + { + if (res.IsBuffer()) + { + auto internal_state = to_internal(&res); + int subresource = table.UAV_index[i]; + auto& descriptor = subresource >= 0 ? internal_state->subresources_uav[subresource] : internal_state->uav; + if (descriptor.is_typed) + { + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + write.pTexelBufferView = &descriptor.buffer_view; + } + else + { + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write.pBufferInfo = &descriptor.buffer_info; + } + } + else if (res.IsTexture()) + { + auto internal_state = to_internal(&res); + int subresource = table.UAV_index[i]; + auto& descriptor = subresource >= 0 ? internal_state->subresources_uav[subresource] : internal_state->uav; + auto& info = imageInfos.emplace_back(); + info = {}; + info.imageView = descriptor.image_view; + info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + write.pImageInfo = &info; + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + } + } + else + { + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write.pBufferInfo = &nullBufferInfo; + } + } + + for (uint32_t i = 0; i < arraysize(table.SAM); ++i) + { + const Sampler& sam = table.SAM[i]; + auto& write = descriptorWrites.emplace_back(); + write = {}; + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.dstBinding = VULKAN_BINDING_SHIFT_S + i; + write.descriptorCount = 1; + write.dstSet = descriptorSet; + write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + auto& info = imageInfos.emplace_back(); + info = {}; + write.pImageInfo = &info; + + if (sam.IsValid()) + { + auto internal_state = to_internal(&sam); + info.sampler = internal_state->resource; + } + else + { + info.sampler = device->nullSampler; } - VkImageViewType viewtype = imageViewTypes[i++]; - - for (uint32_t descriptor_index = 0; descriptor_index < x.descriptorCount; ++descriptor_index) - { - uint32_t unrolled_binding = x.binding + descriptor_index; - - descriptorWrites.emplace_back(); - auto& write = descriptorWrites.back(); - write = {}; - write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write.dstSet = descriptorSet; - write.dstArrayElement = descriptor_index; - write.descriptorType = x.descriptorType; - write.dstBinding = x.binding; - write.descriptorCount = 1; - - switch (x.descriptorType) - { - case VK_DESCRIPTOR_TYPE_SAMPLER: - { - imageInfos.emplace_back(); - write.pImageInfo = &imageInfos.back(); - imageInfos.back() = {}; - - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_S; - const Sampler& sampler = table.SAM[original_binding]; - if (!sampler.IsValid()) - { - imageInfos.back().sampler = device->nullSampler; - } - else - { - imageInfos.back().sampler = to_internal(&sampler)->resource; - } - } - break; - - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - { - imageInfos.emplace_back(); - write.pImageInfo = &imageInfos.back(); - imageInfos.back() = {}; - - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_T; - const GPUResource& resource = table.SRV[original_binding]; - if (!resource.IsValid() || !resource.IsTexture()) - { - switch (viewtype) - { - case VK_IMAGE_VIEW_TYPE_1D: - imageInfos.back().imageView = device->nullImageView1D; - break; - case VK_IMAGE_VIEW_TYPE_2D: - imageInfos.back().imageView = device->nullImageView2D; - break; - case VK_IMAGE_VIEW_TYPE_3D: - imageInfos.back().imageView = device->nullImageView3D; - break; - case VK_IMAGE_VIEW_TYPE_CUBE: - imageInfos.back().imageView = device->nullImageViewCube; - break; - case VK_IMAGE_VIEW_TYPE_1D_ARRAY: - imageInfos.back().imageView = device->nullImageView1DArray; - break; - case VK_IMAGE_VIEW_TYPE_2D_ARRAY: - imageInfos.back().imageView = device->nullImageView2DArray; - break; - case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: - imageInfos.back().imageView = device->nullImageViewCubeArray; - break; - case VK_IMAGE_VIEW_TYPE_MAX_ENUM: - break; - default: - break; - } - imageInfos.back().imageLayout = VK_IMAGE_LAYOUT_GENERAL; - } - else - { - int subresource = table.SRV_index[original_binding]; - auto texture_internal = to_internal(&resource); - auto& subresource_descriptor = subresource >= 0 ? texture_internal->subresources_srv[subresource] : texture_internal->srv; - imageInfos.back().imageView = subresource_descriptor.image_view; - imageInfos.back().imageLayout = texture_internal->defaultLayout; - } - } - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - { - imageInfos.emplace_back(); - write.pImageInfo = &imageInfos.back(); - imageInfos.back() = {}; - imageInfos.back().imageLayout = VK_IMAGE_LAYOUT_GENERAL; - - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_U; - const GPUResource& resource = table.UAV[original_binding]; - if (!resource.IsValid() || !resource.IsTexture()) - { - switch (viewtype) - { - case VK_IMAGE_VIEW_TYPE_1D: - imageInfos.back().imageView = device->nullImageView1D; - break; - case VK_IMAGE_VIEW_TYPE_2D: - imageInfos.back().imageView = device->nullImageView2D; - break; - case VK_IMAGE_VIEW_TYPE_3D: - imageInfos.back().imageView = device->nullImageView3D; - break; - case VK_IMAGE_VIEW_TYPE_CUBE: - imageInfos.back().imageView = device->nullImageViewCube; - break; - case VK_IMAGE_VIEW_TYPE_1D_ARRAY: - imageInfos.back().imageView = device->nullImageView1DArray; - break; - case VK_IMAGE_VIEW_TYPE_2D_ARRAY: - imageInfos.back().imageView = device->nullImageView2DArray; - break; - case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: - imageInfos.back().imageView = device->nullImageViewCubeArray; - break; - case VK_IMAGE_VIEW_TYPE_MAX_ENUM: - break; - default: - break; - } - } - else - { - int subresource = table.UAV_index[original_binding]; - auto texture_internal = to_internal(&resource); - auto& subresource_descriptor = subresource >= 0 ? texture_internal->subresources_uav[subresource] : texture_internal->uav; - imageInfos.back().imageView = subresource_descriptor.image_view; - } - } - break; - - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - { - bufferInfos.emplace_back(); - write.pBufferInfo = &bufferInfos.back(); - bufferInfos.back() = {}; - - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_B; - const GPUBuffer& buffer = table.CBV[original_binding]; - uint64_t offset = table.CBV_offset[original_binding]; - - if (!buffer.IsValid()) - { - bufferInfos.back().buffer = device->nullBuffer; - bufferInfos.back().range = VK_WHOLE_SIZE; - } - else - { - auto internal_state = to_internal(&buffer); - bufferInfos.back().buffer = internal_state->resource; - bufferInfos.back().offset = offset; - if (graphics) - { - bufferInfos.back().range = pso_internal->uniform_buffer_sizes[original_binding]; - } - else - { - bufferInfos.back().range = cs_internal->uniform_buffer_sizes[original_binding]; - } - if (bufferInfos.back().range == 0ull) - { - bufferInfos.back().range = VK_WHOLE_SIZE; - } - } - } - break; - - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - { - bufferInfos.emplace_back(); - write.pBufferInfo = &bufferInfos.back(); - bufferInfos.back() = {}; - - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_B; - const GPUBuffer& buffer = table.CBV[original_binding]; - - if (!buffer.IsValid()) - { - bufferInfos.back().buffer = device->nullBuffer; - bufferInfos.back().range = VK_WHOLE_SIZE; - } - else - { - auto internal_state = to_internal(&buffer); - bufferInfos.back().buffer = internal_state->resource; - if (graphics) - { - bufferInfos.back().range = pso_internal->uniform_buffer_sizes[original_binding]; - } - else - { - bufferInfos.back().range = cs_internal->uniform_buffer_sizes[original_binding]; - } - if (bufferInfos.back().range == 0ull) - { - bufferInfos.back().range = VK_WHOLE_SIZE; - } - } - } - break; - - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - { - texelBufferViews.emplace_back(); - write.pTexelBufferView = &texelBufferViews.back(); - texelBufferViews.back() = {}; - - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_T; - const GPUResource& resource = table.SRV[original_binding]; - if (!resource.IsValid() || !resource.IsBuffer()) - { - texelBufferViews.back() = device->nullBufferView; - } - else - { - int subresource = table.SRV_index[original_binding]; - auto buffer_internal = to_internal(&resource); - auto& subresource_descriptor = subresource >= 0 ? buffer_internal->subresources_srv[subresource] : buffer_internal->srv; - texelBufferViews.back() = subresource_descriptor.buffer_view; - } - } - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - { - texelBufferViews.emplace_back(); - write.pTexelBufferView = &texelBufferViews.back(); - texelBufferViews.back() = {}; - - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_U; - const GPUResource& resource = table.UAV[original_binding]; - if (!resource.IsValid() || !resource.IsBuffer()) - { - texelBufferViews.back() = device->nullBufferView; - } - else - { - int subresource = table.UAV_index[original_binding]; - auto buffer_internal = to_internal(&resource); - auto& subresource_descriptor = subresource >= 0 ? buffer_internal->subresources_uav[subresource] : buffer_internal->uav; - texelBufferViews.back() = subresource_descriptor.buffer_view; - } - } - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - { - bufferInfos.emplace_back(); - write.pBufferInfo = &bufferInfos.back(); - bufferInfos.back() = {}; - - if (x.binding < VULKAN_BINDING_SHIFT_U) - { - // SRV - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_T; - const GPUResource& resource = table.SRV[original_binding]; - if (!resource.IsValid() || !resource.IsBuffer()) - { - bufferInfos.back().buffer = device->nullBuffer; - bufferInfos.back().range = VK_WHOLE_SIZE; - } - else - { - int subresource = table.SRV_index[original_binding]; - auto buffer_internal = to_internal(&resource); - auto& subresource_descriptor = subresource >= 0 ? buffer_internal->subresources_srv[subresource] : buffer_internal->srv; - bufferInfos.back() = subresource_descriptor.buffer_info; - } - } - else - { - // UAV - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_U; - const GPUResource& resource = table.UAV[original_binding]; - if (!resource.IsValid() || !resource.IsBuffer()) - { - bufferInfos.back().buffer = device->nullBuffer; - bufferInfos.back().range = VK_WHOLE_SIZE; - } - else - { - int subresource = table.UAV_index[original_binding]; - auto buffer_internal = to_internal(&resource); - auto& subresource_descriptor = subresource >= 0 ? buffer_internal->subresources_uav[subresource] : buffer_internal->uav; - bufferInfos.back() = subresource_descriptor.buffer_info; - } - } - } - break; - - case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: - { - accelerationStructureViews.emplace_back(); - write.pNext = &accelerationStructureViews.back(); - accelerationStructureViews.back() = {}; - accelerationStructureViews.back().sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR; - accelerationStructureViews.back().accelerationStructureCount = 1; - - const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_T; - const GPUResource& resource = table.SRV[original_binding]; - if (!resource.IsValid() || !resource.IsAccelerationStructure()) - { - assert(0); // invalid acceleration structure! - } - else - { - auto as_internal = to_internal(&resource); - accelerationStructureViews.back().pAccelerationStructures = &as_internal->resource; - } - } - break; - - default: break; - } - - } + assert(info.sampler != nullptr); } vkUpdateDescriptorSets( device->device, - (uint32_t)descriptorWrites.size(), + descriptorWrites.size(), descriptorWrites.data(), 0, nullptr @@ -2087,25 +1831,14 @@ using namespace vulkan_internal; vkCmdBindDescriptorSets( commandBuffer, bindPoint, - pipelineLayout, + device->pipeline_layout, 0, 1, &descriptorSet, - uniform_buffer_dynamic_count, + arraysize(uniform_buffer_dynamic_offsets), uniform_buffer_dynamic_offsets ); - // Save last used descriptor set handles: - // This is needed to handle the case when descriptorSet is not allocated, but only dynamic offsets are updated - if (graphics) - { - descriptorSet_graphics = descriptorSet; - } - else - { - descriptorSet_compute = descriptorSet; - } - dirty = DIRTY_NONE; } @@ -2541,6 +2274,7 @@ using namespace vulkan_internal; fragment_shading_rate_features = {}; mesh_shader_features = {}; conditional_rendering_features = {}; + mutable_descriptor_features = {}; depth_clip_enable_features = {}; properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; @@ -2654,6 +2388,14 @@ using namespace vulkan_internal; features_chain = &conditional_rendering_features.pNext; } + if (checkExtensionSupport(VK_EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME, available_deviceExtensions)) + { + enabled_deviceExtensions.push_back(VK_EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME); + mutable_descriptor_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT; + *features_chain = &mutable_descriptor_features; + features_chain = &mutable_descriptor_features.pNext; + } + if (checkExtensionSupport(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME, available_deviceExtensions) && checkExtensionSupport(VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME, available_deviceExtensions)) { @@ -2756,6 +2498,7 @@ using namespace vulkan_internal; assert(features2.features.occlusionQueryPrecise == VK_TRUE); assert(features_1_2.descriptorIndexing == VK_TRUE); assert(features_1_3.dynamicRendering == VK_TRUE); + assert(mutable_descriptor_features.mutableDescriptorType == VK_TRUE); // Init adapter properties vendorId = properties2.properties.vendorID; @@ -2811,7 +2554,7 @@ using namespace vulkan_internal; } if (mesh_shader_features.meshShader == VK_TRUE && mesh_shader_features.taskShader == VK_TRUE) { - // Disable Vulkan mesh shader for now because it can crash AMD driver just by compiling shader, without any warnings + // Mesh shader still has issues on Vulkan: https://github.com/microsoft/DirectXShaderCompiler/issues/6862 //capabilities |= GraphicsDeviceCapability::MESH_SHADER; } if (fragment_shading_rate_features.pipelineFragmentShadingRate == VK_TRUE) @@ -3427,40 +3170,287 @@ using namespace vulkan_internal; dynamicStateInfo_MeshShader.pDynamicStates = pso_dynamicStates.data(); dynamicStateInfo_MeshShader.dynamicStateCount = (uint32_t)pso_dynamicStates.size() - 1; // don't include VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE for mesh shader - // Note: limiting descriptors by constant amount is needed, because the bindless sets are bound to multiple slots to match DX12 layout - // And binding to multiple slot adds up towards limits, so the limits will be quickly reached for some descriptor types - // But not all descriptor types have this problem, like storage buffers that are not bound for multiple slots usually - // Ideally, this shouldn't be the case, because Vulkan could have it's own layout in shaders - const uint32_t limit_bindless_descriptors = 100000u; + // Static samplers: + { + VkSamplerCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + createInfo.pNext = nullptr; + createInfo.flags = 0; + createInfo.compareEnable = false; + createInfo.compareOp = VK_COMPARE_OP_NEVER; + createInfo.minLod = 0; + createInfo.maxLod = FLT_MAX; + createInfo.mipLodBias = 0; + createInfo.anisotropyEnable = false; + createInfo.maxAnisotropy = 0; + // sampler_linear_clamp: + createInfo.minFilter = VK_FILTER_LINEAR; + createInfo.magFilter = VK_FILTER_LINEAR; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[0])); + + // sampler_linear_wrap: + createInfo.minFilter = VK_FILTER_LINEAR; + createInfo.magFilter = VK_FILTER_LINEAR; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[1])); + + //sampler_linear_mirror: + createInfo.minFilter = VK_FILTER_LINEAR; + createInfo.magFilter = VK_FILTER_LINEAR; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[2])); + + // sampler_point_clamp: + createInfo.minFilter = VK_FILTER_NEAREST; + createInfo.magFilter = VK_FILTER_NEAREST; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[3])); + + // sampler_point_wrap: + createInfo.minFilter = VK_FILTER_NEAREST; + createInfo.magFilter = VK_FILTER_NEAREST; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[4])); + + // sampler_point_mirror: + createInfo.minFilter = VK_FILTER_NEAREST; + createInfo.magFilter = VK_FILTER_NEAREST; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[5])); + + // sampler_aniso_clamp: + createInfo.minFilter = VK_FILTER_LINEAR; + createInfo.magFilter = VK_FILTER_LINEAR; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.anisotropyEnable = true; + createInfo.maxAnisotropy = 16; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[6])); + + // sampler_aniso_wrap: + createInfo.minFilter = VK_FILTER_LINEAR; + createInfo.magFilter = VK_FILTER_LINEAR; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + createInfo.anisotropyEnable = true; + createInfo.maxAnisotropy = 16; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[7])); + + // sampler_aniso_mirror: + createInfo.minFilter = VK_FILTER_LINEAR; + createInfo.magFilter = VK_FILTER_LINEAR; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + createInfo.anisotropyEnable = true; + createInfo.maxAnisotropy = 16; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[8])); + + // sampler_cmp_depth: + createInfo.minFilter = VK_FILTER_LINEAR; + createInfo.magFilter = VK_FILTER_LINEAR; + createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.anisotropyEnable = false; + createInfo.maxAnisotropy = 0; + createInfo.compareEnable = true; + createInfo.compareOp = VK_COMPARE_OP_GREATER_OR_EQUAL; + createInfo.minLod = 0; + createInfo.maxLod = 0; + vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers[9])); + } + + // Bindings: + { + const VkDescriptorType allowed_types_srv[] = { + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR + }; + + const VkDescriptorType allowed_types_uav[] = { + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, + }; + + struct MutableTypeLists + { + VkMutableDescriptorTypeListEXT CBV[DESCRIPTORBINDER_CBV_COUNT] = {}; + VkMutableDescriptorTypeListEXT SRV[DESCRIPTORBINDER_SRV_COUNT] = {}; + VkMutableDescriptorTypeListEXT UAV[DESCRIPTORBINDER_SRV_COUNT] = {}; + VkMutableDescriptorTypeListEXT SAM[DESCRIPTORBINDER_SAMPLER_COUNT] = {}; + VkMutableDescriptorTypeListEXT IMMUTABLE_SAM[arraysize(immutable_samplers)] = {}; + } mutable_type_lists; + + uint32_t srv_type_count = arraysize(allowed_types_srv); + if (!CheckCapability(GraphicsDeviceCapability::RAYTRACING)) + { + // If raytracing not supported, remove this option from mutable descriptor type: + srv_type_count--; + } + for (uint32_t i = 0; i < arraysize(mutable_type_lists.SRV); ++i) + { + mutable_type_lists.SRV[i].pDescriptorTypes = allowed_types_srv; + mutable_type_lists.SRV[i].descriptorTypeCount = srv_type_count; + } + for (uint32_t i = 0; i < arraysize(mutable_type_lists.UAV); ++i) + { + mutable_type_lists.UAV[i].pDescriptorTypes = allowed_types_uav; + mutable_type_lists.UAV[i].descriptorTypeCount = arraysize(allowed_types_uav); + } + + VkMutableDescriptorTypeCreateInfoEXT mutable_info = {}; + mutable_info.sType = VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT; + mutable_info.pMutableDescriptorTypeLists = (const VkMutableDescriptorTypeListEXT*)&mutable_type_lists; + mutable_info.mutableDescriptorTypeListCount = sizeof(mutable_type_lists) / sizeof(VkMutableDescriptorTypeListEXT); + + struct VulkanDescriptorBindingTable + { + VkDescriptorSetLayoutBinding CBV[DESCRIPTORBINDER_CBV_COUNT] = {}; + VkDescriptorSetLayoutBinding SRV[DESCRIPTORBINDER_SRV_COUNT] = {}; + VkDescriptorSetLayoutBinding UAV[DESCRIPTORBINDER_UAV_COUNT] = {}; + VkDescriptorSetLayoutBinding SAM[DESCRIPTORBINDER_SAMPLER_COUNT] = {}; + VkDescriptorSetLayoutBinding IMMUTABLE_SAM[arraysize(immutable_samplers)] = {}; + } table; + + for (uint32_t i = 0; i < arraysize(table.CBV); ++i) + { + VkDescriptorSetLayoutBinding& binding = table.CBV[i]; + binding.binding = VULKAN_BINDING_SHIFT_B + i; + binding.descriptorCount = 1; + binding.descriptorType = i < dynamic_cbv_count ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + binding.stageFlags = VK_SHADER_STAGE_ALL; + } + for (uint32_t i = 0; i < arraysize(table.SRV); ++i) + { + VkDescriptorSetLayoutBinding& binding = table.SRV[i]; + binding.binding = VULKAN_BINDING_SHIFT_T + i; + binding.descriptorCount = 1; + binding.descriptorType = VK_DESCRIPTOR_TYPE_MUTABLE_EXT; + binding.stageFlags = VK_SHADER_STAGE_ALL; + } + for (uint32_t i = 0; i < arraysize(table.UAV); ++i) + { + VkDescriptorSetLayoutBinding& binding = table.UAV[i]; + binding.binding = VULKAN_BINDING_SHIFT_U + i; + binding.descriptorCount = 1; + binding.descriptorType = VK_DESCRIPTOR_TYPE_MUTABLE_EXT; + binding.stageFlags = VK_SHADER_STAGE_ALL; + } + for (uint32_t i = 0; i < arraysize(table.SAM); ++i) + { + VkDescriptorSetLayoutBinding& binding = table.SAM[i]; + binding.binding = VULKAN_BINDING_SHIFT_S + i; + binding.descriptorCount = 1; + binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + binding.stageFlags = VK_SHADER_STAGE_ALL; + } + for (uint32_t i = 0; i < arraysize(table.IMMUTABLE_SAM); ++i) + { + VkDescriptorSetLayoutBinding& binding = table.IMMUTABLE_SAM[i]; + binding.binding = VULKAN_BINDING_SHIFT_S + 100 + i; + binding.descriptorCount = 1; + binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + binding.stageFlags = VK_SHADER_STAGE_ALL; + binding.pImmutableSamplers = &immutable_samplers[i]; + } + + VkDescriptorSetLayoutCreateInfo layoutInfo = {}; + layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layoutInfo.bindingCount = sizeof(table) / sizeof(VkDescriptorSetLayoutBinding); + layoutInfo.pBindings = (const VkDescriptorSetLayoutBinding*)&table; + layoutInfo.pNext = &mutable_info; + + vulkan_check(vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptor_set_layouts[DESCRIPTOR_SET_BINDINGS])); + } + + // Bindless: if (features_1_2.descriptorBindingSampledImageUpdateAfterBind == VK_TRUE) { allocationhandler->bindlessSampledImages.init(this, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, std::min(limit_bindless_descriptors, properties_1_2.maxDescriptorSetUpdateAfterBindSampledImages / 4)); + descriptor_sets[DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE] = allocationhandler->bindlessSampledImages.descriptorSet; + descriptor_set_layouts[DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE] = allocationhandler->bindlessSampledImages.descriptorSetLayout; } if (features_1_2.descriptorBindingUniformTexelBufferUpdateAfterBind == VK_TRUE) { allocationhandler->bindlessUniformTexelBuffers.init(this, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, std::min(limit_bindless_descriptors, properties_1_2.maxDescriptorSetUpdateAfterBindSampledImages / 4)); + descriptor_sets[DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER] = allocationhandler->bindlessUniformTexelBuffers.descriptorSet; + descriptor_set_layouts[DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER] = allocationhandler->bindlessUniformTexelBuffers.descriptorSetLayout; } if (features_1_2.descriptorBindingStorageBufferUpdateAfterBind == VK_TRUE) { allocationhandler->bindlessStorageBuffers.init(this, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, properties_1_2.maxDescriptorSetUpdateAfterBindStorageBuffers / 4); + descriptor_sets[DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER] = allocationhandler->bindlessStorageBuffers.descriptorSet; + descriptor_set_layouts[DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER] = allocationhandler->bindlessStorageBuffers.descriptorSetLayout; } if (features_1_2.descriptorBindingStorageImageUpdateAfterBind == VK_TRUE) { allocationhandler->bindlessStorageImages.init(this, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, std::min(limit_bindless_descriptors, properties_1_2.maxDescriptorSetUpdateAfterBindStorageImages / 4)); + descriptor_sets[DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE] = allocationhandler->bindlessStorageImages.descriptorSet; + descriptor_set_layouts[DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE] = allocationhandler->bindlessStorageImages.descriptorSetLayout; } if (features_1_2.descriptorBindingStorageTexelBufferUpdateAfterBind == VK_TRUE) { allocationhandler->bindlessStorageTexelBuffers.init(this, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, std::min(limit_bindless_descriptors, properties_1_2.maxDescriptorSetUpdateAfterBindStorageImages / 4)); + descriptor_sets[DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER] = allocationhandler->bindlessStorageTexelBuffers.descriptorSet; + descriptor_set_layouts[DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER] = allocationhandler->bindlessStorageTexelBuffers.descriptorSetLayout; } if (features_1_2.descriptorBindingSampledImageUpdateAfterBind == VK_TRUE) { allocationhandler->bindlessSamplers.init(this, VK_DESCRIPTOR_TYPE_SAMPLER, 256); + descriptor_sets[DESCRIPTOR_SET_BINDLESS_SAMPLER] = allocationhandler->bindlessSamplers.descriptorSet; + descriptor_set_layouts[DESCRIPTOR_SET_BINDLESS_SAMPLER] = allocationhandler->bindlessSamplers.descriptorSetLayout; } if (CheckCapability(GraphicsDeviceCapability::RAYTRACING)) { allocationhandler->bindlessAccelerationStructures.init(this, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 32); + descriptor_sets[DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE] = allocationhandler->bindlessAccelerationStructures.descriptorSet; + descriptor_set_layouts[DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE] = allocationhandler->bindlessAccelerationStructures.descriptorSetLayout; + } + + // Pipeline layouts: + { + VkPushConstantRange range = {}; + range.size = sizeof(uint32_t) * pushcosntant_count; + range.stageFlags = VK_SHADER_STAGE_ALL; + + VkPipelineLayoutCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + info.pPushConstantRanges = ⦥ + info.pushConstantRangeCount = 1; + info.pSetLayouts = descriptor_set_layouts; + info.setLayoutCount = arraysize(descriptor_set_layouts); + vulkan_check(vkCreatePipelineLayout(device, &info, nullptr, &pipeline_layout)); } #ifdef VULKAN_PIPELINE_CACHE_ENABLED @@ -3531,123 +3521,6 @@ using namespace vulkan_internal; } #endif - // Static samplers: - { - VkSamplerCreateInfo createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - createInfo.pNext = nullptr; - createInfo.flags = 0; - createInfo.compareEnable = false; - createInfo.compareOp = VK_COMPARE_OP_NEVER; - createInfo.minLod = 0; - createInfo.maxLod = FLT_MAX; - createInfo.mipLodBias = 0; - createInfo.anisotropyEnable = false; - createInfo.maxAnisotropy = 0; - - // sampler_linear_clamp: - createInfo.minFilter = VK_FILTER_LINEAR; - createInfo.magFilter = VK_FILTER_LINEAR; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - - // sampler_linear_wrap: - createInfo.minFilter = VK_FILTER_LINEAR; - createInfo.magFilter = VK_FILTER_LINEAR; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - - //sampler_linear_mirror: - createInfo.minFilter = VK_FILTER_LINEAR; - createInfo.magFilter = VK_FILTER_LINEAR; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - - // sampler_point_clamp: - createInfo.minFilter = VK_FILTER_NEAREST; - createInfo.magFilter = VK_FILTER_NEAREST; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - - // sampler_point_wrap: - createInfo.minFilter = VK_FILTER_NEAREST; - createInfo.magFilter = VK_FILTER_NEAREST; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - - // sampler_point_mirror: - createInfo.minFilter = VK_FILTER_NEAREST; - createInfo.magFilter = VK_FILTER_NEAREST; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - - // sampler_aniso_clamp: - createInfo.minFilter = VK_FILTER_LINEAR; - createInfo.magFilter = VK_FILTER_LINEAR; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.anisotropyEnable = true; - createInfo.maxAnisotropy = 16; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - - // sampler_aniso_wrap: - createInfo.minFilter = VK_FILTER_LINEAR; - createInfo.magFilter = VK_FILTER_LINEAR; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - createInfo.anisotropyEnable = true; - createInfo.maxAnisotropy = 16; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - - // sampler_aniso_mirror: - createInfo.minFilter = VK_FILTER_LINEAR; - createInfo.magFilter = VK_FILTER_LINEAR; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - createInfo.anisotropyEnable = true; - createInfo.maxAnisotropy = 16; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - - // sampler_cmp_depth: - createInfo.minFilter = VK_FILTER_LINEAR; - createInfo.magFilter = VK_FILTER_LINEAR; - createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - createInfo.anisotropyEnable = false; - createInfo.maxAnisotropy = 0; - createInfo.compareEnable = true; - createInfo.compareOp = VK_COMPARE_OP_GREATER_OR_EQUAL; - createInfo.minLod = 0; - createInfo.maxLod = 0; - vulkan_check(vkCreateSampler(device, &createInfo, nullptr, &immutable_samplers.emplace_back())); - } - wilog("Created GraphicsDevice_Vulkan (%d ms)\nAdapter: %s", (int)std::round(timer.elapsed()), adapterName.c_str()); } GraphicsDevice_Vulkan::~GraphicsDevice_Vulkan() @@ -3683,8 +3556,6 @@ using namespace vulkan_internal; } } - pso_layout_cache.clear(); - for (auto& commandlist : commandlists) { for (int buffer = 0; buffer < BUFFERCOUNT; ++buffer) @@ -3708,6 +3579,13 @@ using namespace vulkan_internal; vkDestroyPipeline(device, x.second, nullptr); } + vkDestroyPipelineLayout(device, pipeline_layout, nullptr); + + for (auto& x : descriptor_set_layouts) + { + vkDestroyDescriptorSetLayout(device, x, nullptr); + } + for (auto& x : semaphore_pool) { vkDestroySemaphore(device, x, nullptr); @@ -3840,6 +3718,7 @@ using namespace vulkan_internal; if (has_flag(buffer->desc.bind_flags, BindFlag::CONSTANT_BUFFER)) { bufferInfo.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + bufferInfo.size = align(bufferInfo.size + dynamic_cbv_maxsize, dynamic_cbv_maxsize); // hack: padding for descriptor writes! } if (has_flag(buffer->desc.bind_flags, BindFlag::SHADER_RESOURCE)) { @@ -4774,256 +4653,11 @@ using namespace vulkan_internal; break; } - { - SpvReflectShaderModule module; - SpvReflectResult result = spvReflectCreateShaderModule(moduleInfo.codeSize, moduleInfo.pCode, &module); - assert(result == SPV_REFLECT_RESULT_SUCCESS); - - uint32_t binding_count = 0; - result = spvReflectEnumerateDescriptorBindings( - &module, &binding_count, nullptr - ); - assert(result == SPV_REFLECT_RESULT_SUCCESS); - - wi::vector bindings(binding_count); - result = spvReflectEnumerateDescriptorBindings( - &module, &binding_count, bindings.data() - ); - assert(result == SPV_REFLECT_RESULT_SUCCESS); - - uint32_t push_count = 0; - result = spvReflectEnumeratePushConstantBlocks(&module, &push_count, nullptr); - assert(result == SPV_REFLECT_RESULT_SUCCESS); - - wi::vector pushconstants(push_count); - result = spvReflectEnumeratePushConstantBlocks(&module, &push_count, pushconstants.data()); - assert(result == SPV_REFLECT_RESULT_SUCCESS); - - for (auto& x : pushconstants) - { - auto& push = internal_state->pushconstants; - push.stageFlags = internal_state->stageInfo.stage; - push.offset = x->offset; - push.size = x->size; - } - - for (auto& x : bindings) - { - // This has some issues atm with some specific shader, recheck in the future with different compiler version - //if (x->accessed == 0) - // continue; - const bool bindless = x->set > 0; - - if (bindless) - { - // There can be padding between bindless spaces because sets need to be bound contiguously - internal_state->bindlessBindings.resize(std::max(internal_state->bindlessBindings.size(), (size_t)x->set)); - internal_state->bindlessBindings[x->set - 1].used = true; - } - - auto& descriptor = bindless ? internal_state->bindlessBindings[x->set - 1].binding : internal_state->layoutBindings.emplace_back(); - descriptor.stageFlags = internal_state->stageInfo.stage; - descriptor.binding = x->binding; - descriptor.descriptorCount = x->count; - descriptor.descriptorType = (VkDescriptorType)x->descriptor_type; - - if (bindless) - continue; - - auto& imageViewType = internal_state->imageViewTypes.emplace_back(); - imageViewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - - if (x->descriptor_type == SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER && x->binding >= VULKAN_BINDING_SHIFT_S + immutable_sampler_slot_begin) - { - descriptor.pImmutableSamplers = immutable_samplers.data() + x->binding - VULKAN_BINDING_SHIFT_S - immutable_sampler_slot_begin; - continue; - } - - if (descriptor.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) - { - // For now, always replace VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER with VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC - // It would be quite messy to track which buffer is dynamic and which is not in the binding code, consider multiple pipeline bind points too - // But maybe the dynamic uniform buffer is not always best because it occupies more registers (like DX12 root descriptor)? - descriptor.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; - for (uint32_t i = 0; i < descriptor.descriptorCount; ++i) - { - internal_state->uniform_buffer_sizes[descriptor.binding + i] = x->block.size; - internal_state->uniform_buffer_dynamic_slots.push_back(descriptor.binding + i); - } - } - - switch (x->descriptor_type) - { - default: - break; - case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: - switch (x->image.dim) - { - default: - case SpvDim1D: - if (x->image.arrayed == 0) - { - imageViewType = VK_IMAGE_VIEW_TYPE_1D; - } - else - { - imageViewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY; - } - break; - case SpvDim2D: - if (x->image.arrayed == 0) - { - imageViewType = VK_IMAGE_VIEW_TYPE_2D; - } - else - { - imageViewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - } - break; - case SpvDim3D: - imageViewType = VK_IMAGE_VIEW_TYPE_3D; - break; - case SpvDimCube: - if (x->image.arrayed == 0) - { - imageViewType = VK_IMAGE_VIEW_TYPE_CUBE; - } - else - { - imageViewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; - } - break; - } - break; - } - } - - spvReflectDestroyShaderModule(&module); - - if (stage == ShaderStage::CS || stage == ShaderStage::LIB) - { - PSOLayoutHash layout_hasher; - size_t i = 0; - for (auto& x : internal_state->layoutBindings) - { - auto& item = layout_hasher.items.emplace_back(); - item.binding = x; - item.viewType = internal_state->imageViewTypes[i++]; - } - for (auto& x : internal_state->bindlessBindings) - { - auto& item = layout_hasher.items.emplace_back(); - item.binding = x.binding; - item.used = x.used; - } - layout_hasher.push = internal_state->pushconstants; - layout_hasher.embed_hash(); - - pso_layout_cache_mutex.lock(); - if (pso_layout_cache[layout_hasher] == nullptr) - { - wi::vector layouts; - - { - VkDescriptorSetLayoutCreateInfo descriptorSetlayoutInfo = {}; - descriptorSetlayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptorSetlayoutInfo.pBindings = internal_state->layoutBindings.data(); - descriptorSetlayoutInfo.bindingCount = uint32_t(internal_state->layoutBindings.size()); - vulkan_check(vkCreateDescriptorSetLayout(device, &descriptorSetlayoutInfo, nullptr, &internal_state->descriptorSetLayout)); - layouts.push_back(internal_state->descriptorSetLayout); - } - - internal_state->bindlessFirstSet = (uint32_t)layouts.size(); - for (auto& x : internal_state->bindlessBindings) - { - switch (x.binding.descriptorType) - { - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - assert(0); // not supported, use the raw buffers for same functionality - break; - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - layouts.push_back(allocationhandler->bindlessSampledImages.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessSampledImages.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - layouts.push_back(allocationhandler->bindlessUniformTexelBuffers.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessUniformTexelBuffers.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - layouts.push_back(allocationhandler->bindlessStorageBuffers.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessStorageBuffers.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - layouts.push_back(allocationhandler->bindlessStorageImages.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessStorageImages.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - layouts.push_back(allocationhandler->bindlessStorageTexelBuffers.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessStorageTexelBuffers.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_SAMPLER: - layouts.push_back(allocationhandler->bindlessSamplers.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessSamplers.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: - layouts.push_back(allocationhandler->bindlessAccelerationStructures.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessAccelerationStructures.descriptorSet); - break; - default: - break; - } - } - - VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; - pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutInfo.pSetLayouts = layouts.data(); - pipelineLayoutInfo.setLayoutCount = (uint32_t)layouts.size(); - if (internal_state->pushconstants.size > 0) - { - pipelineLayoutInfo.pushConstantRangeCount = 1; - pipelineLayoutInfo.pPushConstantRanges = &internal_state->pushconstants; - } - else - { - pipelineLayoutInfo.pushConstantRangeCount = 0; - pipelineLayoutInfo.pPushConstantRanges = nullptr; - } - - res = vulkan_check(vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &internal_state->pipelineLayout_cs)); - if (res == VK_SUCCESS) - { - auto& cached_layout = pso_layout_cache[layout_hasher]; - cached_layout = wi::allocator::make_shared(); - cached_layout->allocationhandler = allocationhandler; - cached_layout->descriptorSetLayout = internal_state->descriptorSetLayout; - cached_layout->pipelineLayout = internal_state->pipelineLayout_cs; - cached_layout->bindlessSets = internal_state->bindlessSets; - cached_layout->bindlessFirstSet = internal_state->bindlessFirstSet; - internal_state->layout_lifetime = cached_layout; - } - } - else - { - auto& cached_layout = pso_layout_cache[layout_hasher]; - internal_state->descriptorSetLayout = cached_layout->descriptorSetLayout; - internal_state->pipelineLayout_cs = cached_layout->pipelineLayout; - internal_state->bindlessSets = cached_layout->bindlessSets; - internal_state->bindlessFirstSet = cached_layout->bindlessFirstSet; - internal_state->layout_lifetime = cached_layout; - } - pso_layout_cache_mutex.unlock(); - } - } - if (stage == ShaderStage::CS) { - // sort because dynamic offsets array is tightly packed to match slot numbers: - std::sort(internal_state->uniform_buffer_dynamic_slots.begin(), internal_state->uniform_buffer_dynamic_slots.end()); - VkComputePipelineCreateInfo pipelineInfo = {}; pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - pipelineInfo.layout = internal_state->pipelineLayout_cs; + pipelineInfo.layout = pipeline_layout; pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; // Create compute pipeline state in place: @@ -5307,219 +4941,6 @@ using namespace vulkan_internal; VkResult res = VK_SUCCESS; - { - auto insert_shader = [&](const Shader* shader) { - if (shader == nullptr) - return; - auto shader_internal = to_internal(shader); - - uint32_t i = 0; - for (auto& x : shader_internal->layoutBindings) - { - bool found = false; - size_t j = 0; - for (auto& y : internal_state->layoutBindings) - { - if (x.binding == y.binding) - { - // If the asserts fire, it means there are overlapping bindings between shader stages - // This is not supported now for performance reasons (less binding management)! - // (Overlaps between s/b/t bind points are not a problem because those are shifted by the compiler) - assert(x.descriptorCount == y.descriptorCount); - assert(x.descriptorType == y.descriptorType); - found = true; - y.stageFlags |= x.stageFlags; - break; - } - } - - if (!found) - { - internal_state->layoutBindings.push_back(x); - internal_state->imageViewTypes.push_back(shader_internal->imageViewTypes[i]); - if (x.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || x.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) - { - for (uint32_t k = 0; k < x.descriptorCount; ++k) - { - internal_state->uniform_buffer_sizes[x.binding + k] = shader_internal->uniform_buffer_sizes[x.binding + k]; - } - } - if (x.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) - { - for (uint32_t k = 0; k < x.descriptorCount; ++k) - { - internal_state->uniform_buffer_dynamic_slots.push_back(x.binding + k); - } - } - } - i++; - } - - if (shader_internal->pushconstants.size > 0) - { - internal_state->pushconstants.offset = std::min(internal_state->pushconstants.offset, shader_internal->pushconstants.offset); - internal_state->pushconstants.size = std::max(internal_state->pushconstants.size, shader_internal->pushconstants.size); - internal_state->pushconstants.stageFlags |= shader_internal->pushconstants.stageFlags; - } - }; - - insert_shader(desc->ms); - insert_shader(desc->as); - insert_shader(desc->vs); - insert_shader(desc->hs); - insert_shader(desc->ds); - insert_shader(desc->gs); - insert_shader(desc->ps); - - // sort because dynamic offsets array is tightly packed to match slot numbers: - std::sort(internal_state->uniform_buffer_dynamic_slots.begin(), internal_state->uniform_buffer_dynamic_slots.end()); - - auto insert_shader_bindless = [&](const Shader* shader) { - if (shader == nullptr) - return; - auto shader_internal = to_internal(shader); - - internal_state->bindlessBindings.resize(std::max(internal_state->bindlessBindings.size(), shader_internal->bindlessBindings.size())); - - int i = 0; - for (auto& x : shader_internal->bindlessBindings) - { - if (x.used) - { - if (internal_state->bindlessBindings[i].binding.descriptorType != x.binding.descriptorType) - { - internal_state->bindlessBindings[i] = x; - } - else - { - internal_state->bindlessBindings[i].binding.stageFlags |= x.binding.stageFlags; - } - } - i++; - } - }; - - insert_shader_bindless(desc->ms); - insert_shader_bindless(desc->as); - insert_shader_bindless(desc->vs); - insert_shader_bindless(desc->hs); - insert_shader_bindless(desc->ds); - insert_shader_bindless(desc->gs); - insert_shader_bindless(desc->ps); - - PSOLayoutHash layout_hasher; - size_t i = 0; - for (auto& x : internal_state->layoutBindings) - { - auto& item = layout_hasher.items.emplace_back(); - item.binding = x; - item.viewType = internal_state->imageViewTypes[i++]; - } - for (auto& x : internal_state->bindlessBindings) - { - auto& item = layout_hasher.items.emplace_back(); - item.binding = x.binding; - item.used = x.used; - } - layout_hasher.push = internal_state->pushconstants; - layout_hasher.embed_hash(); - - pso_layout_cache_mutex.lock(); - if (pso_layout_cache[layout_hasher] == nullptr) - { - wi::vector layouts; - { - VkDescriptorSetLayoutCreateInfo descriptorSetlayoutInfo = {}; - descriptorSetlayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptorSetlayoutInfo.pBindings = internal_state->layoutBindings.data(); - descriptorSetlayoutInfo.bindingCount = static_cast(internal_state->layoutBindings.size()); - vulkan_check(vkCreateDescriptorSetLayout(device, &descriptorSetlayoutInfo, nullptr, &internal_state->descriptorSetLayout)); - layouts.push_back(internal_state->descriptorSetLayout); - } - - internal_state->bindlessFirstSet = (uint32_t)layouts.size(); - for (auto& x : internal_state->bindlessBindings) - { - switch (x.binding.descriptorType) - { - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - assert(0); // not supported, use the raw buffers for same functionality - break; - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - layouts.push_back(allocationhandler->bindlessSampledImages.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessSampledImages.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - layouts.push_back(allocationhandler->bindlessUniformTexelBuffers.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessUniformTexelBuffers.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - layouts.push_back(allocationhandler->bindlessStorageBuffers.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessStorageBuffers.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - layouts.push_back(allocationhandler->bindlessStorageImages.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessStorageImages.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - layouts.push_back(allocationhandler->bindlessStorageTexelBuffers.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessStorageTexelBuffers.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_SAMPLER: - layouts.push_back(allocationhandler->bindlessSamplers.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessSamplers.descriptorSet); - break; - case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: - layouts.push_back(allocationhandler->bindlessAccelerationStructures.descriptorSetLayout); - internal_state->bindlessSets.push_back(allocationhandler->bindlessAccelerationStructures.descriptorSet); - break; - default: - break; - } - - } - - VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; - pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutInfo.pSetLayouts = layouts.data(); - pipelineLayoutInfo.setLayoutCount = (uint32_t)layouts.size(); - if (internal_state->pushconstants.size > 0) - { - pipelineLayoutInfo.pushConstantRangeCount = 1; - pipelineLayoutInfo.pPushConstantRanges = &internal_state->pushconstants; - } - else - { - pipelineLayoutInfo.pushConstantRangeCount = 0; - pipelineLayoutInfo.pPushConstantRanges = nullptr; - } - - res = vulkan_check(vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &internal_state->pipelineLayout)); - if (res == VK_SUCCESS) - { - auto& cached_layout = pso_layout_cache[layout_hasher]; - cached_layout = wi::allocator::make_shared(); - cached_layout->allocationhandler = allocationhandler; - cached_layout->descriptorSetLayout = internal_state->descriptorSetLayout; - cached_layout->pipelineLayout = internal_state->pipelineLayout; - cached_layout->bindlessSets = internal_state->bindlessSets; - cached_layout->bindlessFirstSet = internal_state->bindlessFirstSet; - internal_state->layout_lifetime = cached_layout; - } - } - else - { - auto& cached_layout = pso_layout_cache[layout_hasher]; - internal_state->descriptorSetLayout = cached_layout->descriptorSetLayout; - internal_state->pipelineLayout = cached_layout->pipelineLayout; - internal_state->bindlessSets = cached_layout->bindlessSets; - internal_state->bindlessFirstSet = cached_layout->bindlessFirstSet; - internal_state->layout_lifetime = cached_layout; - } - pso_layout_cache_mutex.unlock(); - } - - VkGraphicsPipelineCreateInfo& pipelineInfo = internal_state->pipelineInfo; //pipelineInfo.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; //if (CheckCapability(GraphicsDeviceCapability::VARIABLE_RATE_SHADING_TIER2)) @@ -5527,7 +4948,7 @@ using namespace vulkan_internal; // pipelineInfo.flags |= VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR; //} pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipelineInfo.layout = internal_state->pipelineLayout; + pipelineInfo.layout = pipeline_layout; pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; // Shaders: @@ -6180,7 +5601,7 @@ using namespace vulkan_internal; info.maxPipelineRayRecursionDepth = desc->max_trace_recursion_depth; - info.layout = to_internal(desc->shader_libraries.front().shader)->pipelineLayout_cs; + info.layout = pipeline_layout; //VkRayTracingPipelineInterfaceCreateInfoKHR library_interface = {}; //library_interface.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR; @@ -7466,10 +6887,6 @@ using namespace vulkan_internal; { allocationhandler->destroylocker.lock(); - pso_layout_cache_mutex.lock(); - pso_layout_cache.clear(); - pso_layout_cache_mutex.unlock(); - for (auto& x : pipelines_global) { allocationhandler->destroyer_pipelines.push_back(std::make_pair(x.second, FRAMECOUNT)); @@ -8253,7 +7670,14 @@ using namespace vulkan_internal; if (binder.table.CBV_offset[slot] != offset) { binder.table.CBV_offset[slot] = offset; - binder.dirty |= DescriptorBinder::DIRTY_OFFSET; + if (slot < dynamic_cbv_count) + { + binder.dirty |= DescriptorBinder::DIRTY_OFFSET; + } + else + { + binder.dirty |= DescriptorBinder::DIRTY_DESCRIPTOR; + } } } void GraphicsDevice_Vulkan::BindVertexBuffers(const GPUBuffer *const* vertexBuffers, uint32_t slot, uint32_t count, const uint32_t* strides, const uint64_t* offsets, CommandList cmd) @@ -8426,28 +7850,17 @@ using namespace vulkan_internal; { commandlist.binder.dirty |= DescriptorBinder::DIRTY_ALL; } - else - { - auto active_internal = to_internal(commandlist.active_pso); - if (internal_state->pipelineLayout != active_internal->pipelineLayout) - { - commandlist.binder.dirty |= DescriptorBinder::DIRTY_ALL; - } - } - if (!internal_state->bindlessSets.empty()) - { - vkCmdBindDescriptorSets( - commandlist.GetCommandBuffer(), - VK_PIPELINE_BIND_POINT_GRAPHICS, - internal_state->pipelineLayout, - internal_state->bindlessFirstSet, - (uint32_t)internal_state->bindlessSets.size(), - internal_state->bindlessSets.data(), - 0, - nullptr - ); - } + vkCmdBindDescriptorSets( + commandlist.GetCommandBuffer(), + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline_layout, + 1, + arraysize(descriptor_sets) - 1, + &descriptor_sets[1], + 0, + nullptr + ); commandlist.active_pso = pso; } @@ -8465,15 +7878,6 @@ using namespace vulkan_internal; { commandlist.binder.dirty |= DescriptorBinder::DIRTY_ALL; } - else - { - auto internal_state = to_internal(cs); - auto active_internal = to_internal(commandlist.active_cs); - if (internal_state->pipelineLayout_cs != active_internal->pipelineLayout_cs) - { - commandlist.binder.dirty |= DescriptorBinder::DIRTY_ALL; - } - } commandlist.active_cs = cs; auto internal_state = to_internal(cs); @@ -8481,36 +7885,16 @@ using namespace vulkan_internal; if (cs->stage == ShaderStage::CS) { vkCmdBindPipeline(commandlist.GetCommandBuffer(), VK_PIPELINE_BIND_POINT_COMPUTE, internal_state->pipeline_cs); - - if (!internal_state->bindlessSets.empty()) - { - vkCmdBindDescriptorSets( - commandlist.GetCommandBuffer(), - VK_PIPELINE_BIND_POINT_COMPUTE, - internal_state->pipelineLayout_cs, - internal_state->bindlessFirstSet, - (uint32_t)internal_state->bindlessSets.size(), - internal_state->bindlessSets.data(), - 0, - nullptr - ); - } - } - else if (cs->stage == ShaderStage::LIB) - { - if (!internal_state->bindlessSets.empty()) - { - vkCmdBindDescriptorSets( - commandlist.GetCommandBuffer(), - VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, - internal_state->pipelineLayout_cs, - internal_state->bindlessFirstSet, - (uint32_t)internal_state->bindlessSets.size(), - internal_state->bindlessSets.data(), - 0, - nullptr - ); - } + vkCmdBindDescriptorSets( + commandlist.GetCommandBuffer(), + VK_PIPELINE_BIND_POINT_COMPUTE, + pipeline_layout, + 1, + arraysize(descriptor_sets) - 1, + &descriptor_sets[1], + 0, + nullptr + ); } } void GraphicsDevice_Vulkan::BindDepthBounds(float min_bounds, float max_bounds, CommandList cmd) @@ -9287,6 +8671,16 @@ using namespace vulkan_internal; BindComputeShader(rtpso->desc.shader_libraries.front().shader, cmd); vkCmdBindPipeline(commandlist.GetCommandBuffer(), VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, to_internal(rtpso)->pipeline); + vkCmdBindDescriptorSets( + commandlist.GetCommandBuffer(), + VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, + pipeline_layout, + 1, + arraysize(descriptor_sets) - 1, + &descriptor_sets[1], + 0, + nullptr + ); } void GraphicsDevice_Vulkan::DispatchRays(const DispatchRaysDesc* desc, CommandList cmd) { @@ -9332,41 +8726,14 @@ using namespace vulkan_internal; { CommandList_Vulkan& commandlist = GetCommandList(cmd); - if (commandlist.active_pso != nullptr) - { - auto pso_internal = to_internal(commandlist.active_pso); - if (pso_internal->pushconstants.size > 0) - { - vkCmdPushConstants( - commandlist.GetCommandBuffer(), - pso_internal->pipelineLayout, - pso_internal->pushconstants.stageFlags, - offset, - size, - data - ); - return; - } - assert(0); // there was no push constant block! - } - if(commandlist.active_cs != nullptr) - { - auto cs_internal = to_internal(commandlist.active_cs); - if (cs_internal->pushconstants.size > 0) - { - vkCmdPushConstants( - commandlist.GetCommandBuffer(), - cs_internal->pipelineLayout_cs, - cs_internal->pushconstants.stageFlags, - offset, - size, - data - ); - return; - } - assert(0); // there was no push constant block! - } - assert(0); // there was no active pipeline! + vkCmdPushConstants( + commandlist.GetCommandBuffer(), + pipeline_layout, + VK_SHADER_STAGE_ALL, + offset, + size, + data + ); } void GraphicsDevice_Vulkan::PredicationBegin(const GPUBuffer* buffer, uint64_t offset, PredicationOp op, CommandList cmd) { diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.h b/WickedEngine/wiGraphicsDevice_Vulkan.h index ca3732556..2053f7c5b 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.h +++ b/WickedEngine/wiGraphicsDevice_Vulkan.h @@ -32,80 +32,6 @@ #define vulkan_assert(cond, fname) { wilog_assert(cond, "Vulkan error: %s failed with %s (%s:%d)", fname, string_VkResult(res), relative_path(__FILE__), __LINE__); } #define vulkan_check(call) [&]() { VkResult res = call; vulkan_assert((res >= VK_SUCCESS), extract_function_name(#call).c_str()); return res; }() -namespace wi::graphics -{ - struct PSOLayoutHash - { - VkPushConstantRange push = {}; - struct Item - { - bool used = true; - VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_2D; - VkDescriptorSetLayoutBinding binding = {}; - }; - wi::vector items; - size_t hash = 0; - - inline bool operator==(const PSOLayoutHash& other) const - { - if (hash != other.hash) - return false; - if (items.size() != other.items.size()) - return false; - for (size_t i = 0; i < items.size(); ++i) - { - const Item& a = items[i]; - const Item& b = other.items[i]; - if ( - a.used != b.used || - a.viewType != b.viewType || - a.binding.binding != b.binding.binding || - a.binding.descriptorCount != b.binding.descriptorCount || - a.binding.descriptorType != b.binding.descriptorType || - a.binding.stageFlags != b.binding.stageFlags || - a.binding.pImmutableSamplers != b.binding.pImmutableSamplers - ) - return false; - } - return - push.offset == other.push.offset && - push.size == other.push.size && - push.stageFlags == other.push.stageFlags; - } - inline void embed_hash() - { - hash = 0; - for (auto& x : items) - { - wi::helper::hash_combine(hash, x.used); - wi::helper::hash_combine(hash, x.viewType); - wi::helper::hash_combine(hash, x.binding.binding); - wi::helper::hash_combine(hash, x.binding.descriptorCount); - wi::helper::hash_combine(hash, x.binding.descriptorType); - wi::helper::hash_combine(hash, x.binding.stageFlags); - } - wi::helper::hash_combine(hash, push.offset); - wi::helper::hash_combine(hash, push.size); - wi::helper::hash_combine(hash, push.stageFlags); - } - constexpr size_t get_hash() const - { - return hash; - } - }; -} -namespace std -{ - template <> - struct hash - { - constexpr size_t operator()(const wi::graphics::PSOLayoutHash& hash) const - { - return hash.get_hash(); - } - }; -} - namespace wi::graphics { class GraphicsDevice_Vulkan final : public GraphicsDevice @@ -155,6 +81,7 @@ namespace wi::graphics VkPhysicalDeviceRayQueryFeaturesKHR raytracing_query_features = {}; VkPhysicalDeviceFragmentShadingRateFeaturesKHR fragment_shading_rate_features = {}; VkPhysicalDeviceConditionalRenderingFeaturesEXT conditional_rendering_features = {}; + VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT mutable_descriptor_features = {}; VkPhysicalDeviceDepthClipEnableFeaturesEXT depth_clip_enable_features = {}; VkPhysicalDeviceImageViewMinLodFeaturesEXT image_view_min_lod_features = {}; VkPhysicalDeviceMeshShaderFeaturesEXT mesh_shader_features = {}; @@ -196,6 +123,25 @@ namespace wi::graphics VkImageView nullImageViewCubeArray = VK_NULL_HANDLE; VkImageView nullImageView3D = VK_NULL_HANDLE; + VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; + + enum DESCRIPTOR_SET + { + DESCRIPTOR_SET_BINDINGS, + + DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER, + DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER, + DESCRIPTOR_SET_BINDLESS_SAMPLER, + DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE, + DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE, + DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER, + DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE, + + DESCRIPTOR_SET_COUNT, + }; + VkDescriptorSet descriptor_sets[DESCRIPTOR_SET_COUNT] = {}; + VkDescriptorSetLayout descriptor_set_layouts[DESCRIPTOR_SET_COUNT] = {}; + struct CommandQueue { VkQueue queue = VK_NULL_HANDLE; @@ -262,17 +208,7 @@ namespace wi::graphics { DescriptorBindingTable table; GraphicsDevice_Vulkan* device; - - wi::vector descriptorWrites; - wi::vector bufferInfos; - wi::vector imageInfos; - wi::vector texelBufferViews; - wi::vector accelerationStructureViews; - - uint32_t uniform_buffer_dynamic_offsets[DESCRIPTORBINDER_CBV_COUNT] = {}; - - VkDescriptorSet descriptorSet_graphics = VK_NULL_HANDLE; - VkDescriptorSet descriptorSet_compute = VK_NULL_HANDLE; + VkDescriptorSet descriptorSet = VK_NULL_HANDLE; enum DIRTY_FLAGS { @@ -405,8 +341,7 @@ namespace wi::graphics void predraw(CommandList cmd); void predispatch(CommandList cmd); - static constexpr uint32_t immutable_sampler_slot_begin = 100; - wi::vector immutable_samplers; + VkSampler immutable_samplers[10]; void set_fence_name(VkFence fence, const char* name); void set_semaphore_name(VkSemaphore semaphore, const char* name); @@ -897,27 +832,6 @@ namespace wi::graphics }; wi::allocator::shared_ptr allocationhandler; - - struct PSOLayout - { - wi::allocator::shared_ptr allocationhandler; - VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; - VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; - wi::vector bindlessSets; - uint32_t bindlessFirstSet = 0; - ~PSOLayout() - { - if (allocationhandler == nullptr) - return; - allocationhandler->destroylocker.lock(); - uint64_t framecount = allocationhandler->framecount; - allocationhandler->destroyer_pipelineLayouts.push_back(std::make_pair(pipelineLayout, framecount)); - allocationhandler->destroyer_descriptorSetLayouts.push_back(std::make_pair(descriptorSetLayout, framecount)); - allocationhandler->destroylocker.unlock(); - } - }; - mutable wi::unordered_map> pso_layout_cache; - mutable std::mutex pso_layout_cache_mutex; }; }