mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
update SPIRV-Cross
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
|
||||
/*
|
||||
** Enumeration tokens for SPIR-V, in various styles:
|
||||
** C, C++, C++11, JSON, Lua, Python, C#, D
|
||||
** 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
|
||||
@@ -41,6 +41,8 @@
|
||||
** - 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
|
||||
@@ -53,12 +55,12 @@
|
||||
|
||||
typedef unsigned int SpvId;
|
||||
|
||||
#define SPV_VERSION 0x10500
|
||||
#define SPV_REVISION 4
|
||||
#define SPV_VERSION 0x10600
|
||||
#define SPV_REVISION 1
|
||||
|
||||
static const unsigned int SpvMagicNumber = 0x07230203;
|
||||
static const unsigned int SpvVersion = 0x00010500;
|
||||
static const unsigned int SpvRevision = 4;
|
||||
static const unsigned int SpvVersion = 0x00010600;
|
||||
static const unsigned int SpvRevision = 1;
|
||||
static const unsigned int SpvOpCodeMask = 0xffff;
|
||||
static const unsigned int SpvWordCountShift = 16;
|
||||
|
||||
@@ -69,6 +71,8 @@ typedef enum SpvSourceLanguage_ {
|
||||
SpvSourceLanguageOpenCL_C = 3,
|
||||
SpvSourceLanguageOpenCL_CPP = 4,
|
||||
SpvSourceLanguageHLSL = 5,
|
||||
SpvSourceLanguageCPP_for_OpenCL = 6,
|
||||
SpvSourceLanguageSYCL = 7,
|
||||
SpvSourceLanguageMax = 0x7fffffff,
|
||||
} SpvSourceLanguage;
|
||||
|
||||
@@ -94,6 +98,8 @@ typedef enum SpvExecutionModel_ {
|
||||
SpvExecutionModelMissNV = 5317,
|
||||
SpvExecutionModelCallableKHR = 5318,
|
||||
SpvExecutionModelCallableNV = 5318,
|
||||
SpvExecutionModelTaskEXT = 5364,
|
||||
SpvExecutionModelMeshEXT = 5365,
|
||||
SpvExecutionModelMax = 0x7fffffff,
|
||||
} SpvExecutionModel;
|
||||
|
||||
@@ -154,17 +160,28 @@ typedef enum SpvExecutionMode_ {
|
||||
SpvExecutionModeSubgroupsPerWorkgroupId = 37,
|
||||
SpvExecutionModeLocalSizeId = 38,
|
||||
SpvExecutionModeLocalSizeHintId = 39,
|
||||
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,
|
||||
@@ -172,10 +189,17 @@ typedef enum SpvExecutionMode_ {
|
||||
SpvExecutionModeSampleInterlockUnorderedEXT = 5369,
|
||||
SpvExecutionModeShadingRateInterlockOrderedEXT = 5370,
|
||||
SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371,
|
||||
SpvExecutionModeSharedLocalMemorySizeINTEL = 5618,
|
||||
SpvExecutionModeRoundingModeRTPINTEL = 5620,
|
||||
SpvExecutionModeRoundingModeRTNINTEL = 5621,
|
||||
SpvExecutionModeFloatingPointModeALTINTEL = 5622,
|
||||
SpvExecutionModeFloatingPointModeIEEEINTEL = 5623,
|
||||
SpvExecutionModeMaxWorkgroupSizeINTEL = 5893,
|
||||
SpvExecutionModeMaxWorkDimINTEL = 5894,
|
||||
SpvExecutionModeNoGlobalOffsetINTEL = 5895,
|
||||
SpvExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
||||
SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
|
||||
SpvExecutionModeNamedBarrierCountINTEL = 6417,
|
||||
SpvExecutionModeMax = 0x7fffffff,
|
||||
} SpvExecutionMode;
|
||||
|
||||
@@ -207,7 +231,10 @@ typedef enum SpvStorageClass_ {
|
||||
SpvStorageClassShaderRecordBufferNV = 5343,
|
||||
SpvStorageClassPhysicalStorageBuffer = 5349,
|
||||
SpvStorageClassPhysicalStorageBufferEXT = 5349,
|
||||
SpvStorageClassTaskPayloadWorkgroupEXT = 5402,
|
||||
SpvStorageClassCodeSectionINTEL = 5605,
|
||||
SpvStorageClassDeviceOnlyINTEL = 5936,
|
||||
SpvStorageClassHostOnlyINTEL = 5937,
|
||||
SpvStorageClassMax = 0x7fffffff,
|
||||
} SpvStorageClass;
|
||||
|
||||
@@ -347,6 +374,8 @@ typedef enum SpvImageOperandsShift_ {
|
||||
SpvImageOperandsVolatileTexelKHRShift = 11,
|
||||
SpvImageOperandsSignExtendShift = 12,
|
||||
SpvImageOperandsZeroExtendShift = 13,
|
||||
SpvImageOperandsNontemporalShift = 14,
|
||||
SpvImageOperandsOffsetsShift = 16,
|
||||
SpvImageOperandsMax = 0x7fffffff,
|
||||
} SpvImageOperandsShift;
|
||||
|
||||
@@ -370,6 +399,8 @@ typedef enum SpvImageOperandsMask_ {
|
||||
SpvImageOperandsVolatileTexelKHRMask = 0x00000800,
|
||||
SpvImageOperandsSignExtendMask = 0x00001000,
|
||||
SpvImageOperandsZeroExtendMask = 0x00002000,
|
||||
SpvImageOperandsNontemporalMask = 0x00004000,
|
||||
SpvImageOperandsOffsetsMask = 0x00010000,
|
||||
} SpvImageOperandsMask;
|
||||
|
||||
typedef enum SpvFPFastMathModeShift_ {
|
||||
@@ -378,6 +409,8 @@ typedef enum SpvFPFastMathModeShift_ {
|
||||
SpvFPFastMathModeNSZShift = 2,
|
||||
SpvFPFastMathModeAllowRecipShift = 3,
|
||||
SpvFPFastMathModeFastShift = 4,
|
||||
SpvFPFastMathModeAllowContractFastINTELShift = 16,
|
||||
SpvFPFastMathModeAllowReassocINTELShift = 17,
|
||||
SpvFPFastMathModeMax = 0x7fffffff,
|
||||
} SpvFPFastMathModeShift;
|
||||
|
||||
@@ -388,6 +421,8 @@ typedef enum SpvFPFastMathModeMask_ {
|
||||
SpvFPFastMathModeNSZMask = 0x00000004,
|
||||
SpvFPFastMathModeAllowRecipMask = 0x00000008,
|
||||
SpvFPFastMathModeFastMask = 0x00000010,
|
||||
SpvFPFastMathModeAllowContractFastINTELMask = 0x00010000,
|
||||
SpvFPFastMathModeAllowReassocINTELMask = 0x00020000,
|
||||
} SpvFPFastMathModeMask;
|
||||
|
||||
typedef enum SpvFPRoundingMode_ {
|
||||
@@ -401,6 +436,7 @@ typedef enum SpvFPRoundingMode_ {
|
||||
typedef enum SpvLinkageType_ {
|
||||
SpvLinkageTypeExport = 0,
|
||||
SpvLinkageTypeImport = 1,
|
||||
SpvLinkageTypeLinkOnceODR = 2,
|
||||
SpvLinkageTypeMax = 0x7fffffff,
|
||||
} SpvLinkageType;
|
||||
|
||||
@@ -478,9 +514,11 @@ typedef enum SpvDecoration_ {
|
||||
SpvDecorationPassthroughNV = 5250,
|
||||
SpvDecorationViewportRelativeNV = 5252,
|
||||
SpvDecorationSecondaryViewportRelativeNV = 5256,
|
||||
SpvDecorationPerPrimitiveEXT = 5271,
|
||||
SpvDecorationPerPrimitiveNV = 5271,
|
||||
SpvDecorationPerViewNV = 5272,
|
||||
SpvDecorationPerTaskNV = 5273,
|
||||
SpvDecorationPerVertexKHR = 5285,
|
||||
SpvDecorationPerVertexNV = 5285,
|
||||
SpvDecorationNonUniform = 5300,
|
||||
SpvDecorationNonUniformEXT = 5300,
|
||||
@@ -488,12 +526,26 @@ typedef enum SpvDecoration_ {
|
||||
SpvDecorationRestrictPointerEXT = 5355,
|
||||
SpvDecorationAliasedPointer = 5356,
|
||||
SpvDecorationAliasedPointerEXT = 5356,
|
||||
SpvDecorationBindlessSamplerNV = 5398,
|
||||
SpvDecorationBindlessImageNV = 5399,
|
||||
SpvDecorationBoundSamplerNV = 5400,
|
||||
SpvDecorationBoundImageNV = 5401,
|
||||
SpvDecorationSIMTCallINTEL = 5599,
|
||||
SpvDecorationReferencedIndirectlyINTEL = 5602,
|
||||
SpvDecorationClobberINTEL = 5607,
|
||||
SpvDecorationSideEffectsINTEL = 5608,
|
||||
SpvDecorationVectorComputeVariableINTEL = 5624,
|
||||
SpvDecorationFuncParamIOKindINTEL = 5625,
|
||||
SpvDecorationVectorComputeFunctionINTEL = 5626,
|
||||
SpvDecorationStackCallINTEL = 5627,
|
||||
SpvDecorationGlobalVariableOffsetINTEL = 5628,
|
||||
SpvDecorationCounterBuffer = 5634,
|
||||
SpvDecorationHlslCounterBufferGOOGLE = 5634,
|
||||
SpvDecorationHlslSemanticGOOGLE = 5635,
|
||||
SpvDecorationUserSemantic = 5635,
|
||||
SpvDecorationUserTypeGOOGLE = 5636,
|
||||
SpvDecorationFunctionRoundingModeINTEL = 5822,
|
||||
SpvDecorationFunctionDenormModeINTEL = 5823,
|
||||
SpvDecorationRegisterINTEL = 5825,
|
||||
SpvDecorationMemoryINTEL = 5826,
|
||||
SpvDecorationNumbanksINTEL = 5827,
|
||||
@@ -506,6 +558,20 @@ typedef enum SpvDecoration_ {
|
||||
SpvDecorationMergeINTEL = 5834,
|
||||
SpvDecorationBankBitsINTEL = 5835,
|
||||
SpvDecorationForcePow2DepthINTEL = 5836,
|
||||
SpvDecorationBurstCoalesceINTEL = 5899,
|
||||
SpvDecorationCacheSizeINTEL = 5900,
|
||||
SpvDecorationDontStaticallyCoalesceINTEL = 5901,
|
||||
SpvDecorationPrefetchINTEL = 5902,
|
||||
SpvDecorationStallEnableINTEL = 5905,
|
||||
SpvDecorationFuseLoopsInFunctionINTEL = 5907,
|
||||
SpvDecorationAliasScopeINTEL = 5914,
|
||||
SpvDecorationNoAliasINTEL = 5915,
|
||||
SpvDecorationBufferLocationINTEL = 5921,
|
||||
SpvDecorationIOPipeStorageINTEL = 5944,
|
||||
SpvDecorationFunctionFloatingPointModeINTEL = 6080,
|
||||
SpvDecorationSingleElementVectorINTEL = 6085,
|
||||
SpvDecorationVectorComputeCallableFunctionINTEL = 6087,
|
||||
SpvDecorationMediaBlockIOINTEL = 6140,
|
||||
SpvDecorationMax = 0x7fffffff,
|
||||
} SpvDecoration;
|
||||
|
||||
@@ -590,12 +656,18 @@ typedef enum SpvBuiltIn_ {
|
||||
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,
|
||||
@@ -621,6 +693,7 @@ typedef enum SpvBuiltIn_ {
|
||||
SpvBuiltInHitTNV = 5332,
|
||||
SpvBuiltInHitKindKHR = 5333,
|
||||
SpvBuiltInHitKindNV = 5333,
|
||||
SpvBuiltInCurrentRayTimeNV = 5334,
|
||||
SpvBuiltInIncomingRayFlagsKHR = 5351,
|
||||
SpvBuiltInIncomingRayFlagsNV = 5351,
|
||||
SpvBuiltInRayGeometryIndexKHR = 5352,
|
||||
@@ -628,6 +701,7 @@ typedef enum SpvBuiltIn_ {
|
||||
SpvBuiltInSMCountNV = 5375,
|
||||
SpvBuiltInWarpIDNV = 5376,
|
||||
SpvBuiltInSMIDNV = 5377,
|
||||
SpvBuiltInCullMaskKHR = 6021,
|
||||
SpvBuiltInMax = 0x7fffffff,
|
||||
} SpvBuiltIn;
|
||||
|
||||
@@ -660,6 +734,7 @@ typedef enum SpvLoopControlShift_ {
|
||||
SpvLoopControlLoopCoalesceINTELShift = 20,
|
||||
SpvLoopControlMaxInterleavingINTELShift = 21,
|
||||
SpvLoopControlSpeculatedIterationsINTELShift = 22,
|
||||
SpvLoopControlNoFusionINTELShift = 23,
|
||||
SpvLoopControlMax = 0x7fffffff,
|
||||
} SpvLoopControlShift;
|
||||
|
||||
@@ -681,6 +756,7 @@ typedef enum SpvLoopControlMask_ {
|
||||
SpvLoopControlLoopCoalesceINTELMask = 0x00100000,
|
||||
SpvLoopControlMaxInterleavingINTELMask = 0x00200000,
|
||||
SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000,
|
||||
SpvLoopControlNoFusionINTELMask = 0x00800000,
|
||||
} SpvLoopControlMask;
|
||||
|
||||
typedef enum SpvFunctionControlShift_ {
|
||||
@@ -688,6 +764,7 @@ typedef enum SpvFunctionControlShift_ {
|
||||
SpvFunctionControlDontInlineShift = 1,
|
||||
SpvFunctionControlPureShift = 2,
|
||||
SpvFunctionControlConstShift = 3,
|
||||
SpvFunctionControlOptNoneINTELShift = 16,
|
||||
SpvFunctionControlMax = 0x7fffffff,
|
||||
} SpvFunctionControlShift;
|
||||
|
||||
@@ -697,6 +774,7 @@ typedef enum SpvFunctionControlMask_ {
|
||||
SpvFunctionControlDontInlineMask = 0x00000002,
|
||||
SpvFunctionControlPureMask = 0x00000004,
|
||||
SpvFunctionControlConstMask = 0x00000008,
|
||||
SpvFunctionControlOptNoneINTELMask = 0x00010000,
|
||||
} SpvFunctionControlMask;
|
||||
|
||||
typedef enum SpvMemorySemanticsShift_ {
|
||||
@@ -751,6 +829,8 @@ typedef enum SpvMemoryAccessShift_ {
|
||||
SpvMemoryAccessMakePointerVisibleKHRShift = 4,
|
||||
SpvMemoryAccessNonPrivatePointerShift = 5,
|
||||
SpvMemoryAccessNonPrivatePointerKHRShift = 5,
|
||||
SpvMemoryAccessAliasScopeINTELMaskShift = 16,
|
||||
SpvMemoryAccessNoAliasINTELMaskShift = 17,
|
||||
SpvMemoryAccessMax = 0x7fffffff,
|
||||
} SpvMemoryAccessShift;
|
||||
|
||||
@@ -765,6 +845,8 @@ typedef enum SpvMemoryAccessMask_ {
|
||||
SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
||||
SpvMemoryAccessNonPrivatePointerMask = 0x00000020,
|
||||
SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
||||
SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000,
|
||||
SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000,
|
||||
} SpvMemoryAccessMask;
|
||||
|
||||
typedef enum SpvScope_ {
|
||||
@@ -877,9 +959,13 @@ typedef enum SpvCapability_ {
|
||||
SpvCapabilityGroupNonUniformQuad = 68,
|
||||
SpvCapabilityShaderLayer = 69,
|
||||
SpvCapabilityShaderViewportIndex = 70,
|
||||
SpvCapabilityUniformDecoration = 71,
|
||||
SpvCapabilityFragmentShadingRateKHR = 4422,
|
||||
SpvCapabilitySubgroupBallotKHR = 4423,
|
||||
SpvCapabilityDrawParameters = 4427,
|
||||
SpvCapabilityWorkgroupMemoryExplicitLayoutKHR = 4428,
|
||||
SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429,
|
||||
SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430,
|
||||
SpvCapabilitySubgroupVoteKHR = 4431,
|
||||
SpvCapabilityStorageBuffer16BitAccess = 4433,
|
||||
SpvCapabilityStorageUniformBufferBlock16 = 4433,
|
||||
@@ -922,6 +1008,8 @@ typedef enum SpvCapability_ {
|
||||
SpvCapabilityFragmentFullyCoveredEXT = 5265,
|
||||
SpvCapabilityMeshShadingNV = 5266,
|
||||
SpvCapabilityImageFootprintNV = 5282,
|
||||
SpvCapabilityMeshShadingEXT = 5283,
|
||||
SpvCapabilityFragmentBarycentricKHR = 5284,
|
||||
SpvCapabilityFragmentBarycentricNV = 5284,
|
||||
SpvCapabilityComputeDerivativeGroupQuadsNV = 5288,
|
||||
SpvCapabilityFragmentDensityEXT = 5291,
|
||||
@@ -952,6 +1040,7 @@ typedef enum SpvCapability_ {
|
||||
SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
|
||||
SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
|
||||
SpvCapabilityRayTracingNV = 5340,
|
||||
SpvCapabilityRayTracingMotionBlurNV = 5341,
|
||||
SpvCapabilityVulkanMemoryModel = 5345,
|
||||
SpvCapabilityVulkanMemoryModelKHR = 5345,
|
||||
SpvCapabilityVulkanMemoryModelDeviceScope = 5346,
|
||||
@@ -965,26 +1054,67 @@ typedef enum SpvCapability_ {
|
||||
SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372,
|
||||
SpvCapabilityShaderSMBuiltinsNV = 5373,
|
||||
SpvCapabilityFragmentShaderPixelInterlockEXT = 5378,
|
||||
SpvCapabilityDemoteToHelperInvocation = 5379,
|
||||
SpvCapabilityDemoteToHelperInvocationEXT = 5379,
|
||||
SpvCapabilityBindlessTextureNV = 5390,
|
||||
SpvCapabilitySubgroupShuffleINTEL = 5568,
|
||||
SpvCapabilitySubgroupBufferBlockIOINTEL = 5569,
|
||||
SpvCapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||
SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579,
|
||||
SpvCapabilityRoundToInfinityINTEL = 5582,
|
||||
SpvCapabilityFloatingPointModeINTEL = 5583,
|
||||
SpvCapabilityIntegerFunctions2INTEL = 5584,
|
||||
SpvCapabilityFunctionPointersINTEL = 5603,
|
||||
SpvCapabilityIndirectReferencesINTEL = 5604,
|
||||
SpvCapabilityAsmINTEL = 5606,
|
||||
SpvCapabilityAtomicFloat32MinMaxEXT = 5612,
|
||||
SpvCapabilityAtomicFloat64MinMaxEXT = 5613,
|
||||
SpvCapabilityAtomicFloat16MinMaxEXT = 5616,
|
||||
SpvCapabilityVectorComputeINTEL = 5617,
|
||||
SpvCapabilityVectorAnyINTEL = 5619,
|
||||
SpvCapabilityExpectAssumeKHR = 5629,
|
||||
SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696,
|
||||
SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
|
||||
SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
|
||||
SpvCapabilityVariableLengthArrayINTEL = 5817,
|
||||
SpvCapabilityFunctionFloatControlINTEL = 5821,
|
||||
SpvCapabilityFPGAMemoryAttributesINTEL = 5824,
|
||||
SpvCapabilityFPFastMathModeINTEL = 5837,
|
||||
SpvCapabilityArbitraryPrecisionIntegersINTEL = 5844,
|
||||
SpvCapabilityArbitraryPrecisionFloatingPointINTEL = 5845,
|
||||
SpvCapabilityUnstructuredLoopControlsINTEL = 5886,
|
||||
SpvCapabilityFPGALoopControlsINTEL = 5888,
|
||||
SpvCapabilityKernelAttributesINTEL = 5892,
|
||||
SpvCapabilityFPGAKernelAttributesINTEL = 5897,
|
||||
SpvCapabilityFPGAMemoryAccessesINTEL = 5898,
|
||||
SpvCapabilityFPGAClusterAttributesINTEL = 5904,
|
||||
SpvCapabilityLoopFuseINTEL = 5906,
|
||||
SpvCapabilityMemoryAccessAliasingINTEL = 5910,
|
||||
SpvCapabilityFPGABufferLocationINTEL = 5920,
|
||||
SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922,
|
||||
SpvCapabilityUSMStorageClassesINTEL = 5935,
|
||||
SpvCapabilityIOPipesINTEL = 5943,
|
||||
SpvCapabilityBlockingPipesINTEL = 5945,
|
||||
SpvCapabilityFPGARegINTEL = 5948,
|
||||
SpvCapabilityDotProductInputAll = 6016,
|
||||
SpvCapabilityDotProductInputAllKHR = 6016,
|
||||
SpvCapabilityDotProductInput4x8Bit = 6017,
|
||||
SpvCapabilityDotProductInput4x8BitKHR = 6017,
|
||||
SpvCapabilityDotProductInput4x8BitPacked = 6018,
|
||||
SpvCapabilityDotProductInput4x8BitPackedKHR = 6018,
|
||||
SpvCapabilityDotProduct = 6019,
|
||||
SpvCapabilityDotProductKHR = 6019,
|
||||
SpvCapabilityRayCullMaskKHR = 6020,
|
||||
SpvCapabilityBitInstructions = 6025,
|
||||
SpvCapabilityGroupNonUniformRotateKHR = 6026,
|
||||
SpvCapabilityAtomicFloat32AddEXT = 6033,
|
||||
SpvCapabilityAtomicFloat64AddEXT = 6034,
|
||||
SpvCapabilityLongConstantCompositeINTEL = 6089,
|
||||
SpvCapabilityOptNoneINTEL = 6094,
|
||||
SpvCapabilityAtomicFloat16AddEXT = 6095,
|
||||
SpvCapabilityDebugInfoModuleINTEL = 6114,
|
||||
SpvCapabilitySplitBarrierINTEL = 6141,
|
||||
SpvCapabilityGroupUniformArithmeticKHR = 6400,
|
||||
SpvCapabilityMax = 0x7fffffff,
|
||||
} SpvCapability;
|
||||
|
||||
@@ -1051,6 +1181,44 @@ typedef enum SpvFragmentShadingRateMask_ {
|
||||
SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008,
|
||||
} SpvFragmentShadingRateMask;
|
||||
|
||||
typedef enum SpvFPDenormMode_ {
|
||||
SpvFPDenormModePreserve = 0,
|
||||
SpvFPDenormModeFlushToZero = 1,
|
||||
SpvFPDenormModeMax = 0x7fffffff,
|
||||
} SpvFPDenormMode;
|
||||
|
||||
typedef enum SpvFPOperationMode_ {
|
||||
SpvFPOperationModeIEEE = 0,
|
||||
SpvFPOperationModeALT = 1,
|
||||
SpvFPOperationModeMax = 0x7fffffff,
|
||||
} SpvFPOperationMode;
|
||||
|
||||
typedef enum SpvQuantizationModes_ {
|
||||
SpvQuantizationModesTRN = 0,
|
||||
SpvQuantizationModesTRN_ZERO = 1,
|
||||
SpvQuantizationModesRND = 2,
|
||||
SpvQuantizationModesRND_ZERO = 3,
|
||||
SpvQuantizationModesRND_INF = 4,
|
||||
SpvQuantizationModesRND_MIN_INF = 5,
|
||||
SpvQuantizationModesRND_CONV = 6,
|
||||
SpvQuantizationModesRND_CONV_ODD = 7,
|
||||
SpvQuantizationModesMax = 0x7fffffff,
|
||||
} SpvQuantizationModes;
|
||||
|
||||
typedef enum SpvOverflowModes_ {
|
||||
SpvOverflowModesWRAP = 0,
|
||||
SpvOverflowModesSAT = 1,
|
||||
SpvOverflowModesSAT_ZERO = 2,
|
||||
SpvOverflowModesSAT_SYM = 3,
|
||||
SpvOverflowModesMax = 0x7fffffff,
|
||||
} SpvOverflowModes;
|
||||
|
||||
typedef enum SpvPackedVectorFormat_ {
|
||||
SpvPackedVectorFormatPackedVectorFormat4x8Bit = 0,
|
||||
SpvPackedVectorFormatPackedVectorFormat4x8BitKHR = 0,
|
||||
SpvPackedVectorFormatMax = 0x7fffffff,
|
||||
} SpvPackedVectorFormat;
|
||||
|
||||
typedef enum SpvOp_ {
|
||||
SpvOpNop = 0,
|
||||
SpvOpUndef = 1,
|
||||
@@ -1402,12 +1570,25 @@ typedef enum SpvOp_ {
|
||||
SpvOpSubgroupAllKHR = 4428,
|
||||
SpvOpSubgroupAnyKHR = 4429,
|
||||
SpvOpSubgroupAllEqualKHR = 4430,
|
||||
SpvOpGroupNonUniformRotateKHR = 4431,
|
||||
SpvOpSubgroupReadInvocationKHR = 4432,
|
||||
SpvOpTraceRayKHR = 4445,
|
||||
SpvOpExecuteCallableKHR = 4446,
|
||||
SpvOpConvertUToAccelerationStructureKHR = 4447,
|
||||
SpvOpIgnoreIntersectionKHR = 4448,
|
||||
SpvOpTerminateRayKHR = 4449,
|
||||
SpvOpSDot = 4450,
|
||||
SpvOpSDotKHR = 4450,
|
||||
SpvOpUDot = 4451,
|
||||
SpvOpUDotKHR = 4451,
|
||||
SpvOpSUDot = 4452,
|
||||
SpvOpSUDotKHR = 4452,
|
||||
SpvOpSDotAccSat = 4453,
|
||||
SpvOpSDotAccSatKHR = 4453,
|
||||
SpvOpUDotAccSat = 4454,
|
||||
SpvOpUDotAccSatKHR = 4454,
|
||||
SpvOpSUDotAccSat = 4455,
|
||||
SpvOpSUDotAccSatKHR = 4455,
|
||||
SpvOpTypeRayQueryKHR = 4472,
|
||||
SpvOpRayQueryInitializeKHR = 4473,
|
||||
SpvOpRayQueryTerminateKHR = 4474,
|
||||
@@ -1427,6 +1608,8 @@ typedef enum SpvOp_ {
|
||||
SpvOpFragmentFetchAMD = 5012,
|
||||
SpvOpReadClockKHR = 5056,
|
||||
SpvOpImageSampleFootprintNV = 5283,
|
||||
SpvOpEmitMeshTasksEXT = 5294,
|
||||
SpvOpSetMeshOutputsEXT = 5295,
|
||||
SpvOpGroupNonUniformPartitionNV = 5296,
|
||||
SpvOpWritePackedPrimitiveIndices4x8NV = 5299,
|
||||
SpvOpReportIntersectionKHR = 5334,
|
||||
@@ -1434,6 +1617,8 @@ typedef enum SpvOp_ {
|
||||
SpvOpIgnoreIntersectionNV = 5335,
|
||||
SpvOpTerminateRayNV = 5336,
|
||||
SpvOpTraceNV = 5337,
|
||||
SpvOpTraceMotionNV = 5338,
|
||||
SpvOpTraceRayMotionNV = 5339,
|
||||
SpvOpTypeAccelerationStructureKHR = 5341,
|
||||
SpvOpTypeAccelerationStructureNV = 5341,
|
||||
SpvOpExecuteCallableNV = 5344,
|
||||
@@ -1444,8 +1629,16 @@ typedef enum SpvOp_ {
|
||||
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,
|
||||
@@ -1470,8 +1663,15 @@ typedef enum SpvOp_ {
|
||||
SpvOpUSubSatINTEL = 5596,
|
||||
SpvOpIMul32x16INTEL = 5597,
|
||||
SpvOpUMul32x16INTEL = 5598,
|
||||
SpvOpFunctionPointerINTEL = 5600,
|
||||
SpvOpConstantFunctionPointerINTEL = 5600,
|
||||
SpvOpFunctionPointerCallINTEL = 5601,
|
||||
SpvOpAsmTargetINTEL = 5609,
|
||||
SpvOpAsmINTEL = 5610,
|
||||
SpvOpAsmCallINTEL = 5611,
|
||||
SpvOpAtomicFMinEXT = 5614,
|
||||
SpvOpAtomicFMaxEXT = 5615,
|
||||
SpvOpAssumeTrueKHR = 5630,
|
||||
SpvOpExpectKHR = 5631,
|
||||
SpvOpDecorateString = 5632,
|
||||
SpvOpDecorateStringGOOGLE = 5632,
|
||||
SpvOpMemberDecorateString = 5633,
|
||||
@@ -1594,7 +1794,67 @@ typedef enum SpvOp_ {
|
||||
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,
|
||||
@@ -1616,10 +1876,27 @@ typedef enum SpvOp_ {
|
||||
SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031,
|
||||
SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032,
|
||||
SpvOpAtomicFAddEXT = 6035,
|
||||
SpvOpTypeBufferSurfaceINTEL = 6086,
|
||||
SpvOpTypeStructContinuedINTEL = 6090,
|
||||
SpvOpConstantCompositeContinuedINTEL = 6091,
|
||||
SpvOpSpecConstantCompositeContinuedINTEL = 6092,
|
||||
SpvOpControlBarrierArriveINTEL = 6142,
|
||||
SpvOpControlBarrierWaitINTEL = 6143,
|
||||
SpvOpGroupIMulKHR = 6401,
|
||||
SpvOpGroupFMulKHR = 6402,
|
||||
SpvOpGroupBitwiseAndKHR = 6403,
|
||||
SpvOpGroupBitwiseOrKHR = 6404,
|
||||
SpvOpGroupBitwiseXorKHR = 6405,
|
||||
SpvOpGroupLogicalAndKHR = 6406,
|
||||
SpvOpGroupLogicalOrKHR = 6407,
|
||||
SpvOpGroupLogicalXorKHR = 6408,
|
||||
SpvOpMax = 0x7fffffff,
|
||||
} SpvOp;
|
||||
|
||||
#ifdef SPV_ENABLE_UTILITY_CODE
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) {
|
||||
*hasResult = *hasResultType = false;
|
||||
switch (opcode) {
|
||||
@@ -1974,12 +2251,19 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpSDot: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpUDot: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSUDot: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSDotAccSat: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpUDotAccSat: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSUDotAccSat: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
|
||||
case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
|
||||
@@ -1999,12 +2283,16 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; 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 SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
|
||||
case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
|
||||
@@ -2014,8 +2302,15 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpDemoteToHelperInvocationEXT: *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;
|
||||
@@ -2040,8 +2335,15 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpFunctionPointerINTEL: *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;
|
||||
@@ -2162,7 +2464,67 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
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;
|
||||
@@ -2184,6 +2546,20 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||
}
|
||||
}
|
||||
#endif /* SPV_ENABLE_UTILITY_CODE */
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
// the Binary Section of the SPIR-V specification.
|
||||
|
||||
// Enumeration tokens for SPIR-V, in various styles:
|
||||
// C, C++, C++11, JSON, Lua, Python, C#, D
|
||||
// C, 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
|
||||
@@ -36,6 +36,8 @@
|
||||
// - 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
|
||||
@@ -49,12 +51,12 @@ namespace spv {
|
||||
|
||||
typedef unsigned int Id;
|
||||
|
||||
#define SPV_VERSION 0x10500
|
||||
#define SPV_REVISION 4
|
||||
#define SPV_VERSION 0x10600
|
||||
#define SPV_REVISION 1
|
||||
|
||||
static const unsigned int MagicNumber = 0x07230203;
|
||||
static const unsigned int Version = 0x00010500;
|
||||
static const unsigned int Revision = 4;
|
||||
static const unsigned int Version = 0x00010600;
|
||||
static const unsigned int Revision = 1;
|
||||
static const unsigned int OpCodeMask = 0xffff;
|
||||
static const unsigned int WordCountShift = 16;
|
||||
|
||||
@@ -65,6 +67,8 @@ enum SourceLanguage {
|
||||
SourceLanguageOpenCL_C = 3,
|
||||
SourceLanguageOpenCL_CPP = 4,
|
||||
SourceLanguageHLSL = 5,
|
||||
SourceLanguageCPP_for_OpenCL = 6,
|
||||
SourceLanguageSYCL = 7,
|
||||
SourceLanguageMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -90,6 +94,8 @@ enum ExecutionModel {
|
||||
ExecutionModelMissNV = 5317,
|
||||
ExecutionModelCallableKHR = 5318,
|
||||
ExecutionModelCallableNV = 5318,
|
||||
ExecutionModelTaskEXT = 5364,
|
||||
ExecutionModelMeshEXT = 5365,
|
||||
ExecutionModelMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -150,17 +156,28 @@ enum ExecutionMode {
|
||||
ExecutionModeSubgroupsPerWorkgroupId = 37,
|
||||
ExecutionModeLocalSizeId = 38,
|
||||
ExecutionModeLocalSizeHintId = 39,
|
||||
ExecutionModeSubgroupUniformControlFlowKHR = 4421,
|
||||
ExecutionModePostDepthCoverage = 4446,
|
||||
ExecutionModeDenormPreserve = 4459,
|
||||
ExecutionModeDenormFlushToZero = 4460,
|
||||
ExecutionModeSignedZeroInfNanPreserve = 4461,
|
||||
ExecutionModeRoundingModeRTE = 4462,
|
||||
ExecutionModeRoundingModeRTZ = 4463,
|
||||
ExecutionModeEarlyAndLateFragmentTestsAMD = 5017,
|
||||
ExecutionModeStencilRefReplacingEXT = 5027,
|
||||
ExecutionModeStencilRefUnchangedFrontAMD = 5079,
|
||||
ExecutionModeStencilRefGreaterFrontAMD = 5080,
|
||||
ExecutionModeStencilRefLessFrontAMD = 5081,
|
||||
ExecutionModeStencilRefUnchangedBackAMD = 5082,
|
||||
ExecutionModeStencilRefGreaterBackAMD = 5083,
|
||||
ExecutionModeStencilRefLessBackAMD = 5084,
|
||||
ExecutionModeOutputLinesEXT = 5269,
|
||||
ExecutionModeOutputLinesNV = 5269,
|
||||
ExecutionModeOutputPrimitivesEXT = 5270,
|
||||
ExecutionModeOutputPrimitivesNV = 5270,
|
||||
ExecutionModeDerivativeGroupQuadsNV = 5289,
|
||||
ExecutionModeDerivativeGroupLinearNV = 5290,
|
||||
ExecutionModeOutputTrianglesEXT = 5298,
|
||||
ExecutionModeOutputTrianglesNV = 5298,
|
||||
ExecutionModePixelInterlockOrderedEXT = 5366,
|
||||
ExecutionModePixelInterlockUnorderedEXT = 5367,
|
||||
@@ -168,10 +185,17 @@ enum ExecutionMode {
|
||||
ExecutionModeSampleInterlockUnorderedEXT = 5369,
|
||||
ExecutionModeShadingRateInterlockOrderedEXT = 5370,
|
||||
ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
|
||||
ExecutionModeSharedLocalMemorySizeINTEL = 5618,
|
||||
ExecutionModeRoundingModeRTPINTEL = 5620,
|
||||
ExecutionModeRoundingModeRTNINTEL = 5621,
|
||||
ExecutionModeFloatingPointModeALTINTEL = 5622,
|
||||
ExecutionModeFloatingPointModeIEEEINTEL = 5623,
|
||||
ExecutionModeMaxWorkgroupSizeINTEL = 5893,
|
||||
ExecutionModeMaxWorkDimINTEL = 5894,
|
||||
ExecutionModeNoGlobalOffsetINTEL = 5895,
|
||||
ExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
||||
ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
|
||||
ExecutionModeNamedBarrierCountINTEL = 6417,
|
||||
ExecutionModeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -203,7 +227,10 @@ enum StorageClass {
|
||||
StorageClassShaderRecordBufferNV = 5343,
|
||||
StorageClassPhysicalStorageBuffer = 5349,
|
||||
StorageClassPhysicalStorageBufferEXT = 5349,
|
||||
StorageClassTaskPayloadWorkgroupEXT = 5402,
|
||||
StorageClassCodeSectionINTEL = 5605,
|
||||
StorageClassDeviceOnlyINTEL = 5936,
|
||||
StorageClassHostOnlyINTEL = 5937,
|
||||
StorageClassMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -343,6 +370,8 @@ enum ImageOperandsShift {
|
||||
ImageOperandsVolatileTexelKHRShift = 11,
|
||||
ImageOperandsSignExtendShift = 12,
|
||||
ImageOperandsZeroExtendShift = 13,
|
||||
ImageOperandsNontemporalShift = 14,
|
||||
ImageOperandsOffsetsShift = 16,
|
||||
ImageOperandsMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -366,6 +395,8 @@ enum ImageOperandsMask {
|
||||
ImageOperandsVolatileTexelKHRMask = 0x00000800,
|
||||
ImageOperandsSignExtendMask = 0x00001000,
|
||||
ImageOperandsZeroExtendMask = 0x00002000,
|
||||
ImageOperandsNontemporalMask = 0x00004000,
|
||||
ImageOperandsOffsetsMask = 0x00010000,
|
||||
};
|
||||
|
||||
enum FPFastMathModeShift {
|
||||
@@ -374,6 +405,8 @@ enum FPFastMathModeShift {
|
||||
FPFastMathModeNSZShift = 2,
|
||||
FPFastMathModeAllowRecipShift = 3,
|
||||
FPFastMathModeFastShift = 4,
|
||||
FPFastMathModeAllowContractFastINTELShift = 16,
|
||||
FPFastMathModeAllowReassocINTELShift = 17,
|
||||
FPFastMathModeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -384,6 +417,8 @@ enum FPFastMathModeMask {
|
||||
FPFastMathModeNSZMask = 0x00000004,
|
||||
FPFastMathModeAllowRecipMask = 0x00000008,
|
||||
FPFastMathModeFastMask = 0x00000010,
|
||||
FPFastMathModeAllowContractFastINTELMask = 0x00010000,
|
||||
FPFastMathModeAllowReassocINTELMask = 0x00020000,
|
||||
};
|
||||
|
||||
enum FPRoundingMode {
|
||||
@@ -397,6 +432,7 @@ enum FPRoundingMode {
|
||||
enum LinkageType {
|
||||
LinkageTypeExport = 0,
|
||||
LinkageTypeImport = 1,
|
||||
LinkageTypeLinkOnceODR = 2,
|
||||
LinkageTypeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -474,9 +510,11 @@ enum Decoration {
|
||||
DecorationPassthroughNV = 5250,
|
||||
DecorationViewportRelativeNV = 5252,
|
||||
DecorationSecondaryViewportRelativeNV = 5256,
|
||||
DecorationPerPrimitiveEXT = 5271,
|
||||
DecorationPerPrimitiveNV = 5271,
|
||||
DecorationPerViewNV = 5272,
|
||||
DecorationPerTaskNV = 5273,
|
||||
DecorationPerVertexKHR = 5285,
|
||||
DecorationPerVertexNV = 5285,
|
||||
DecorationNonUniform = 5300,
|
||||
DecorationNonUniformEXT = 5300,
|
||||
@@ -484,12 +522,26 @@ enum Decoration {
|
||||
DecorationRestrictPointerEXT = 5355,
|
||||
DecorationAliasedPointer = 5356,
|
||||
DecorationAliasedPointerEXT = 5356,
|
||||
DecorationBindlessSamplerNV = 5398,
|
||||
DecorationBindlessImageNV = 5399,
|
||||
DecorationBoundSamplerNV = 5400,
|
||||
DecorationBoundImageNV = 5401,
|
||||
DecorationSIMTCallINTEL = 5599,
|
||||
DecorationReferencedIndirectlyINTEL = 5602,
|
||||
DecorationClobberINTEL = 5607,
|
||||
DecorationSideEffectsINTEL = 5608,
|
||||
DecorationVectorComputeVariableINTEL = 5624,
|
||||
DecorationFuncParamIOKindINTEL = 5625,
|
||||
DecorationVectorComputeFunctionINTEL = 5626,
|
||||
DecorationStackCallINTEL = 5627,
|
||||
DecorationGlobalVariableOffsetINTEL = 5628,
|
||||
DecorationCounterBuffer = 5634,
|
||||
DecorationHlslCounterBufferGOOGLE = 5634,
|
||||
DecorationHlslSemanticGOOGLE = 5635,
|
||||
DecorationUserSemantic = 5635,
|
||||
DecorationUserTypeGOOGLE = 5636,
|
||||
DecorationFunctionRoundingModeINTEL = 5822,
|
||||
DecorationFunctionDenormModeINTEL = 5823,
|
||||
DecorationRegisterINTEL = 5825,
|
||||
DecorationMemoryINTEL = 5826,
|
||||
DecorationNumbanksINTEL = 5827,
|
||||
@@ -502,6 +554,20 @@ enum Decoration {
|
||||
DecorationMergeINTEL = 5834,
|
||||
DecorationBankBitsINTEL = 5835,
|
||||
DecorationForcePow2DepthINTEL = 5836,
|
||||
DecorationBurstCoalesceINTEL = 5899,
|
||||
DecorationCacheSizeINTEL = 5900,
|
||||
DecorationDontStaticallyCoalesceINTEL = 5901,
|
||||
DecorationPrefetchINTEL = 5902,
|
||||
DecorationStallEnableINTEL = 5905,
|
||||
DecorationFuseLoopsInFunctionINTEL = 5907,
|
||||
DecorationAliasScopeINTEL = 5914,
|
||||
DecorationNoAliasINTEL = 5915,
|
||||
DecorationBufferLocationINTEL = 5921,
|
||||
DecorationIOPipeStorageINTEL = 5944,
|
||||
DecorationFunctionFloatingPointModeINTEL = 6080,
|
||||
DecorationSingleElementVectorINTEL = 6085,
|
||||
DecorationVectorComputeCallableFunctionINTEL = 6087,
|
||||
DecorationMediaBlockIOINTEL = 6140,
|
||||
DecorationMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -586,12 +652,18 @@ enum BuiltIn {
|
||||
BuiltInLayerPerViewNV = 5279,
|
||||
BuiltInMeshViewCountNV = 5280,
|
||||
BuiltInMeshViewIndicesNV = 5281,
|
||||
BuiltInBaryCoordKHR = 5286,
|
||||
BuiltInBaryCoordNV = 5286,
|
||||
BuiltInBaryCoordNoPerspKHR = 5287,
|
||||
BuiltInBaryCoordNoPerspNV = 5287,
|
||||
BuiltInFragSizeEXT = 5292,
|
||||
BuiltInFragmentSizeNV = 5292,
|
||||
BuiltInFragInvocationCountEXT = 5293,
|
||||
BuiltInInvocationsPerPixelNV = 5293,
|
||||
BuiltInPrimitivePointIndicesEXT = 5294,
|
||||
BuiltInPrimitiveLineIndicesEXT = 5295,
|
||||
BuiltInPrimitiveTriangleIndicesEXT = 5296,
|
||||
BuiltInCullPrimitiveEXT = 5299,
|
||||
BuiltInLaunchIdKHR = 5319,
|
||||
BuiltInLaunchIdNV = 5319,
|
||||
BuiltInLaunchSizeKHR = 5320,
|
||||
@@ -617,6 +689,7 @@ enum BuiltIn {
|
||||
BuiltInHitTNV = 5332,
|
||||
BuiltInHitKindKHR = 5333,
|
||||
BuiltInHitKindNV = 5333,
|
||||
BuiltInCurrentRayTimeNV = 5334,
|
||||
BuiltInIncomingRayFlagsKHR = 5351,
|
||||
BuiltInIncomingRayFlagsNV = 5351,
|
||||
BuiltInRayGeometryIndexKHR = 5352,
|
||||
@@ -624,6 +697,7 @@ enum BuiltIn {
|
||||
BuiltInSMCountNV = 5375,
|
||||
BuiltInWarpIDNV = 5376,
|
||||
BuiltInSMIDNV = 5377,
|
||||
BuiltInCullMaskKHR = 6021,
|
||||
BuiltInMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -656,6 +730,7 @@ enum LoopControlShift {
|
||||
LoopControlLoopCoalesceINTELShift = 20,
|
||||
LoopControlMaxInterleavingINTELShift = 21,
|
||||
LoopControlSpeculatedIterationsINTELShift = 22,
|
||||
LoopControlNoFusionINTELShift = 23,
|
||||
LoopControlMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -677,6 +752,7 @@ enum LoopControlMask {
|
||||
LoopControlLoopCoalesceINTELMask = 0x00100000,
|
||||
LoopControlMaxInterleavingINTELMask = 0x00200000,
|
||||
LoopControlSpeculatedIterationsINTELMask = 0x00400000,
|
||||
LoopControlNoFusionINTELMask = 0x00800000,
|
||||
};
|
||||
|
||||
enum FunctionControlShift {
|
||||
@@ -684,6 +760,7 @@ enum FunctionControlShift {
|
||||
FunctionControlDontInlineShift = 1,
|
||||
FunctionControlPureShift = 2,
|
||||
FunctionControlConstShift = 3,
|
||||
FunctionControlOptNoneINTELShift = 16,
|
||||
FunctionControlMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -693,6 +770,7 @@ enum FunctionControlMask {
|
||||
FunctionControlDontInlineMask = 0x00000002,
|
||||
FunctionControlPureMask = 0x00000004,
|
||||
FunctionControlConstMask = 0x00000008,
|
||||
FunctionControlOptNoneINTELMask = 0x00010000,
|
||||
};
|
||||
|
||||
enum MemorySemanticsShift {
|
||||
@@ -747,6 +825,8 @@ enum MemoryAccessShift {
|
||||
MemoryAccessMakePointerVisibleKHRShift = 4,
|
||||
MemoryAccessNonPrivatePointerShift = 5,
|
||||
MemoryAccessNonPrivatePointerKHRShift = 5,
|
||||
MemoryAccessAliasScopeINTELMaskShift = 16,
|
||||
MemoryAccessNoAliasINTELMaskShift = 17,
|
||||
MemoryAccessMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -761,6 +841,8 @@ enum MemoryAccessMask {
|
||||
MemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
||||
MemoryAccessNonPrivatePointerMask = 0x00000020,
|
||||
MemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
||||
MemoryAccessAliasScopeINTELMaskMask = 0x00010000,
|
||||
MemoryAccessNoAliasINTELMaskMask = 0x00020000,
|
||||
};
|
||||
|
||||
enum Scope {
|
||||
@@ -873,9 +955,13 @@ enum Capability {
|
||||
CapabilityGroupNonUniformQuad = 68,
|
||||
CapabilityShaderLayer = 69,
|
||||
CapabilityShaderViewportIndex = 70,
|
||||
CapabilityUniformDecoration = 71,
|
||||
CapabilityFragmentShadingRateKHR = 4422,
|
||||
CapabilitySubgroupBallotKHR = 4423,
|
||||
CapabilityDrawParameters = 4427,
|
||||
CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428,
|
||||
CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429,
|
||||
CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430,
|
||||
CapabilitySubgroupVoteKHR = 4431,
|
||||
CapabilityStorageBuffer16BitAccess = 4433,
|
||||
CapabilityStorageUniformBufferBlock16 = 4433,
|
||||
@@ -918,6 +1004,8 @@ enum Capability {
|
||||
CapabilityFragmentFullyCoveredEXT = 5265,
|
||||
CapabilityMeshShadingNV = 5266,
|
||||
CapabilityImageFootprintNV = 5282,
|
||||
CapabilityMeshShadingEXT = 5283,
|
||||
CapabilityFragmentBarycentricKHR = 5284,
|
||||
CapabilityFragmentBarycentricNV = 5284,
|
||||
CapabilityComputeDerivativeGroupQuadsNV = 5288,
|
||||
CapabilityFragmentDensityEXT = 5291,
|
||||
@@ -948,6 +1036,7 @@ enum Capability {
|
||||
CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
|
||||
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
|
||||
CapabilityRayTracingNV = 5340,
|
||||
CapabilityRayTracingMotionBlurNV = 5341,
|
||||
CapabilityVulkanMemoryModel = 5345,
|
||||
CapabilityVulkanMemoryModelKHR = 5345,
|
||||
CapabilityVulkanMemoryModelDeviceScope = 5346,
|
||||
@@ -961,26 +1050,67 @@ enum Capability {
|
||||
CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
|
||||
CapabilityShaderSMBuiltinsNV = 5373,
|
||||
CapabilityFragmentShaderPixelInterlockEXT = 5378,
|
||||
CapabilityDemoteToHelperInvocation = 5379,
|
||||
CapabilityDemoteToHelperInvocationEXT = 5379,
|
||||
CapabilityBindlessTextureNV = 5390,
|
||||
CapabilitySubgroupShuffleINTEL = 5568,
|
||||
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
||||
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||
CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
|
||||
CapabilityRoundToInfinityINTEL = 5582,
|
||||
CapabilityFloatingPointModeINTEL = 5583,
|
||||
CapabilityIntegerFunctions2INTEL = 5584,
|
||||
CapabilityFunctionPointersINTEL = 5603,
|
||||
CapabilityIndirectReferencesINTEL = 5604,
|
||||
CapabilityAsmINTEL = 5606,
|
||||
CapabilityAtomicFloat32MinMaxEXT = 5612,
|
||||
CapabilityAtomicFloat64MinMaxEXT = 5613,
|
||||
CapabilityAtomicFloat16MinMaxEXT = 5616,
|
||||
CapabilityVectorComputeINTEL = 5617,
|
||||
CapabilityVectorAnyINTEL = 5619,
|
||||
CapabilityExpectAssumeKHR = 5629,
|
||||
CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
|
||||
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
|
||||
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
|
||||
CapabilityVariableLengthArrayINTEL = 5817,
|
||||
CapabilityFunctionFloatControlINTEL = 5821,
|
||||
CapabilityFPGAMemoryAttributesINTEL = 5824,
|
||||
CapabilityFPFastMathModeINTEL = 5837,
|
||||
CapabilityArbitraryPrecisionIntegersINTEL = 5844,
|
||||
CapabilityArbitraryPrecisionFloatingPointINTEL = 5845,
|
||||
CapabilityUnstructuredLoopControlsINTEL = 5886,
|
||||
CapabilityFPGALoopControlsINTEL = 5888,
|
||||
CapabilityKernelAttributesINTEL = 5892,
|
||||
CapabilityFPGAKernelAttributesINTEL = 5897,
|
||||
CapabilityFPGAMemoryAccessesINTEL = 5898,
|
||||
CapabilityFPGAClusterAttributesINTEL = 5904,
|
||||
CapabilityLoopFuseINTEL = 5906,
|
||||
CapabilityMemoryAccessAliasingINTEL = 5910,
|
||||
CapabilityFPGABufferLocationINTEL = 5920,
|
||||
CapabilityArbitraryPrecisionFixedPointINTEL = 5922,
|
||||
CapabilityUSMStorageClassesINTEL = 5935,
|
||||
CapabilityIOPipesINTEL = 5943,
|
||||
CapabilityBlockingPipesINTEL = 5945,
|
||||
CapabilityFPGARegINTEL = 5948,
|
||||
CapabilityDotProductInputAll = 6016,
|
||||
CapabilityDotProductInputAllKHR = 6016,
|
||||
CapabilityDotProductInput4x8Bit = 6017,
|
||||
CapabilityDotProductInput4x8BitKHR = 6017,
|
||||
CapabilityDotProductInput4x8BitPacked = 6018,
|
||||
CapabilityDotProductInput4x8BitPackedKHR = 6018,
|
||||
CapabilityDotProduct = 6019,
|
||||
CapabilityDotProductKHR = 6019,
|
||||
CapabilityRayCullMaskKHR = 6020,
|
||||
CapabilityBitInstructions = 6025,
|
||||
CapabilityGroupNonUniformRotateKHR = 6026,
|
||||
CapabilityAtomicFloat32AddEXT = 6033,
|
||||
CapabilityAtomicFloat64AddEXT = 6034,
|
||||
CapabilityLongConstantCompositeINTEL = 6089,
|
||||
CapabilityOptNoneINTEL = 6094,
|
||||
CapabilityAtomicFloat16AddEXT = 6095,
|
||||
CapabilityDebugInfoModuleINTEL = 6114,
|
||||
CapabilitySplitBarrierINTEL = 6141,
|
||||
CapabilityGroupUniformArithmeticKHR = 6400,
|
||||
CapabilityMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -1047,6 +1177,44 @@ enum FragmentShadingRateMask {
|
||||
FragmentShadingRateHorizontal4PixelsMask = 0x00000008,
|
||||
};
|
||||
|
||||
enum FPDenormMode {
|
||||
FPDenormModePreserve = 0,
|
||||
FPDenormModeFlushToZero = 1,
|
||||
FPDenormModeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum FPOperationMode {
|
||||
FPOperationModeIEEE = 0,
|
||||
FPOperationModeALT = 1,
|
||||
FPOperationModeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum QuantizationModes {
|
||||
QuantizationModesTRN = 0,
|
||||
QuantizationModesTRN_ZERO = 1,
|
||||
QuantizationModesRND = 2,
|
||||
QuantizationModesRND_ZERO = 3,
|
||||
QuantizationModesRND_INF = 4,
|
||||
QuantizationModesRND_MIN_INF = 5,
|
||||
QuantizationModesRND_CONV = 6,
|
||||
QuantizationModesRND_CONV_ODD = 7,
|
||||
QuantizationModesMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum OverflowModes {
|
||||
OverflowModesWRAP = 0,
|
||||
OverflowModesSAT = 1,
|
||||
OverflowModesSAT_ZERO = 2,
|
||||
OverflowModesSAT_SYM = 3,
|
||||
OverflowModesMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum PackedVectorFormat {
|
||||
PackedVectorFormatPackedVectorFormat4x8Bit = 0,
|
||||
PackedVectorFormatPackedVectorFormat4x8BitKHR = 0,
|
||||
PackedVectorFormatMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum Op {
|
||||
OpNop = 0,
|
||||
OpUndef = 1,
|
||||
@@ -1398,12 +1566,25 @@ enum Op {
|
||||
OpSubgroupAllKHR = 4428,
|
||||
OpSubgroupAnyKHR = 4429,
|
||||
OpSubgroupAllEqualKHR = 4430,
|
||||
OpGroupNonUniformRotateKHR = 4431,
|
||||
OpSubgroupReadInvocationKHR = 4432,
|
||||
OpTraceRayKHR = 4445,
|
||||
OpExecuteCallableKHR = 4446,
|
||||
OpConvertUToAccelerationStructureKHR = 4447,
|
||||
OpIgnoreIntersectionKHR = 4448,
|
||||
OpTerminateRayKHR = 4449,
|
||||
OpSDot = 4450,
|
||||
OpSDotKHR = 4450,
|
||||
OpUDot = 4451,
|
||||
OpUDotKHR = 4451,
|
||||
OpSUDot = 4452,
|
||||
OpSUDotKHR = 4452,
|
||||
OpSDotAccSat = 4453,
|
||||
OpSDotAccSatKHR = 4453,
|
||||
OpUDotAccSat = 4454,
|
||||
OpUDotAccSatKHR = 4454,
|
||||
OpSUDotAccSat = 4455,
|
||||
OpSUDotAccSatKHR = 4455,
|
||||
OpTypeRayQueryKHR = 4472,
|
||||
OpRayQueryInitializeKHR = 4473,
|
||||
OpRayQueryTerminateKHR = 4474,
|
||||
@@ -1423,6 +1604,8 @@ enum Op {
|
||||
OpFragmentFetchAMD = 5012,
|
||||
OpReadClockKHR = 5056,
|
||||
OpImageSampleFootprintNV = 5283,
|
||||
OpEmitMeshTasksEXT = 5294,
|
||||
OpSetMeshOutputsEXT = 5295,
|
||||
OpGroupNonUniformPartitionNV = 5296,
|
||||
OpWritePackedPrimitiveIndices4x8NV = 5299,
|
||||
OpReportIntersectionKHR = 5334,
|
||||
@@ -1430,6 +1613,8 @@ enum Op {
|
||||
OpIgnoreIntersectionNV = 5335,
|
||||
OpTerminateRayNV = 5336,
|
||||
OpTraceNV = 5337,
|
||||
OpTraceMotionNV = 5338,
|
||||
OpTraceRayMotionNV = 5339,
|
||||
OpTypeAccelerationStructureKHR = 5341,
|
||||
OpTypeAccelerationStructureNV = 5341,
|
||||
OpExecuteCallableNV = 5344,
|
||||
@@ -1440,8 +1625,16 @@ enum Op {
|
||||
OpCooperativeMatrixLengthNV = 5362,
|
||||
OpBeginInvocationInterlockEXT = 5364,
|
||||
OpEndInvocationInterlockEXT = 5365,
|
||||
OpDemoteToHelperInvocation = 5380,
|
||||
OpDemoteToHelperInvocationEXT = 5380,
|
||||
OpIsHelperInvocationEXT = 5381,
|
||||
OpConvertUToImageNV = 5391,
|
||||
OpConvertUToSamplerNV = 5392,
|
||||
OpConvertImageToUNV = 5393,
|
||||
OpConvertSamplerToUNV = 5394,
|
||||
OpConvertUToSampledImageNV = 5395,
|
||||
OpConvertSampledImageToUNV = 5396,
|
||||
OpSamplerImageAddressingModeNV = 5397,
|
||||
OpSubgroupShuffleINTEL = 5571,
|
||||
OpSubgroupShuffleDownINTEL = 5572,
|
||||
OpSubgroupShuffleUpINTEL = 5573,
|
||||
@@ -1466,8 +1659,15 @@ enum Op {
|
||||
OpUSubSatINTEL = 5596,
|
||||
OpIMul32x16INTEL = 5597,
|
||||
OpUMul32x16INTEL = 5598,
|
||||
OpFunctionPointerINTEL = 5600,
|
||||
OpConstantFunctionPointerINTEL = 5600,
|
||||
OpFunctionPointerCallINTEL = 5601,
|
||||
OpAsmTargetINTEL = 5609,
|
||||
OpAsmINTEL = 5610,
|
||||
OpAsmCallINTEL = 5611,
|
||||
OpAtomicFMinEXT = 5614,
|
||||
OpAtomicFMaxEXT = 5615,
|
||||
OpAssumeTrueKHR = 5630,
|
||||
OpExpectKHR = 5631,
|
||||
OpDecorateString = 5632,
|
||||
OpDecorateStringGOOGLE = 5632,
|
||||
OpMemberDecorateString = 5633,
|
||||
@@ -1590,7 +1790,67 @@ enum Op {
|
||||
OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
|
||||
OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
|
||||
OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
|
||||
OpVariableLengthArrayINTEL = 5818,
|
||||
OpSaveMemoryINTEL = 5819,
|
||||
OpRestoreMemoryINTEL = 5820,
|
||||
OpArbitraryFloatSinCosPiINTEL = 5840,
|
||||
OpArbitraryFloatCastINTEL = 5841,
|
||||
OpArbitraryFloatCastFromIntINTEL = 5842,
|
||||
OpArbitraryFloatCastToIntINTEL = 5843,
|
||||
OpArbitraryFloatAddINTEL = 5846,
|
||||
OpArbitraryFloatSubINTEL = 5847,
|
||||
OpArbitraryFloatMulINTEL = 5848,
|
||||
OpArbitraryFloatDivINTEL = 5849,
|
||||
OpArbitraryFloatGTINTEL = 5850,
|
||||
OpArbitraryFloatGEINTEL = 5851,
|
||||
OpArbitraryFloatLTINTEL = 5852,
|
||||
OpArbitraryFloatLEINTEL = 5853,
|
||||
OpArbitraryFloatEQINTEL = 5854,
|
||||
OpArbitraryFloatRecipINTEL = 5855,
|
||||
OpArbitraryFloatRSqrtINTEL = 5856,
|
||||
OpArbitraryFloatCbrtINTEL = 5857,
|
||||
OpArbitraryFloatHypotINTEL = 5858,
|
||||
OpArbitraryFloatSqrtINTEL = 5859,
|
||||
OpArbitraryFloatLogINTEL = 5860,
|
||||
OpArbitraryFloatLog2INTEL = 5861,
|
||||
OpArbitraryFloatLog10INTEL = 5862,
|
||||
OpArbitraryFloatLog1pINTEL = 5863,
|
||||
OpArbitraryFloatExpINTEL = 5864,
|
||||
OpArbitraryFloatExp2INTEL = 5865,
|
||||
OpArbitraryFloatExp10INTEL = 5866,
|
||||
OpArbitraryFloatExpm1INTEL = 5867,
|
||||
OpArbitraryFloatSinINTEL = 5868,
|
||||
OpArbitraryFloatCosINTEL = 5869,
|
||||
OpArbitraryFloatSinCosINTEL = 5870,
|
||||
OpArbitraryFloatSinPiINTEL = 5871,
|
||||
OpArbitraryFloatCosPiINTEL = 5872,
|
||||
OpArbitraryFloatASinINTEL = 5873,
|
||||
OpArbitraryFloatASinPiINTEL = 5874,
|
||||
OpArbitraryFloatACosINTEL = 5875,
|
||||
OpArbitraryFloatACosPiINTEL = 5876,
|
||||
OpArbitraryFloatATanINTEL = 5877,
|
||||
OpArbitraryFloatATanPiINTEL = 5878,
|
||||
OpArbitraryFloatATan2INTEL = 5879,
|
||||
OpArbitraryFloatPowINTEL = 5880,
|
||||
OpArbitraryFloatPowRINTEL = 5881,
|
||||
OpArbitraryFloatPowNINTEL = 5882,
|
||||
OpLoopControlINTEL = 5887,
|
||||
OpAliasDomainDeclINTEL = 5911,
|
||||
OpAliasScopeDeclINTEL = 5912,
|
||||
OpAliasScopeListDeclINTEL = 5913,
|
||||
OpFixedSqrtINTEL = 5923,
|
||||
OpFixedRecipINTEL = 5924,
|
||||
OpFixedRsqrtINTEL = 5925,
|
||||
OpFixedSinINTEL = 5926,
|
||||
OpFixedCosINTEL = 5927,
|
||||
OpFixedSinCosINTEL = 5928,
|
||||
OpFixedSinPiINTEL = 5929,
|
||||
OpFixedCosPiINTEL = 5930,
|
||||
OpFixedSinCosPiINTEL = 5931,
|
||||
OpFixedLogINTEL = 5932,
|
||||
OpFixedExpINTEL = 5933,
|
||||
OpPtrCastToCrossWorkgroupINTEL = 5934,
|
||||
OpCrossWorkgroupCastToPtrINTEL = 5938,
|
||||
OpReadPipeBlockingINTEL = 5946,
|
||||
OpWritePipeBlockingINTEL = 5947,
|
||||
OpFPGARegINTEL = 5949,
|
||||
@@ -1612,10 +1872,27 @@ enum Op {
|
||||
OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
|
||||
OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
|
||||
OpAtomicFAddEXT = 6035,
|
||||
OpTypeBufferSurfaceINTEL = 6086,
|
||||
OpTypeStructContinuedINTEL = 6090,
|
||||
OpConstantCompositeContinuedINTEL = 6091,
|
||||
OpSpecConstantCompositeContinuedINTEL = 6092,
|
||||
OpControlBarrierArriveINTEL = 6142,
|
||||
OpControlBarrierWaitINTEL = 6143,
|
||||
OpGroupIMulKHR = 6401,
|
||||
OpGroupFMulKHR = 6402,
|
||||
OpGroupBitwiseAndKHR = 6403,
|
||||
OpGroupBitwiseOrKHR = 6404,
|
||||
OpGroupBitwiseXorKHR = 6405,
|
||||
OpGroupLogicalAndKHR = 6406,
|
||||
OpGroupLogicalOrKHR = 6407,
|
||||
OpGroupLogicalXorKHR = 6408,
|
||||
OpMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
#ifdef SPV_ENABLE_UTILITY_CODE
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
*hasResult = *hasResultType = false;
|
||||
switch (opcode) {
|
||||
@@ -1970,12 +2247,19 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpSDot: *hasResult = true; *hasResultType = true; break;
|
||||
case OpUDot: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSUDot: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSDotAccSat: *hasResult = true; *hasResultType = true; break;
|
||||
case OpUDotAccSat: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSUDotAccSat: *hasResult = true; *hasResultType = true; break;
|
||||
case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
|
||||
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
|
||||
@@ -1995,12 +2279,16 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break;
|
||||
case OpReadClockKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break;
|
||||
case OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break;
|
||||
case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTraceNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
|
||||
case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
|
||||
@@ -2010,8 +2298,15 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
|
||||
case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
|
||||
case OpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break;
|
||||
case OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break;
|
||||
case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break;
|
||||
case OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
@@ -2036,8 +2331,15 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAsmINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpExpectKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpDecorateString: *hasResult = false; *hasResultType = false; break;
|
||||
case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
|
||||
case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
@@ -2158,7 +2460,67 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
@@ -2180,6 +2542,20 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
|
||||
case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||
}
|
||||
}
|
||||
#endif /* SPV_ENABLE_UTILITY_CODE */
|
||||
|
||||
@@ -306,15 +306,36 @@ bool CFG::node_terminates_control_flow_in_sub_graph(BlockID from, BlockID to) co
|
||||
|
||||
bool true_path_ignore = false;
|
||||
bool false_path_ignore = false;
|
||||
if (ignore_block_id && dom.terminator == SPIRBlock::Select)
|
||||
|
||||
bool merges_to_nothing = dom.merge == SPIRBlock::MergeNone ||
|
||||
(dom.merge == SPIRBlock::MergeSelection && dom.next_block &&
|
||||
compiler.get<SPIRBlock>(dom.next_block).terminator == SPIRBlock::Unreachable) ||
|
||||
(dom.merge == SPIRBlock::MergeLoop && dom.merge_block &&
|
||||
compiler.get<SPIRBlock>(dom.merge_block).terminator == SPIRBlock::Unreachable);
|
||||
|
||||
if (dom.self == from || merges_to_nothing)
|
||||
{
|
||||
auto &true_block = compiler.get<SPIRBlock>(dom.true_block);
|
||||
auto &false_block = compiler.get<SPIRBlock>(dom.false_block);
|
||||
auto &ignore_block = compiler.get<SPIRBlock>(ignore_block_id);
|
||||
true_path_ignore = compiler.execution_is_branchless(true_block, ignore_block);
|
||||
false_path_ignore = compiler.execution_is_branchless(false_block, ignore_block);
|
||||
// We can only ignore inner branchy paths if there is no merge,
|
||||
// i.e. no code is generated afterwards. E.g. this allows us to elide continue:
|
||||
// for (;;) { if (cond) { continue; } else { break; } }.
|
||||
// Codegen here in SPIR-V will be something like either no merge if one path directly breaks, or
|
||||
// we merge to Unreachable.
|
||||
if (ignore_block_id && dom.terminator == SPIRBlock::Select)
|
||||
{
|
||||
auto &true_block = compiler.get<SPIRBlock>(dom.true_block);
|
||||
auto &false_block = compiler.get<SPIRBlock>(dom.false_block);
|
||||
auto &ignore_block = compiler.get<SPIRBlock>(ignore_block_id);
|
||||
true_path_ignore = compiler.execution_is_branchless(true_block, ignore_block);
|
||||
false_path_ignore = compiler.execution_is_branchless(false_block, ignore_block);
|
||||
}
|
||||
}
|
||||
|
||||
// Cases where we allow traversal. This serves as a proxy for post-dominance in a loop body.
|
||||
// TODO: Might want to do full post-dominance analysis, but it's a lot of churn for something like this ...
|
||||
// - We're the merge block of a selection construct. Jump to header.
|
||||
// - We're the merge block of a loop. Jump to header.
|
||||
// - Direct branch. Trivial.
|
||||
// - Allow cases inside a branch if the header cannot merge execution before loop exit.
|
||||
if ((dom.merge == SPIRBlock::MergeSelection && dom.next_block == to) ||
|
||||
(dom.merge == SPIRBlock::MergeLoop && dom.merge_block == to) ||
|
||||
(dom.terminator == SPIRBlock::Direct && dom.next_block == to) ||
|
||||
|
||||
@@ -59,6 +59,11 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_reachable(uint32_t block) const
|
||||
{
|
||||
return visit_order.count(block) != 0;
|
||||
}
|
||||
|
||||
uint32_t get_visit_order(uint32_t block) const
|
||||
{
|
||||
auto itr = visit_order.find(block);
|
||||
|
||||
@@ -24,7 +24,11 @@
|
||||
#ifndef SPIRV_CROSS_COMMON_HPP
|
||||
#define SPIRV_CROSS_COMMON_HPP
|
||||
|
||||
#ifndef SPV_ENABLE_UTILITY_CODE
|
||||
#define SPV_ENABLE_UTILITY_CODE
|
||||
#endif
|
||||
#include "spirv.hpp"
|
||||
|
||||
#include "spirv_cross_containers.hpp"
|
||||
#include "spirv_cross_error_handling.hpp"
|
||||
#include <functional>
|
||||
@@ -291,6 +295,20 @@ inline std::string convert_to_string(double t, char locale_radix_point)
|
||||
return buf;
|
||||
}
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
class FloatFormatter
|
||||
{
|
||||
public:
|
||||
virtual ~FloatFormatter() = default;
|
||||
virtual std::string format_float(float value) = 0;
|
||||
virtual std::string format_double(double value) = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ValueSaver
|
||||
{
|
||||
@@ -314,12 +332,6 @@ struct ValueSaver
|
||||
T saved;
|
||||
};
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
struct Instruction
|
||||
{
|
||||
uint16_t op = 0;
|
||||
@@ -536,6 +548,9 @@ struct SPIRType : IVariant
|
||||
type = TypeType
|
||||
};
|
||||
|
||||
spv::Op op = spv::Op::OpNop;
|
||||
explicit SPIRType(spv::Op op_) : op(op_) {}
|
||||
|
||||
enum BaseType
|
||||
{
|
||||
Unknown,
|
||||
@@ -606,7 +621,7 @@ struct SPIRType : IVariant
|
||||
uint32_t sampled;
|
||||
spv::ImageFormat format;
|
||||
spv::AccessQualifier access;
|
||||
} image;
|
||||
} image = {};
|
||||
|
||||
// Structs can be declared multiple times if they are used as part of interface blocks.
|
||||
// We want to detect this so that we only emit the struct definition once.
|
||||
@@ -638,7 +653,10 @@ struct SPIRExtension : IVariant
|
||||
SPV_AMD_shader_ballot,
|
||||
SPV_AMD_shader_explicit_vertex_parameter,
|
||||
SPV_AMD_shader_trinary_minmax,
|
||||
SPV_AMD_gcn_shader
|
||||
SPV_AMD_gcn_shader,
|
||||
NonSemanticDebugPrintf,
|
||||
NonSemanticShaderDebugInfo,
|
||||
NonSemanticGeneric
|
||||
};
|
||||
|
||||
explicit SPIRExtension(Extension ext_)
|
||||
@@ -672,10 +690,12 @@ struct SPIREntryPoint
|
||||
struct WorkgroupSize
|
||||
{
|
||||
uint32_t x = 0, y = 0, z = 0;
|
||||
uint32_t id_x = 0, id_y = 0, id_z = 0;
|
||||
uint32_t constant = 0; // Workgroup size can be expressed as a constant/spec-constant instead.
|
||||
} workgroup_size;
|
||||
uint32_t invocations = 0;
|
||||
uint32_t output_vertices = 0;
|
||||
uint32_t output_primitives = 0;
|
||||
spv::ExecutionModel model = spv::ExecutionModelMax;
|
||||
bool geometry_passthrough = false;
|
||||
};
|
||||
@@ -689,7 +709,7 @@ struct SPIRExpression : IVariant
|
||||
|
||||
// Only created by the backend target to avoid creating tons of temporaries.
|
||||
SPIRExpression(std::string expr, TypeID expression_type_, bool immutable_)
|
||||
: expression(move(expr))
|
||||
: expression(std::move(expr))
|
||||
, expression_type(expression_type_)
|
||||
, immutable(immutable_)
|
||||
{
|
||||
@@ -720,6 +740,9 @@ struct SPIRExpression : IVariant
|
||||
// Whether or not this is an access chain expression.
|
||||
bool access_chain = false;
|
||||
|
||||
// Whether or not gl_MeshVerticesEXT[].gl_Position (as a whole or .y) is referenced
|
||||
bool access_meshlet_position_y = false;
|
||||
|
||||
// A list of expressions which this expression depends on.
|
||||
SmallVector<ID> expression_dependencies;
|
||||
|
||||
@@ -770,7 +793,8 @@ struct SPIRBlock : IVariant
|
||||
Unreachable, // Noop
|
||||
Kill, // Discard
|
||||
IgnoreIntersection, // Ray Tracing
|
||||
TerminateRay // Ray Tracing
|
||||
TerminateRay, // Ray Tracing
|
||||
EmitMeshTasks // Mesh shaders
|
||||
};
|
||||
|
||||
enum Merge
|
||||
@@ -832,6 +856,13 @@ struct SPIRBlock : IVariant
|
||||
BlockID false_block = 0;
|
||||
BlockID default_block = 0;
|
||||
|
||||
// If terminator is EmitMeshTasksEXT.
|
||||
struct
|
||||
{
|
||||
ID groups[3];
|
||||
ID payload;
|
||||
} mesh = {};
|
||||
|
||||
SmallVector<Instruction> ops;
|
||||
|
||||
struct Phi
|
||||
@@ -1071,7 +1102,6 @@ struct SPIRVariable : IVariant
|
||||
|
||||
// Temporaries which can remain forwarded as long as this variable is not modified.
|
||||
SmallVector<ID> dependees;
|
||||
bool forwardable = true;
|
||||
|
||||
bool deferred_declaration = false;
|
||||
bool phi_variable = false;
|
||||
@@ -1563,6 +1593,8 @@ struct AccessChainMeta
|
||||
bool storage_is_packed = false;
|
||||
bool storage_is_invariant = false;
|
||||
bool flattened_struct = false;
|
||||
bool relaxed_precision = false;
|
||||
bool access_meshlet_position_y = false;
|
||||
};
|
||||
|
||||
enum ExtendedDecorations
|
||||
@@ -1630,6 +1662,12 @@ enum ExtendedDecorations
|
||||
// results of interpolation can.
|
||||
SPIRVCrossDecorationInterpolantComponentExpr,
|
||||
|
||||
// Apply to any struct type that is used in the Workgroup storage class.
|
||||
// This causes matrices in MSL prior to Metal 3.0 to be emitted using a special
|
||||
// class that is convertible to the standard matrix type, to work around the
|
||||
// lack of constructors in the 'threadgroup' address space.
|
||||
SPIRVCrossDecorationWorkgroupStruct,
|
||||
|
||||
SPIRVCrossDecorationCount
|
||||
};
|
||||
|
||||
@@ -1640,6 +1678,7 @@ struct Meta
|
||||
std::string alias;
|
||||
std::string qualified_alias;
|
||||
std::string hlsl_semantic;
|
||||
std::string user_type;
|
||||
Bitset decoration_flags;
|
||||
spv::BuiltIn builtin_type = spv::BuiltInMax;
|
||||
uint32_t location = 0;
|
||||
@@ -1775,6 +1814,33 @@ static inline bool opcode_is_sign_invariant(spv::Op opcode)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool opcode_can_promote_integer_implicitly(spv::Op opcode)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case spv::OpSNegate:
|
||||
case spv::OpNot:
|
||||
case spv::OpBitwiseAnd:
|
||||
case spv::OpBitwiseOr:
|
||||
case spv::OpBitwiseXor:
|
||||
case spv::OpShiftLeftLogical:
|
||||
case spv::OpShiftRightLogical:
|
||||
case spv::OpShiftRightArithmetic:
|
||||
case spv::OpIAdd:
|
||||
case spv::OpISub:
|
||||
case spv::OpIMul:
|
||||
case spv::OpSDiv:
|
||||
case spv::OpUDiv:
|
||||
case spv::OpSRem:
|
||||
case spv::OpUMod:
|
||||
case spv::OpSMod:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct SetBindingPair
|
||||
{
|
||||
uint32_t desc_set;
|
||||
|
||||
@@ -274,8 +274,6 @@ void CompilerCPP::emit_resources()
|
||||
if (emitted)
|
||||
statement("");
|
||||
|
||||
declare_undefined_values();
|
||||
|
||||
statement("inline void init(spirv_cross_shader& s)");
|
||||
begin_scope();
|
||||
statement(resource_type, "::init(s);");
|
||||
@@ -338,11 +336,8 @@ string CompilerCPP::compile()
|
||||
uint32_t pass_count = 0;
|
||||
do
|
||||
{
|
||||
if (pass_count >= 3)
|
||||
SPIRV_CROSS_THROW("Over 3 compilation loops detected. Must be a bug!");
|
||||
|
||||
resource_registrations.clear();
|
||||
reset();
|
||||
reset(pass_count);
|
||||
|
||||
// Move constructor for this type is broken on GCC 4.9 ...
|
||||
buffer.reset();
|
||||
|
||||
@@ -36,16 +36,16 @@ using namespace SPIRV_CROSS_NAMESPACE;
|
||||
|
||||
Compiler::Compiler(vector<uint32_t> ir_)
|
||||
{
|
||||
Parser parser(move(ir_));
|
||||
Parser parser(std::move(ir_));
|
||||
parser.parse();
|
||||
set_ir(move(parser.get_parsed_ir()));
|
||||
set_ir(std::move(parser.get_parsed_ir()));
|
||||
}
|
||||
|
||||
Compiler::Compiler(const uint32_t *ir_, size_t word_count)
|
||||
{
|
||||
Parser parser(ir_, word_count);
|
||||
parser.parse();
|
||||
set_ir(move(parser.get_parsed_ir()));
|
||||
set_ir(std::move(parser.get_parsed_ir()));
|
||||
}
|
||||
|
||||
Compiler::Compiler(const ParsedIR &ir_)
|
||||
@@ -55,12 +55,12 @@ Compiler::Compiler(const ParsedIR &ir_)
|
||||
|
||||
Compiler::Compiler(ParsedIR &&ir_)
|
||||
{
|
||||
set_ir(move(ir_));
|
||||
set_ir(std::move(ir_));
|
||||
}
|
||||
|
||||
void Compiler::set_ir(ParsedIR &&ir_)
|
||||
{
|
||||
ir = move(ir_);
|
||||
ir = std::move(ir_);
|
||||
parse_fixup();
|
||||
}
|
||||
|
||||
@@ -98,7 +98,8 @@ bool Compiler::block_is_pure(const SPIRBlock &block)
|
||||
// This is a global side effect of the function.
|
||||
if (block.terminator == SPIRBlock::Kill ||
|
||||
block.terminator == SPIRBlock::TerminateRay ||
|
||||
block.terminator == SPIRBlock::IgnoreIntersection)
|
||||
block.terminator == SPIRBlock::IgnoreIntersection ||
|
||||
block.terminator == SPIRBlock::EmitMeshTasks)
|
||||
return false;
|
||||
|
||||
for (auto &i : block.ops)
|
||||
@@ -154,6 +155,11 @@ bool Compiler::block_is_pure(const SPIRBlock &block)
|
||||
case OpEmitVertex:
|
||||
return false;
|
||||
|
||||
// Mesh shader functions modify global state.
|
||||
// (EmitMeshTasks is a terminator).
|
||||
case OpSetMeshOutputsEXT:
|
||||
return false;
|
||||
|
||||
// Barriers disallow any reordering, so we should treat blocks with barrier as writing.
|
||||
case OpControlBarrier:
|
||||
case OpMemoryBarrier:
|
||||
@@ -621,7 +627,22 @@ bool Compiler::is_matrix(const SPIRType &type) const
|
||||
|
||||
bool Compiler::is_array(const SPIRType &type) const
|
||||
{
|
||||
return !type.array.empty();
|
||||
return type.op == OpTypeArray || type.op == OpTypeRuntimeArray;
|
||||
}
|
||||
|
||||
bool Compiler::is_pointer(const SPIRType &type) const
|
||||
{
|
||||
return type.op == OpTypePointer && type.basetype != SPIRType::Unknown; // Ignore function pointers.
|
||||
}
|
||||
|
||||
bool Compiler::is_physical_pointer(const SPIRType &type) const
|
||||
{
|
||||
return type.op == OpTypePointer && type.storage == StorageClassPhysicalStorageBuffer;
|
||||
}
|
||||
|
||||
bool Compiler::is_runtime_size_array(const SPIRType &type)
|
||||
{
|
||||
return type.op == OpTypeRuntimeArray;
|
||||
}
|
||||
|
||||
ShaderResources Compiler::get_shader_resources() const
|
||||
@@ -719,7 +740,7 @@ bool Compiler::InterfaceVariableAccessHandler::handle(Op opcode, const uint32_t
|
||||
|
||||
case OpExtInst:
|
||||
{
|
||||
if (length < 5)
|
||||
if (length < 3)
|
||||
return false;
|
||||
auto &extension_set = compiler.get<SPIRExtension>(args[2]);
|
||||
switch (extension_set.ext)
|
||||
@@ -852,7 +873,7 @@ unordered_set<VariableID> Compiler::get_active_interface_variables() const
|
||||
|
||||
void Compiler::set_enabled_interface_variables(std::unordered_set<VariableID> active_variables)
|
||||
{
|
||||
active_interface_variables = move(active_variables);
|
||||
active_interface_variables = std::move(active_variables);
|
||||
check_active_interface_variables = true;
|
||||
}
|
||||
|
||||
@@ -985,57 +1006,74 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<VariableID> *
|
||||
// in the future.
|
||||
res.push_constant_buffers.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
// Images
|
||||
else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Image &&
|
||||
type.image.sampled == 2)
|
||||
else if (type.storage == StorageClassShaderRecordBufferKHR)
|
||||
{
|
||||
res.storage_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
// Separate images
|
||||
else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Image &&
|
||||
type.image.sampled == 1)
|
||||
{
|
||||
res.separate_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
// Separate samplers
|
||||
else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Sampler)
|
||||
{
|
||||
res.separate_samplers.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
// Textures
|
||||
else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::SampledImage)
|
||||
{
|
||||
res.sampled_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
res.shader_record_buffers.push_back({ var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self, ssbo_instance_name) });
|
||||
}
|
||||
// Atomic counters
|
||||
else if (type.storage == StorageClassAtomicCounter)
|
||||
{
|
||||
res.atomic_counters.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
// Acceleration structures
|
||||
else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::AccelerationStructure)
|
||||
else if (type.storage == StorageClassUniformConstant)
|
||||
{
|
||||
res.acceleration_structures.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
if (type.basetype == SPIRType::Image)
|
||||
{
|
||||
// Images
|
||||
if (type.image.sampled == 2)
|
||||
{
|
||||
res.storage_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
// Separate images
|
||||
else if (type.image.sampled == 1)
|
||||
{
|
||||
res.separate_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
}
|
||||
// Separate samplers
|
||||
else if (type.basetype == SPIRType::Sampler)
|
||||
{
|
||||
res.separate_samplers.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
// Textures
|
||||
else if (type.basetype == SPIRType::SampledImage)
|
||||
{
|
||||
res.sampled_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
// Acceleration structures
|
||||
else if (type.basetype == SPIRType::AccelerationStructure)
|
||||
{
|
||||
res.acceleration_structures.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
else
|
||||
{
|
||||
res.gl_plain_uniforms.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Compiler::type_is_block_like(const SPIRType &type) const
|
||||
bool Compiler::type_is_top_level_block(const SPIRType &type) const
|
||||
{
|
||||
if (type.basetype != SPIRType::Struct)
|
||||
return false;
|
||||
return has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock);
|
||||
}
|
||||
|
||||
if (has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock))
|
||||
{
|
||||
bool Compiler::type_is_block_like(const SPIRType &type) const
|
||||
{
|
||||
if (type_is_top_level_block(type))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Block-like types may have Offset decorations.
|
||||
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
|
||||
if (has_member_decoration(type.self, i, DecorationOffset))
|
||||
return true;
|
||||
if (type.basetype == SPIRType::Struct)
|
||||
{
|
||||
// Block-like types may have Offset decorations.
|
||||
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
|
||||
if (has_member_decoration(type.self, i, DecorationOffset))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1050,10 +1088,12 @@ void Compiler::parse_fixup()
|
||||
if (id.get_type() == TypeConstant)
|
||||
{
|
||||
auto &c = id.get<SPIRConstant>();
|
||||
if (ir.meta[c.self].decoration.builtin && ir.meta[c.self].decoration.builtin_type == BuiltInWorkgroupSize)
|
||||
if (has_decoration(c.self, DecorationBuiltIn) &&
|
||||
BuiltIn(get_decoration(c.self, DecorationBuiltIn)) == BuiltInWorkgroupSize)
|
||||
{
|
||||
// In current SPIR-V, there can be just one constant like this.
|
||||
// All entry points will receive the constant value.
|
||||
// WorkgroupSize take precedence over LocalSizeId.
|
||||
for (auto &entry : ir.entry_points)
|
||||
{
|
||||
entry.second.workgroup_size.constant = c.self;
|
||||
@@ -1067,8 +1107,11 @@ void Compiler::parse_fixup()
|
||||
{
|
||||
auto &var = id.get<SPIRVariable>();
|
||||
if (var.storage == StorageClassPrivate || var.storage == StorageClassWorkgroup ||
|
||||
var.storage == StorageClassTaskPayloadWorkgroupEXT ||
|
||||
var.storage == StorageClassOutput)
|
||||
{
|
||||
global_variables.push_back(var.self);
|
||||
}
|
||||
if (variable_storage_is_aliased(var))
|
||||
aliased_variables.push_back(var.self);
|
||||
}
|
||||
@@ -1453,6 +1496,58 @@ bool Compiler::get_binary_offset_for_decoration(VariableID id, spv::Decoration d
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compiler::block_is_noop(const SPIRBlock &block) const
|
||||
{
|
||||
if (block.terminator != SPIRBlock::Direct)
|
||||
return false;
|
||||
|
||||
auto &child = get<SPIRBlock>(block.next_block);
|
||||
|
||||
// If this block participates in PHI, the block isn't really noop.
|
||||
for (auto &phi : block.phi_variables)
|
||||
if (phi.parent == block.self || phi.parent == child.self)
|
||||
return false;
|
||||
|
||||
for (auto &phi : child.phi_variables)
|
||||
if (phi.parent == block.self)
|
||||
return false;
|
||||
|
||||
// Verify all instructions have no semantic impact.
|
||||
for (auto &i : block.ops)
|
||||
{
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
// Non-Semantic instructions.
|
||||
case OpLine:
|
||||
case OpNoLine:
|
||||
break;
|
||||
|
||||
case OpExtInst:
|
||||
{
|
||||
auto *ops = stream(i);
|
||||
auto ext = get<SPIRExtension>(ops[2]).ext;
|
||||
|
||||
bool ext_is_nonsemantic_only =
|
||||
ext == SPIRExtension::NonSemanticShaderDebugInfo ||
|
||||
ext == SPIRExtension::SPV_debug_info ||
|
||||
ext == SPIRExtension::NonSemanticGeneric;
|
||||
|
||||
if (!ext_is_nonsemantic_only)
|
||||
return false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compiler::block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method method) const
|
||||
{
|
||||
// Tried and failed.
|
||||
@@ -1510,7 +1605,7 @@ bool Compiler::block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method
|
||||
{
|
||||
// Empty loop header that just sets up merge target
|
||||
// and branches to loop body.
|
||||
bool ret = block.terminator == SPIRBlock::Direct && block.merge == SPIRBlock::MergeLoop && block.ops.empty();
|
||||
bool ret = block.terminator == SPIRBlock::Direct && block.merge == SPIRBlock::MergeLoop && block_is_noop(block);
|
||||
|
||||
if (!ret)
|
||||
return false;
|
||||
@@ -1536,19 +1631,8 @@ bool Compiler::block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method
|
||||
ret = child.terminator == SPIRBlock::Select && child.merge == SPIRBlock::MergeNone &&
|
||||
(positive_candidate || negative_candidate);
|
||||
|
||||
// If we have OpPhi which depends on branches which came from our own block,
|
||||
// we need to flush phi variables in else block instead of a trivial break,
|
||||
// so we cannot assume this is a for loop candidate.
|
||||
if (ret)
|
||||
{
|
||||
for (auto &phi : block.phi_variables)
|
||||
if (phi.parent == block.self || phi.parent == child.self)
|
||||
return false;
|
||||
|
||||
for (auto &phi : child.phi_variables)
|
||||
if (phi.parent == block.self)
|
||||
return false;
|
||||
|
||||
auto *merge = maybe_get<SPIRBlock>(block.merge_block);
|
||||
if (merge)
|
||||
for (auto &phi : merge->phi_variables)
|
||||
@@ -1573,15 +1657,10 @@ bool Compiler::execution_is_noop(const SPIRBlock &from, const SPIRBlock &to) con
|
||||
if (start->self == to.self)
|
||||
return true;
|
||||
|
||||
if (!start->ops.empty())
|
||||
if (!block_is_noop(*start))
|
||||
return false;
|
||||
|
||||
auto &next = get<SPIRBlock>(start->next_block);
|
||||
// Flushing phi variables does not count as noop.
|
||||
for (auto &phi : next.phi_variables)
|
||||
if (phi.parent == start->self)
|
||||
return false;
|
||||
|
||||
start = &next;
|
||||
}
|
||||
}
|
||||
@@ -1675,6 +1754,11 @@ const SmallVector<SPIRBlock::Case> &Compiler::get_case_list(const SPIRBlock &blo
|
||||
const auto &type = get<SPIRType>(var->basetype);
|
||||
width = type.width;
|
||||
}
|
||||
else if (const auto *undef = maybe_get<SPIRUndef>(block.condition))
|
||||
{
|
||||
const auto &type = get<SPIRType>(undef->basetype);
|
||||
width = type.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto search = ir.load_type_width.find(block.condition);
|
||||
@@ -2156,6 +2240,12 @@ void Compiler::set_execution_mode(ExecutionMode mode, uint32_t arg0, uint32_t ar
|
||||
execution.workgroup_size.z = arg2;
|
||||
break;
|
||||
|
||||
case ExecutionModeLocalSizeId:
|
||||
execution.workgroup_size.id_x = arg0;
|
||||
execution.workgroup_size.id_y = arg1;
|
||||
execution.workgroup_size.id_z = arg2;
|
||||
break;
|
||||
|
||||
case ExecutionModeInvocations:
|
||||
execution.invocations = arg0;
|
||||
break;
|
||||
@@ -2164,6 +2254,10 @@ void Compiler::set_execution_mode(ExecutionMode mode, uint32_t arg0, uint32_t ar
|
||||
execution.output_vertices = arg0;
|
||||
break;
|
||||
|
||||
case ExecutionModeOutputPrimitivesEXT:
|
||||
execution.output_primitives = arg0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2183,6 +2277,7 @@ uint32_t Compiler::get_work_group_size_specialization_constants(SpecializationCo
|
||||
y = { 0, 0 };
|
||||
z = { 0, 0 };
|
||||
|
||||
// WorkgroupSize builtin takes precedence over LocalSize / LocalSizeId.
|
||||
if (execution.workgroup_size.constant != 0)
|
||||
{
|
||||
auto &c = get<SPIRConstant>(execution.workgroup_size.constant);
|
||||
@@ -2205,6 +2300,29 @@ uint32_t Compiler::get_work_group_size_specialization_constants(SpecializationCo
|
||||
z.constant_id = get_decoration(c.m.c[0].id[2], DecorationSpecId);
|
||||
}
|
||||
}
|
||||
else if (execution.flags.get(ExecutionModeLocalSizeId))
|
||||
{
|
||||
auto &cx = get<SPIRConstant>(execution.workgroup_size.id_x);
|
||||
if (cx.specialization)
|
||||
{
|
||||
x.id = execution.workgroup_size.id_x;
|
||||
x.constant_id = get_decoration(execution.workgroup_size.id_x, DecorationSpecId);
|
||||
}
|
||||
|
||||
auto &cy = get<SPIRConstant>(execution.workgroup_size.id_y);
|
||||
if (cy.specialization)
|
||||
{
|
||||
y.id = execution.workgroup_size.id_y;
|
||||
y.constant_id = get_decoration(execution.workgroup_size.id_y, DecorationSpecId);
|
||||
}
|
||||
|
||||
auto &cz = get<SPIRConstant>(execution.workgroup_size.id_z);
|
||||
if (cz.specialization)
|
||||
{
|
||||
z.id = execution.workgroup_size.id_z;
|
||||
z.constant_id = get_decoration(execution.workgroup_size.id_z, DecorationSpecId);
|
||||
}
|
||||
}
|
||||
|
||||
return execution.workgroup_size.constant;
|
||||
}
|
||||
@@ -2214,15 +2332,42 @@ uint32_t Compiler::get_execution_mode_argument(spv::ExecutionMode mode, uint32_t
|
||||
auto &execution = get_entry_point();
|
||||
switch (mode)
|
||||
{
|
||||
case ExecutionModeLocalSizeId:
|
||||
if (execution.flags.get(ExecutionModeLocalSizeId))
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return execution.workgroup_size.id_x;
|
||||
case 1:
|
||||
return execution.workgroup_size.id_y;
|
||||
case 2:
|
||||
return execution.workgroup_size.id_z;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
case ExecutionModeLocalSize:
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return execution.workgroup_size.x;
|
||||
if (execution.flags.get(ExecutionModeLocalSizeId) && execution.workgroup_size.id_x != 0)
|
||||
return get<SPIRConstant>(execution.workgroup_size.id_x).scalar();
|
||||
else
|
||||
return execution.workgroup_size.x;
|
||||
case 1:
|
||||
return execution.workgroup_size.y;
|
||||
if (execution.flags.get(ExecutionModeLocalSizeId) && execution.workgroup_size.id_y != 0)
|
||||
return get<SPIRConstant>(execution.workgroup_size.id_y).scalar();
|
||||
else
|
||||
return execution.workgroup_size.y;
|
||||
case 2:
|
||||
return execution.workgroup_size.z;
|
||||
if (execution.flags.get(ExecutionModeLocalSizeId) && execution.workgroup_size.id_z != 0)
|
||||
return get<SPIRConstant>(execution.workgroup_size.id_z).scalar();
|
||||
else
|
||||
return execution.workgroup_size.z;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -2233,6 +2378,9 @@ uint32_t Compiler::get_execution_mode_argument(spv::ExecutionMode mode, uint32_t
|
||||
case ExecutionModeOutputVertices:
|
||||
return execution.output_vertices;
|
||||
|
||||
case ExecutionModeOutputPrimitivesEXT:
|
||||
return execution.output_primitives;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -2261,6 +2409,11 @@ bool Compiler::is_tessellation_shader() const
|
||||
return is_tessellation_shader(get_execution_model());
|
||||
}
|
||||
|
||||
bool Compiler::is_tessellating_triangles() const
|
||||
{
|
||||
return get_execution_mode_bitset().get(ExecutionModeTriangles);
|
||||
}
|
||||
|
||||
void Compiler::set_remapped_variable_state(VariableID id, bool remap_enable)
|
||||
{
|
||||
get<SPIRVariable>(id).remapped_variable = remap_enable;
|
||||
@@ -2295,6 +2448,19 @@ void Compiler::add_implied_read_expression(SPIRAccessChain &e, uint32_t source)
|
||||
e.implied_read_expressions.push_back(source);
|
||||
}
|
||||
|
||||
void Compiler::add_active_interface_variable(uint32_t var_id)
|
||||
{
|
||||
active_interface_variables.insert(var_id);
|
||||
|
||||
// In SPIR-V 1.4 and up we must also track the interface variable in the entry point.
|
||||
if (ir.get_spirv_version() >= 0x10400)
|
||||
{
|
||||
auto &vars = get_entry_point().interface_variables;
|
||||
if (find(begin(vars), end(vars), VariableID(var_id)) == end(vars))
|
||||
vars.push_back(var_id);
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::inherit_expression_dependencies(uint32_t dst, uint32_t source_expression)
|
||||
{
|
||||
// Don't inherit any expression dependencies if the expression in dst
|
||||
@@ -2449,7 +2615,7 @@ void Compiler::CombinedImageSamplerHandler::push_remap_parameters(const SPIRFunc
|
||||
unordered_map<uint32_t, uint32_t> remapping;
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
remapping[func.arguments[i].id] = remap_parameter(args[i]);
|
||||
parameter_remapping.push(move(remapping));
|
||||
parameter_remapping.push(std::move(remapping));
|
||||
}
|
||||
|
||||
void Compiler::CombinedImageSamplerHandler::pop_remap_parameters()
|
||||
@@ -2579,8 +2745,8 @@ void Compiler::CombinedImageSamplerHandler::register_combined_image_sampler(SPIR
|
||||
auto ptr_type_id = id + 1;
|
||||
auto combined_id = id + 2;
|
||||
auto &base = compiler.expression_type(image_id);
|
||||
auto &type = compiler.set<SPIRType>(type_id);
|
||||
auto &ptr_type = compiler.set<SPIRType>(ptr_type_id);
|
||||
auto &type = compiler.set<SPIRType>(type_id, OpTypeSampledImage);
|
||||
auto &ptr_type = compiler.set<SPIRType>(ptr_type_id, OpTypePointer);
|
||||
|
||||
type = base;
|
||||
type.self = type_id;
|
||||
@@ -2839,7 +3005,7 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar
|
||||
{
|
||||
// Have to invent the sampled image type.
|
||||
sampled_type = compiler.ir.increase_bound_by(1);
|
||||
auto &type = compiler.set<SPIRType>(sampled_type);
|
||||
auto &type = compiler.set<SPIRType>(sampled_type, OpTypeSampledImage);
|
||||
type = compiler.expression_type(args[2]);
|
||||
type.self = sampled_type;
|
||||
type.basetype = SPIRType::SampledImage;
|
||||
@@ -2858,7 +3024,7 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar
|
||||
|
||||
// Make a new type, pointer to OpTypeSampledImage, so we can make a variable of this type.
|
||||
// We will probably have this type lying around, but it doesn't hurt to make duplicates for internal purposes.
|
||||
auto &type = compiler.set<SPIRType>(type_id);
|
||||
auto &type = compiler.set<SPIRType>(type_id, OpTypePointer);
|
||||
auto &base = compiler.get<SPIRType>(sampled_type);
|
||||
type = base;
|
||||
type.pointer = true;
|
||||
@@ -2904,11 +3070,10 @@ VariableID Compiler::build_dummy_sampler_for_combined_images()
|
||||
auto ptr_type_id = offset + 1;
|
||||
auto var_id = offset + 2;
|
||||
|
||||
SPIRType sampler_type;
|
||||
auto &sampler = set<SPIRType>(type_id);
|
||||
auto &sampler = set<SPIRType>(type_id, OpTypeSampler);
|
||||
sampler.basetype = SPIRType::Sampler;
|
||||
|
||||
auto &ptr_sampler = set<SPIRType>(ptr_type_id);
|
||||
auto &ptr_sampler = set<SPIRType>(ptr_type_id, OpTypePointer);
|
||||
ptr_sampler = sampler;
|
||||
ptr_sampler.self = type_id;
|
||||
ptr_sampler.storage = StorageClassUniformConstant;
|
||||
@@ -3111,8 +3276,8 @@ void Compiler::AnalyzeVariableScopeAccessHandler::notify_variable_access(uint32_
|
||||
return;
|
||||
|
||||
// Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers.
|
||||
auto itr = access_chain_children.find(id);
|
||||
if (itr != end(access_chain_children))
|
||||
auto itr = rvalue_forward_children.find(id);
|
||||
if (itr != end(rvalue_forward_children))
|
||||
for (auto child_id : itr->second)
|
||||
notify_variable_access(child_id, block);
|
||||
|
||||
@@ -3165,7 +3330,20 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
|
||||
// Keep track of the types of temporaries, so we can hoist them out as necessary.
|
||||
uint32_t result_type, result_id;
|
||||
if (compiler.instruction_to_result_type(result_type, result_id, op, args, length))
|
||||
{
|
||||
// For some opcodes, we will need to override the result id.
|
||||
// If we need to hoist the temporary, the temporary type is the input, not the result.
|
||||
// FIXME: This will likely break with OpCopyObject + hoisting, but we'll have to
|
||||
// solve it if we ever get there ...
|
||||
if (op == OpConvertUToAccelerationStructureKHR)
|
||||
{
|
||||
auto itr = result_id_to_type.find(args[2]);
|
||||
if (itr != result_id_to_type.end())
|
||||
result_type = itr->second;
|
||||
}
|
||||
|
||||
result_id_to_type[result_id] = result_type;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
@@ -3207,14 +3385,14 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
|
||||
if (var)
|
||||
{
|
||||
accessed_variables_to_block[var->self].insert(current_block->self);
|
||||
access_chain_children[args[1]].insert(var->self);
|
||||
rvalue_forward_children[args[1]].insert(var->self);
|
||||
}
|
||||
|
||||
// args[2] might be another access chain we have to track use of.
|
||||
for (uint32_t i = 2; i < length; i++)
|
||||
{
|
||||
notify_variable_access(args[i], current_block->self);
|
||||
access_chain_children[args[1]].insert(args[i]);
|
||||
rvalue_forward_children[args[1]].insert(args[i]);
|
||||
}
|
||||
|
||||
// Also keep track of the access chain pointer itself.
|
||||
@@ -3296,6 +3474,12 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
|
||||
|
||||
// Might be an access chain we have to track use of.
|
||||
notify_variable_access(args[2], current_block->self);
|
||||
|
||||
// If we're loading an opaque type we cannot lower it to a temporary,
|
||||
// we must defer access of args[2] until it's used.
|
||||
auto &type = compiler.get<SPIRType>(args[0]);
|
||||
if (compiler.type_is_opaque_value(type))
|
||||
rvalue_forward_children[args[1]].insert(args[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3667,6 +3851,7 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA
|
||||
DominatorBuilder builder(cfg);
|
||||
auto &blocks = var.second;
|
||||
auto &type = expression_type(var.first);
|
||||
BlockID potential_continue_block = 0;
|
||||
|
||||
// Figure out which block is dominating all accesses of those variables.
|
||||
for (auto &block : blocks)
|
||||
@@ -3688,14 +3873,13 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA
|
||||
{
|
||||
// The variable is used in multiple continue blocks, this is not a loop
|
||||
// candidate, signal that by setting block to -1u.
|
||||
auto &potential = potential_loop_variables[var.first];
|
||||
|
||||
if (potential == 0)
|
||||
potential = block;
|
||||
if (potential_continue_block == 0)
|
||||
potential_continue_block = block;
|
||||
else
|
||||
potential = ~(0u);
|
||||
potential_continue_block = ~(0u);
|
||||
}
|
||||
}
|
||||
|
||||
builder.add_block(block);
|
||||
}
|
||||
|
||||
@@ -3704,6 +3888,34 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA
|
||||
// Add it to a per-block list of variables.
|
||||
BlockID dominating_block = builder.get_dominator();
|
||||
|
||||
if (dominating_block && potential_continue_block != 0 && potential_continue_block != ~0u)
|
||||
{
|
||||
auto &inner_block = get<SPIRBlock>(dominating_block);
|
||||
|
||||
BlockID merge_candidate = 0;
|
||||
|
||||
// Analyze the dominator. If it lives in a different loop scope than the candidate continue
|
||||
// block, reject the loop variable candidate.
|
||||
if (inner_block.merge == SPIRBlock::MergeLoop)
|
||||
merge_candidate = inner_block.merge_block;
|
||||
else if (inner_block.loop_dominator != SPIRBlock::NoDominator)
|
||||
merge_candidate = get<SPIRBlock>(inner_block.loop_dominator).merge_block;
|
||||
|
||||
if (merge_candidate != 0 && cfg.is_reachable(merge_candidate))
|
||||
{
|
||||
// If the merge block has a higher post-visit order, we know that continue candidate
|
||||
// cannot reach the merge block, and we have two separate scopes.
|
||||
if (!cfg.is_reachable(potential_continue_block) ||
|
||||
cfg.get_visit_order(merge_candidate) > cfg.get_visit_order(potential_continue_block))
|
||||
{
|
||||
potential_continue_block = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (potential_continue_block != 0 && potential_continue_block != ~0u)
|
||||
potential_loop_variables[var.first] = potential_continue_block;
|
||||
|
||||
// For variables whose dominating block is inside a loop, there is a risk that these variables
|
||||
// actually need to be preserved across loop iterations. We can express this by adding
|
||||
// a "read" access to the loop header.
|
||||
@@ -4303,8 +4515,9 @@ void Compiler::analyze_image_and_sampler_usage()
|
||||
handler.dependency_hierarchy.clear();
|
||||
traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
|
||||
|
||||
comparison_ids = move(handler.comparison_ids);
|
||||
comparison_ids = std::move(handler.comparison_ids);
|
||||
need_subpass_input = handler.need_subpass_input;
|
||||
need_subpass_input_ms = handler.need_subpass_input_ms;
|
||||
|
||||
// Forward information from separate images and samplers into combined image samplers.
|
||||
for (auto &combined : combined_image_samplers)
|
||||
@@ -4356,7 +4569,7 @@ void Compiler::build_function_control_flow_graphs_and_analyze()
|
||||
CFGBuilder handler(*this);
|
||||
handler.function_cfgs[ir.default_entry_point].reset(new CFG(*this, get<SPIRFunction>(ir.default_entry_point)));
|
||||
traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
|
||||
function_cfgs = move(handler.function_cfgs);
|
||||
function_cfgs = std::move(handler.function_cfgs);
|
||||
bool single_function = function_cfgs.size() <= 1;
|
||||
|
||||
for (auto &f : function_cfgs)
|
||||
@@ -4471,7 +4684,11 @@ bool Compiler::CombinedImageSamplerUsageHandler::handle(Op opcode, const uint32_
|
||||
// If we load an image, we're going to use it and there is little harm in declaring an unused gl_FragCoord.
|
||||
auto &type = compiler.get<SPIRType>(args[0]);
|
||||
if (type.image.dim == DimSubpassData)
|
||||
{
|
||||
need_subpass_input = true;
|
||||
if (type.image.ms)
|
||||
need_subpass_input_ms = true;
|
||||
}
|
||||
|
||||
// If we load a SampledImage and it will be used with Dref, propagate the state up.
|
||||
if (dref_combined_samplers.count(args[1]) != 0)
|
||||
@@ -4646,46 +4863,22 @@ bool Compiler::reflection_ssbo_instance_name_is_significant() const
|
||||
return aliased_ssbo_types;
|
||||
}
|
||||
|
||||
bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op, const uint32_t *args,
|
||||
uint32_t length)
|
||||
bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op,
|
||||
const uint32_t *args, uint32_t length)
|
||||
{
|
||||
// Most instructions follow the pattern of <result-type> <result-id> <arguments>.
|
||||
// There are some exceptions.
|
||||
switch (op)
|
||||
{
|
||||
case OpStore:
|
||||
case OpCopyMemory:
|
||||
case OpCopyMemorySized:
|
||||
case OpImageWrite:
|
||||
case OpAtomicStore:
|
||||
case OpAtomicFlagClear:
|
||||
case OpEmitStreamVertex:
|
||||
case OpEndStreamPrimitive:
|
||||
case OpControlBarrier:
|
||||
case OpMemoryBarrier:
|
||||
case OpGroupWaitEvents:
|
||||
case OpRetainEvent:
|
||||
case OpReleaseEvent:
|
||||
case OpSetUserEventStatus:
|
||||
case OpCaptureEventProfilingInfo:
|
||||
case OpCommitReadPipe:
|
||||
case OpCommitWritePipe:
|
||||
case OpGroupCommitReadPipe:
|
||||
case OpGroupCommitWritePipe:
|
||||
case OpLine:
|
||||
case OpNoLine:
|
||||
if (length < 2)
|
||||
return false;
|
||||
|
||||
default:
|
||||
if (length > 1 && maybe_get<SPIRType>(args[0]) != nullptr)
|
||||
{
|
||||
result_type = args[0];
|
||||
result_id = args[1];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
bool has_result_id = false, has_result_type = false;
|
||||
HasResultAndType(op, &has_result_id, &has_result_type);
|
||||
if (has_result_id && has_result_type)
|
||||
{
|
||||
result_type = args[0];
|
||||
result_id = args[1];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
Bitset Compiler::combined_decoration_for_member(const SPIRType &type, uint32_t index) const
|
||||
@@ -4769,6 +4962,12 @@ void Compiler::force_recompile()
|
||||
is_force_recompile = true;
|
||||
}
|
||||
|
||||
void Compiler::force_recompile_guarantee_forward_progress()
|
||||
{
|
||||
force_recompile();
|
||||
is_force_recompile_forward_progress = true;
|
||||
}
|
||||
|
||||
bool Compiler::is_forcing_recompilation() const
|
||||
{
|
||||
return is_force_recompile;
|
||||
@@ -4777,6 +4976,7 @@ bool Compiler::is_forcing_recompilation() const
|
||||
void Compiler::clear_force_recompile()
|
||||
{
|
||||
is_force_recompile = false;
|
||||
is_force_recompile_forward_progress = false;
|
||||
}
|
||||
|
||||
Compiler::PhysicalStorageBufferPointerHandler::PhysicalStorageBufferPointerHandler(Compiler &compiler_)
|
||||
@@ -4958,7 +5158,7 @@ void Compiler::analyze_non_block_pointer_types()
|
||||
for (auto type : handler.non_block_types)
|
||||
physical_storage_non_block_pointer_types.push_back(type);
|
||||
sort(begin(physical_storage_non_block_pointer_types), end(physical_storage_non_block_pointer_types));
|
||||
physical_storage_type_to_alignment = move(handler.physical_block_type_meta);
|
||||
physical_storage_type_to_alignment = std::move(handler.physical_block_type_meta);
|
||||
}
|
||||
|
||||
bool Compiler::InterlockedResourceAccessPrepassHandler::handle(Op op, const uint32_t *, uint32_t)
|
||||
@@ -5271,19 +5471,51 @@ void Compiler::analyze_interlocked_resource_usage()
|
||||
}
|
||||
}
|
||||
|
||||
bool Compiler::type_is_array_of_pointers(const SPIRType &type) const
|
||||
// Helper function
|
||||
bool Compiler::check_internal_recursion(const SPIRType &type, std::unordered_set<uint32_t> &checked_ids)
|
||||
{
|
||||
if (!type.pointer)
|
||||
if (type.basetype != SPIRType::Struct)
|
||||
return false;
|
||||
|
||||
// If parent type has same pointer depth, we must have an array of pointers.
|
||||
return type.pointer_depth == get<SPIRType>(type.parent_type).pointer_depth;
|
||||
if (checked_ids.count(type.self))
|
||||
return true;
|
||||
|
||||
// Recurse into struct members
|
||||
bool is_recursive = false;
|
||||
checked_ids.insert(type.self);
|
||||
uint32_t mbr_cnt = uint32_t(type.member_types.size());
|
||||
for (uint32_t mbr_idx = 0; !is_recursive && mbr_idx < mbr_cnt; mbr_idx++)
|
||||
{
|
||||
uint32_t mbr_type_id = type.member_types[mbr_idx];
|
||||
auto &mbr_type = get<SPIRType>(mbr_type_id);
|
||||
is_recursive |= check_internal_recursion(mbr_type, checked_ids);
|
||||
}
|
||||
checked_ids.erase(type.self);
|
||||
return is_recursive;
|
||||
}
|
||||
|
||||
bool Compiler::type_is_top_level_physical_pointer(const SPIRType &type) const
|
||||
// Return whether the struct type contains a structural recursion nested somewhere within its content.
|
||||
bool Compiler::type_contains_recursion(const SPIRType &type)
|
||||
{
|
||||
return type.pointer && type.storage == StorageClassPhysicalStorageBuffer &&
|
||||
type.pointer_depth > get<SPIRType>(type.parent_type).pointer_depth;
|
||||
std::unordered_set<uint32_t> checked_ids;
|
||||
return check_internal_recursion(type, checked_ids);
|
||||
}
|
||||
|
||||
bool Compiler::type_is_array_of_pointers(const SPIRType &type) const
|
||||
{
|
||||
if (!is_array(type))
|
||||
return false;
|
||||
|
||||
// BDA types must have parent type hierarchy.
|
||||
if (!type.parent_type)
|
||||
return false;
|
||||
|
||||
// Punch through all array layers.
|
||||
auto *parent = &get<SPIRType>(type.parent_type);
|
||||
while (is_array(*parent))
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
|
||||
return is_pointer(*parent);
|
||||
}
|
||||
|
||||
bool Compiler::flush_phi_required(BlockID from, BlockID to) const
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#ifndef SPIRV_CROSS_HPP
|
||||
#define SPIRV_CROSS_HPP
|
||||
|
||||
#ifndef SPV_ENABLE_UTILITY_CODE
|
||||
#define SPV_ENABLE_UTILITY_CODE
|
||||
#endif
|
||||
#include "spirv.hpp"
|
||||
#include "spirv_cfg.hpp"
|
||||
#include "spirv_cross_parsed_ir.hpp"
|
||||
@@ -91,11 +94,14 @@ struct ShaderResources
|
||||
SmallVector<Resource> sampled_images;
|
||||
SmallVector<Resource> atomic_counters;
|
||||
SmallVector<Resource> acceleration_structures;
|
||||
SmallVector<Resource> gl_plain_uniforms;
|
||||
|
||||
// There can only be one push constant block,
|
||||
// but keep the vector in case this restriction is lifted in the future.
|
||||
SmallVector<Resource> push_constant_buffers;
|
||||
|
||||
SmallVector<Resource> shader_record_buffers;
|
||||
|
||||
// For Vulkan GLSL and HLSL source,
|
||||
// these correspond to separate texture2D and samplers respectively.
|
||||
SmallVector<Resource> separate_images;
|
||||
@@ -357,12 +363,16 @@ public:
|
||||
void set_execution_mode(spv::ExecutionMode mode, uint32_t arg0 = 0, uint32_t arg1 = 0, uint32_t arg2 = 0);
|
||||
|
||||
// Gets argument for an execution mode (LocalSize, Invocations, OutputVertices).
|
||||
// For LocalSize, the index argument is used to select the dimension (X = 0, Y = 1, Z = 2).
|
||||
// For LocalSize or LocalSizeId, the index argument is used to select the dimension (X = 0, Y = 1, Z = 2).
|
||||
// For execution modes which do not have arguments, 0 is returned.
|
||||
// LocalSizeId query returns an ID. If LocalSizeId execution mode is not used, it returns 0.
|
||||
// LocalSize always returns a literal. If execution mode is LocalSizeId,
|
||||
// the literal (spec constant or not) is still returned.
|
||||
uint32_t get_execution_mode_argument(spv::ExecutionMode mode, uint32_t index = 0) const;
|
||||
spv::ExecutionModel get_execution_model() const;
|
||||
|
||||
bool is_tessellation_shader() const;
|
||||
bool is_tessellating_triangles() const;
|
||||
|
||||
// In SPIR-V, the compute work group size can be represented by a constant vector, in which case
|
||||
// the LocalSize execution mode is ignored.
|
||||
@@ -380,6 +390,8 @@ public:
|
||||
// If the component is not a specialization constant, a zeroed out struct will be written.
|
||||
// The return value is the constant ID of the builtin WorkGroupSize, but this is not expected to be useful
|
||||
// for most use cases.
|
||||
// If LocalSizeId is used, there is no uvec3 value representing the workgroup size, so the return value is 0,
|
||||
// but x, y and z are written as normal if the components are specialization constants.
|
||||
uint32_t get_work_group_size_specialization_constants(SpecializationConstant &x, SpecializationConstant &y,
|
||||
SpecializationConstant &z) const;
|
||||
|
||||
@@ -551,6 +563,11 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t *stream_mutable(const Instruction &instr) const
|
||||
{
|
||||
return const_cast<uint32_t *>(stream(instr));
|
||||
}
|
||||
|
||||
ParsedIR ir;
|
||||
// Marks variables which have global scope and variables which can alias with other variables
|
||||
// (SSBO, image load store, etc)
|
||||
@@ -666,6 +683,9 @@ protected:
|
||||
bool is_vector(const SPIRType &type) const;
|
||||
bool is_matrix(const SPIRType &type) const;
|
||||
bool is_array(const SPIRType &type) const;
|
||||
bool is_pointer(const SPIRType &type) const;
|
||||
bool is_physical_pointer(const SPIRType &type) const;
|
||||
static bool is_runtime_size_array(const SPIRType &type);
|
||||
uint32_t expression_type_id(uint32_t id) const;
|
||||
const SPIRType &expression_type(uint32_t id) const;
|
||||
bool expression_is_lvalue(uint32_t id) const;
|
||||
@@ -730,16 +750,20 @@ protected:
|
||||
SPIRBlock::ContinueBlockType continue_block_type(const SPIRBlock &continue_block) const;
|
||||
|
||||
void force_recompile();
|
||||
void force_recompile_guarantee_forward_progress();
|
||||
void clear_force_recompile();
|
||||
bool is_forcing_recompilation() const;
|
||||
bool is_force_recompile = false;
|
||||
bool is_force_recompile_forward_progress = false;
|
||||
|
||||
bool block_is_noop(const SPIRBlock &block) const;
|
||||
bool block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method method) const;
|
||||
|
||||
bool types_are_logically_equivalent(const SPIRType &a, const SPIRType &b) const;
|
||||
void inherit_expression_dependencies(uint32_t dst, uint32_t source);
|
||||
void add_implied_read_expression(SPIRExpression &e, uint32_t source);
|
||||
void add_implied_read_expression(SPIRAccessChain &e, uint32_t source);
|
||||
void add_active_interface_variable(uint32_t var_id);
|
||||
|
||||
// For proper multiple entry point support, allow querying if an Input or Output
|
||||
// variable is part of that entry points interface.
|
||||
@@ -915,6 +939,7 @@ protected:
|
||||
// Similar is implemented for images, as well as if subpass inputs are needed.
|
||||
std::unordered_set<uint32_t> comparison_ids;
|
||||
bool need_subpass_input = false;
|
||||
bool need_subpass_input_ms = false;
|
||||
|
||||
// In certain backends, we will need to use a dummy sampler to be able to emit code.
|
||||
// GLSL does not support texelFetch on texture2D objects, but SPIR-V does,
|
||||
@@ -954,6 +979,7 @@ protected:
|
||||
|
||||
void add_hierarchy_to_comparison_ids(uint32_t ids);
|
||||
bool need_subpass_input = false;
|
||||
bool need_subpass_input_ms = false;
|
||||
void add_dependency(uint32_t dst, uint32_t src);
|
||||
};
|
||||
|
||||
@@ -994,7 +1020,8 @@ protected:
|
||||
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> partial_write_variables_to_block;
|
||||
std::unordered_set<uint32_t> access_chain_expressions;
|
||||
// Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers.
|
||||
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> access_chain_children;
|
||||
// This is also relevant when forwarding opaque objects since we cannot lower these to temporaries.
|
||||
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> rvalue_forward_children;
|
||||
const SPIRBlock *current_block = nullptr;
|
||||
};
|
||||
|
||||
@@ -1120,9 +1147,11 @@ protected:
|
||||
bool has_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration) const;
|
||||
void unset_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration);
|
||||
|
||||
bool check_internal_recursion(const SPIRType &type, std::unordered_set<uint32_t> &checked_ids);
|
||||
bool type_contains_recursion(const SPIRType &type);
|
||||
bool type_is_array_of_pointers(const SPIRType &type) const;
|
||||
bool type_is_top_level_physical_pointer(const SPIRType &type) const;
|
||||
bool type_is_block_like(const SPIRType &type) const;
|
||||
bool type_is_top_level_block(const SPIRType &type) const;
|
||||
bool type_is_opaque_value(const SPIRType &type) const;
|
||||
|
||||
bool reflection_ssbo_instance_name_is_significant() const;
|
||||
|
||||
@@ -194,6 +194,7 @@ struct spvc_resources_s : ScratchMemoryAllocation
|
||||
SmallVector<spvc_reflected_resource> sampled_images;
|
||||
SmallVector<spvc_reflected_resource> atomic_counters;
|
||||
SmallVector<spvc_reflected_resource> push_constant_buffers;
|
||||
SmallVector<spvc_reflected_resource> shader_record_buffers;
|
||||
SmallVector<spvc_reflected_resource> separate_images;
|
||||
SmallVector<spvc_reflected_resource> separate_samplers;
|
||||
SmallVector<spvc_reflected_resource> acceleration_structures;
|
||||
@@ -251,7 +252,7 @@ spvc_result spvc_context_parse_spirv(spvc_context context, const SpvId *spirv, s
|
||||
pir->context = context;
|
||||
Parser parser(spirv, word_count);
|
||||
parser.parse();
|
||||
pir->parsed = move(parser.get_parsed_ir());
|
||||
pir->parsed = std::move(parser.get_parsed_ir());
|
||||
*parsed_ir = pir.get();
|
||||
context->allocations.push_back(std::move(pir));
|
||||
}
|
||||
@@ -283,7 +284,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back
|
||||
{
|
||||
case SPVC_BACKEND_NONE:
|
||||
if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
|
||||
comp->compiler.reset(new Compiler(move(parsed_ir->parsed)));
|
||||
comp->compiler.reset(new Compiler(std::move(parsed_ir->parsed)));
|
||||
else if (mode == SPVC_CAPTURE_MODE_COPY)
|
||||
comp->compiler.reset(new Compiler(parsed_ir->parsed));
|
||||
break;
|
||||
@@ -291,7 +292,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back
|
||||
#if SPIRV_CROSS_C_API_GLSL
|
||||
case SPVC_BACKEND_GLSL:
|
||||
if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
|
||||
comp->compiler.reset(new CompilerGLSL(move(parsed_ir->parsed)));
|
||||
comp->compiler.reset(new CompilerGLSL(std::move(parsed_ir->parsed)));
|
||||
else if (mode == SPVC_CAPTURE_MODE_COPY)
|
||||
comp->compiler.reset(new CompilerGLSL(parsed_ir->parsed));
|
||||
break;
|
||||
@@ -300,7 +301,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back
|
||||
#if SPIRV_CROSS_C_API_HLSL
|
||||
case SPVC_BACKEND_HLSL:
|
||||
if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
|
||||
comp->compiler.reset(new CompilerHLSL(move(parsed_ir->parsed)));
|
||||
comp->compiler.reset(new CompilerHLSL(std::move(parsed_ir->parsed)));
|
||||
else if (mode == SPVC_CAPTURE_MODE_COPY)
|
||||
comp->compiler.reset(new CompilerHLSL(parsed_ir->parsed));
|
||||
break;
|
||||
@@ -309,7 +310,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
case SPVC_BACKEND_MSL:
|
||||
if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
|
||||
comp->compiler.reset(new CompilerMSL(move(parsed_ir->parsed)));
|
||||
comp->compiler.reset(new CompilerMSL(std::move(parsed_ir->parsed)));
|
||||
else if (mode == SPVC_CAPTURE_MODE_COPY)
|
||||
comp->compiler.reset(new CompilerMSL(parsed_ir->parsed));
|
||||
break;
|
||||
@@ -318,7 +319,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back
|
||||
#if SPIRV_CROSS_C_API_CPP
|
||||
case SPVC_BACKEND_CPP:
|
||||
if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
|
||||
comp->compiler.reset(new CompilerCPP(move(parsed_ir->parsed)));
|
||||
comp->compiler.reset(new CompilerCPP(std::move(parsed_ir->parsed)));
|
||||
else if (mode == SPVC_CAPTURE_MODE_COPY)
|
||||
comp->compiler.reset(new CompilerCPP(parsed_ir->parsed));
|
||||
break;
|
||||
@@ -327,7 +328,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back
|
||||
#if SPIRV_CROSS_C_API_REFLECT
|
||||
case SPVC_BACKEND_JSON:
|
||||
if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP)
|
||||
comp->compiler.reset(new CompilerReflection(move(parsed_ir->parsed)));
|
||||
comp->compiler.reset(new CompilerReflection(std::move(parsed_ir->parsed)));
|
||||
else if (mode == SPVC_CAPTURE_MODE_COPY)
|
||||
comp->compiler.reset(new CompilerReflection(parsed_ir->parsed));
|
||||
break;
|
||||
@@ -475,6 +476,12 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
case SPVC_COMPILER_OPTION_GLSL_OVR_MULTIVIEW_VIEW_COUNT:
|
||||
options->glsl.ovr_multiview_view_count = value;
|
||||
break;
|
||||
case SPVC_COMPILER_OPTION_RELAX_NAN_CHECKS:
|
||||
options->glsl.relax_nan_checks = value != 0;
|
||||
break;
|
||||
case SPVC_COMPILER_OPTION_GLSL_ENABLE_ROW_MAJOR_LOAD_WORKAROUND:
|
||||
options->glsl.enable_row_major_load_workaround = value != 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if SPIRV_CROSS_C_API_HLSL
|
||||
@@ -711,6 +718,42 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
case SPVC_COMPILER_OPTION_MSL_IOS_SUPPORT_BASE_VERTEX_INSTANCE:
|
||||
options->msl.ios_support_base_vertex_instance = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_RAW_BUFFER_TESE_INPUT:
|
||||
options->msl.raw_buffer_tese_input = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_INPUT_BUFFER_INDEX:
|
||||
options->msl.shader_patch_input_buffer_index = value;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_MANUAL_HELPER_INVOCATION_UPDATES:
|
||||
options->msl.manual_helper_invocation_updates = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_CHECK_DISCARDED_FRAG_STORES:
|
||||
options->msl.check_discarded_frag_stores = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER:
|
||||
options->msl.argument_buffers_tier = static_cast<CompilerMSL::Options::ArgumentBuffersTier>(value);
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_SAMPLE_DREF_LOD_ARRAY_AS_GRAD:
|
||||
options->msl.sample_dref_lod_array_as_grad = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_READWRITE_TEXTURE_FENCES:
|
||||
options->msl.readwrite_texture_fences = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_REPLACE_RECURSIVE_INPUTS:
|
||||
options->msl.replace_recursive_inputs = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_AGX_MANUAL_CUBE_GRAD_FIXUP:
|
||||
options->msl.agx_manual_cube_grad_fixup = value != 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
@@ -789,6 +832,43 @@ spvc_result spvc_compiler_require_extension(spvc_compiler compiler, const char *
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t spvc_compiler_get_num_required_extensions(spvc_compiler compiler)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_GLSL
|
||||
if (compiler->backend != SPVC_BACKEND_GLSL)
|
||||
{
|
||||
compiler->context->report_error("Enabled extensions can only be queried on GLSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return static_cast<CompilerGLSL *>(compiler->compiler.get())->get_required_extensions().size();
|
||||
#else
|
||||
compiler->context->report_error("Enabled extensions can only be queried on GLSL backend.");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *spvc_compiler_get_required_extension(spvc_compiler compiler, size_t index)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_GLSL
|
||||
if (compiler->backend != SPVC_BACKEND_GLSL)
|
||||
{
|
||||
compiler->context->report_error("Enabled extensions can only be queried on GLSL backend.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto &exts = static_cast<CompilerGLSL *>(compiler->compiler.get())->get_required_extensions();
|
||||
if (index < exts.size())
|
||||
return exts[index].c_str();
|
||||
else
|
||||
return nullptr;
|
||||
#else
|
||||
(void)index;
|
||||
compiler->context->report_error("Enabled extensions can only be queried on GLSL backend.");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_variable_id id)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_GLSL
|
||||
@@ -1133,9 +1213,9 @@ spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler, const
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLShaderInput attr;
|
||||
MSLShaderInterfaceVariable attr;
|
||||
attr.location = va->location;
|
||||
attr.format = static_cast<MSLShaderInputFormat>(va->format);
|
||||
attr.format = static_cast<MSLShaderVariableFormat>(va->format);
|
||||
attr.builtin = static_cast<spv::BuiltIn>(va->builtin);
|
||||
msl.add_msl_shader_input(attr);
|
||||
return SPVC_SUCCESS;
|
||||
@@ -1146,7 +1226,7 @@ spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler, const
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spvc_msl_shader_input *si)
|
||||
spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spvc_msl_shader_interface_var *si)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
@@ -1156,9 +1236,9 @@ spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spv
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLShaderInput input;
|
||||
MSLShaderInterfaceVariable input;
|
||||
input.location = si->location;
|
||||
input.format = static_cast<MSLShaderInputFormat>(si->format);
|
||||
input.format = static_cast<MSLShaderVariableFormat>(si->format);
|
||||
input.builtin = static_cast<spv::BuiltIn>(si->builtin);
|
||||
input.vecsize = si->vecsize;
|
||||
msl.add_msl_shader_input(input);
|
||||
@@ -1170,6 +1250,80 @@ spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spv
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_add_shader_input_2(spvc_compiler compiler, const spvc_msl_shader_interface_var_2 *si)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
{
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLShaderInterfaceVariable input;
|
||||
input.location = si->location;
|
||||
input.format = static_cast<MSLShaderVariableFormat>(si->format);
|
||||
input.builtin = static_cast<spv::BuiltIn>(si->builtin);
|
||||
input.vecsize = si->vecsize;
|
||||
input.rate = static_cast<MSLShaderVariableRate>(si->rate);
|
||||
msl.add_msl_shader_input(input);
|
||||
return SPVC_SUCCESS;
|
||||
#else
|
||||
(void)si;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_add_shader_output(spvc_compiler compiler, const spvc_msl_shader_interface_var *so)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
{
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLShaderInterfaceVariable output;
|
||||
output.location = so->location;
|
||||
output.format = static_cast<MSLShaderVariableFormat>(so->format);
|
||||
output.builtin = static_cast<spv::BuiltIn>(so->builtin);
|
||||
output.vecsize = so->vecsize;
|
||||
msl.add_msl_shader_output(output);
|
||||
return SPVC_SUCCESS;
|
||||
#else
|
||||
(void)so;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_add_shader_output_2(spvc_compiler compiler, const spvc_msl_shader_interface_var_2 *so)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
{
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLShaderInterfaceVariable output;
|
||||
output.location = so->location;
|
||||
output.format = static_cast<MSLShaderVariableFormat>(so->format);
|
||||
output.builtin = static_cast<spv::BuiltIn>(so->builtin);
|
||||
output.vecsize = so->vecsize;
|
||||
output.rate = static_cast<MSLShaderVariableRate>(so->rate);
|
||||
msl.add_msl_shader_output(output);
|
||||
return SPVC_SUCCESS;
|
||||
#else
|
||||
(void)so;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler,
|
||||
const spvc_msl_resource_binding *binding)
|
||||
{
|
||||
@@ -1295,6 +1449,24 @@ spvc_bool spvc_compiler_msl_is_shader_input_used(spvc_compiler compiler, unsigne
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_bool spvc_compiler_msl_is_shader_output_used(spvc_compiler compiler, unsigned location)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
{
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_FALSE;
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
return msl.is_msl_shader_output_used(location) ? SPVC_TRUE : SPVC_FALSE;
|
||||
#else
|
||||
(void)location;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, unsigned location)
|
||||
{
|
||||
return spvc_compiler_msl_is_shader_input_used(compiler, location);
|
||||
@@ -1639,6 +1811,8 @@ bool spvc_resources_s::copy_resources(const ShaderResources &resources)
|
||||
return false;
|
||||
if (!copy_resources(push_constant_buffers, resources.push_constant_buffers))
|
||||
return false;
|
||||
if (!copy_resources(shader_record_buffers, resources.shader_record_buffers))
|
||||
return false;
|
||||
if (!copy_resources(separate_images, resources.separate_images))
|
||||
return false;
|
||||
if (!copy_resources(separate_samplers, resources.separate_samplers))
|
||||
@@ -1792,6 +1966,10 @@ spvc_result spvc_resources_get_resource_list_for_type(spvc_resources resources,
|
||||
list = &resources->acceleration_structures;
|
||||
break;
|
||||
|
||||
case SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER:
|
||||
list = &resources->shader_record_buffers;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2406,6 +2584,51 @@ spvc_type_id spvc_constant_get_type(spvc_constant constant)
|
||||
return constant->constant_type;
|
||||
}
|
||||
|
||||
void spvc_constant_set_scalar_fp16(spvc_constant constant, unsigned column, unsigned row, unsigned short value)
|
||||
{
|
||||
constant->m.c[column].r[row].u32 = value;
|
||||
}
|
||||
|
||||
void spvc_constant_set_scalar_fp32(spvc_constant constant, unsigned column, unsigned row, float value)
|
||||
{
|
||||
constant->m.c[column].r[row].f32 = value;
|
||||
}
|
||||
|
||||
void spvc_constant_set_scalar_fp64(spvc_constant constant, unsigned column, unsigned row, double value)
|
||||
{
|
||||
constant->m.c[column].r[row].f64 = value;
|
||||
}
|
||||
|
||||
void spvc_constant_set_scalar_u32(spvc_constant constant, unsigned column, unsigned row, unsigned value)
|
||||
{
|
||||
constant->m.c[column].r[row].u32 = value;
|
||||
}
|
||||
|
||||
void spvc_constant_set_scalar_i32(spvc_constant constant, unsigned column, unsigned row, int value)
|
||||
{
|
||||
constant->m.c[column].r[row].i32 = value;
|
||||
}
|
||||
|
||||
void spvc_constant_set_scalar_u16(spvc_constant constant, unsigned column, unsigned row, unsigned short value)
|
||||
{
|
||||
constant->m.c[column].r[row].u32 = uint32_t(value);
|
||||
}
|
||||
|
||||
void spvc_constant_set_scalar_i16(spvc_constant constant, unsigned column, unsigned row, signed short value)
|
||||
{
|
||||
constant->m.c[column].r[row].u32 = uint32_t(value);
|
||||
}
|
||||
|
||||
void spvc_constant_set_scalar_u8(spvc_constant constant, unsigned column, unsigned row, unsigned char value)
|
||||
{
|
||||
constant->m.c[column].r[row].u32 = uint32_t(value);
|
||||
}
|
||||
|
||||
void spvc_constant_set_scalar_i8(spvc_constant constant, unsigned column, unsigned row, signed char value)
|
||||
{
|
||||
constant->m.c[column].r[row].u32 = uint32_t(value);
|
||||
}
|
||||
|
||||
spvc_bool spvc_compiler_get_binary_offset_for_decoration(spvc_compiler compiler, spvc_variable_id id,
|
||||
SpvDecoration decoration,
|
||||
unsigned *word_offset)
|
||||
@@ -2508,7 +2731,7 @@ void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
// Crude, but works.
|
||||
MSLShaderInput attr_default;
|
||||
MSLShaderInterfaceVariable attr_default;
|
||||
attr->location = attr_default.location;
|
||||
attr->format = static_cast<spvc_msl_vertex_format>(attr_default.format);
|
||||
attr->builtin = static_cast<SpvBuiltIn>(attr_default.builtin);
|
||||
@@ -2517,16 +2740,35 @@ void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr)
|
||||
#endif
|
||||
}
|
||||
|
||||
void spvc_msl_shader_input_init(spvc_msl_shader_input *input)
|
||||
void spvc_msl_shader_interface_var_init(spvc_msl_shader_interface_var *var)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
MSLShaderInput input_default;
|
||||
input->location = input_default.location;
|
||||
input->format = static_cast<spvc_msl_shader_input_format>(input_default.format);
|
||||
input->builtin = static_cast<SpvBuiltIn>(input_default.builtin);
|
||||
input->vecsize = input_default.vecsize;
|
||||
MSLShaderInterfaceVariable var_default;
|
||||
var->location = var_default.location;
|
||||
var->format = static_cast<spvc_msl_shader_variable_format>(var_default.format);
|
||||
var->builtin = static_cast<SpvBuiltIn>(var_default.builtin);
|
||||
var->vecsize = var_default.vecsize;
|
||||
#else
|
||||
memset(input, 0, sizeof(*input));
|
||||
memset(var, 0, sizeof(*var));
|
||||
#endif
|
||||
}
|
||||
|
||||
void spvc_msl_shader_input_init(spvc_msl_shader_input *input)
|
||||
{
|
||||
spvc_msl_shader_interface_var_init(input);
|
||||
}
|
||||
|
||||
void spvc_msl_shader_interface_var_init_2(spvc_msl_shader_interface_var_2 *var)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
MSLShaderInterfaceVariable var_default;
|
||||
var->location = var_default.location;
|
||||
var->format = static_cast<spvc_msl_shader_variable_format>(var_default.format);
|
||||
var->builtin = static_cast<SpvBuiltIn>(var_default.builtin);
|
||||
var->vecsize = var_default.vecsize;
|
||||
var->rate = static_cast<spvc_msl_shader_variable_rate>(var_default.rate);
|
||||
#else
|
||||
memset(var, 0, sizeof(*var));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ extern "C" {
|
||||
/* Bumped if ABI or API breaks backwards compatibility. */
|
||||
#define SPVC_C_API_VERSION_MAJOR 0
|
||||
/* Bumped if APIs or enumerations are added in a backwards compatible way. */
|
||||
#define SPVC_C_API_VERSION_MINOR 48
|
||||
#define SPVC_C_API_VERSION_MINOR 58
|
||||
/* Bumped if internal implementation details change. */
|
||||
#define SPVC_C_API_VERSION_PATCH 0
|
||||
|
||||
@@ -225,6 +225,7 @@ typedef enum spvc_resource_type
|
||||
SPVC_RESOURCE_TYPE_SEPARATE_SAMPLERS = 11,
|
||||
SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE = 12,
|
||||
SPVC_RESOURCE_TYPE_RAY_QUERY = 13,
|
||||
SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER = 14,
|
||||
SPVC_RESOURCE_TYPE_INT_MAX = 0x7fffffff
|
||||
} spvc_resource_type;
|
||||
|
||||
@@ -290,23 +291,29 @@ typedef enum spvc_msl_index_type
|
||||
} spvc_msl_index_type;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_shader_input_format
|
||||
typedef enum spvc_msl_shader_variable_format
|
||||
{
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_OTHER = 0,
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_UINT8 = 1,
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_UINT16 = 2,
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_ANY16 = 3,
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_ANY32 = 4,
|
||||
SPVC_MSL_SHADER_VARIABLE_FORMAT_OTHER = 0,
|
||||
SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT8 = 1,
|
||||
SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT16 = 2,
|
||||
SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY16 = 3,
|
||||
SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY32 = 4,
|
||||
|
||||
/* Deprecated names. */
|
||||
SPVC_MSL_VERTEX_FORMAT_OTHER = SPVC_MSL_SHADER_INPUT_FORMAT_OTHER,
|
||||
SPVC_MSL_VERTEX_FORMAT_UINT8 = SPVC_MSL_SHADER_INPUT_FORMAT_UINT8,
|
||||
SPVC_MSL_VERTEX_FORMAT_UINT16 = SPVC_MSL_SHADER_INPUT_FORMAT_UINT16,
|
||||
SPVC_MSL_VERTEX_FORMAT_OTHER = SPVC_MSL_SHADER_VARIABLE_FORMAT_OTHER,
|
||||
SPVC_MSL_VERTEX_FORMAT_UINT8 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT8,
|
||||
SPVC_MSL_VERTEX_FORMAT_UINT16 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT16,
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_OTHER = SPVC_MSL_SHADER_VARIABLE_FORMAT_OTHER,
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_UINT8 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT8,
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_UINT16 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT16,
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_ANY16 = SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY16,
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_ANY32 = SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY32,
|
||||
|
||||
|
||||
SPVC_MSL_SHADER_INPUT_FORMAT_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_shader_input_format, spvc_msl_vertex_format;
|
||||
} spvc_msl_shader_variable_format, spvc_msl_shader_input_format, spvc_msl_vertex_format;
|
||||
|
||||
/* Maps to C++ API. Deprecated; use spvc_msl_shader_input. */
|
||||
/* Maps to C++ API. Deprecated; use spvc_msl_shader_interface_var. */
|
||||
typedef struct spvc_msl_vertex_attribute
|
||||
{
|
||||
unsigned location;
|
||||
@@ -329,20 +336,50 @@ typedef struct spvc_msl_vertex_attribute
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_shader_input
|
||||
/* Maps to C++ API. Deprecated; use spvc_msl_shader_interface_var_2. */
|
||||
typedef struct spvc_msl_shader_interface_var
|
||||
{
|
||||
unsigned location;
|
||||
spvc_msl_vertex_format format;
|
||||
SpvBuiltIn builtin;
|
||||
unsigned vecsize;
|
||||
} spvc_msl_shader_input;
|
||||
} spvc_msl_shader_interface_var, spvc_msl_shader_input;
|
||||
|
||||
/*
|
||||
* Initializes the shader input struct.
|
||||
* Deprecated. Use spvc_msl_shader_interface_var_init_2().
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_shader_interface_var_init(spvc_msl_shader_interface_var *var);
|
||||
/*
|
||||
* Deprecated. Use spvc_msl_shader_interface_var_init_2().
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_shader_input_init(spvc_msl_shader_input *input);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_shader_variable_rate
|
||||
{
|
||||
SPVC_MSL_SHADER_VARIABLE_RATE_PER_VERTEX = 0,
|
||||
SPVC_MSL_SHADER_VARIABLE_RATE_PER_PRIMITIVE = 1,
|
||||
SPVC_MSL_SHADER_VARIABLE_RATE_PER_PATCH = 2,
|
||||
|
||||
SPVC_MSL_SHADER_VARIABLE_RATE_INT_MAX = 0x7fffffff,
|
||||
} spvc_msl_shader_variable_rate;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_shader_interface_var_2
|
||||
{
|
||||
unsigned location;
|
||||
spvc_msl_shader_variable_format format;
|
||||
SpvBuiltIn builtin;
|
||||
unsigned vecsize;
|
||||
spvc_msl_shader_variable_rate rate;
|
||||
} spvc_msl_shader_interface_var_2;
|
||||
|
||||
/*
|
||||
* Initializes the shader interface variable struct.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_shader_interface_var_init_2(spvc_msl_shader_interface_var_2 *var);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_resource_binding
|
||||
{
|
||||
@@ -677,6 +714,21 @@ typedef enum spvc_compiler_option
|
||||
|
||||
SPVC_COMPILER_OPTION_GLSL_OVR_MULTIVIEW_VIEW_COUNT = 77 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_RELAX_NAN_CHECKS = 78 | SPVC_COMPILER_OPTION_COMMON_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_RAW_BUFFER_TESE_INPUT = 79 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_INPUT_BUFFER_INDEX = 80 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_MANUAL_HELPER_INVOCATION_UPDATES = 81 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_CHECK_DISCARDED_FRAG_STORES = 82 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_GLSL_ENABLE_ROW_MAJOR_LOAD_WORKAROUND = 83 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER = 84 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SAMPLE_DREF_LOD_ARRAY_AS_GRAD = 85 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_READWRITE_TEXTURE_FENCES = 86 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_REPLACE_RECURSIVE_INPUTS = 87 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_AGX_MANUAL_CUBE_GRAD_FIXUP = 88 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
|
||||
} spvc_compiler_option;
|
||||
|
||||
@@ -735,6 +787,8 @@ SPVC_PUBLIC_API spvc_result spvc_compiler_compile(spvc_compiler compiler, const
|
||||
/* Maps to C++ API. */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_add_header_line(spvc_compiler compiler, const char *line);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_require_extension(spvc_compiler compiler, const char *ext);
|
||||
SPVC_PUBLIC_API size_t spvc_compiler_get_num_required_extensions(spvc_compiler compiler);
|
||||
SPVC_PUBLIC_API const char *spvc_compiler_get_required_extension(spvc_compiler compiler, size_t index);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_variable_id id);
|
||||
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_variable_is_depth_or_compare(spvc_compiler compiler, spvc_variable_id id);
|
||||
@@ -783,14 +837,23 @@ SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler
|
||||
const spvc_msl_vertex_attribute *attrs);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler,
|
||||
const spvc_msl_resource_binding *binding);
|
||||
/* Deprecated; use spvc_compiler_msl_add_shader_input_2(). */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler,
|
||||
const spvc_msl_shader_input *input);
|
||||
const spvc_msl_shader_interface_var *input);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_input_2(spvc_compiler compiler,
|
||||
const spvc_msl_shader_interface_var_2 *input);
|
||||
/* Deprecated; use spvc_compiler_msl_add_shader_output_2(). */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_output(spvc_compiler compiler,
|
||||
const spvc_msl_shader_interface_var *output);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_output_2(spvc_compiler compiler,
|
||||
const spvc_msl_shader_interface_var_2 *output);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_discrete_descriptor_set(spvc_compiler compiler, unsigned desc_set);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_argument_buffer_device_address_space(spvc_compiler compiler, unsigned desc_set, spvc_bool device_address);
|
||||
|
||||
/* Obsolete, use is_shader_input_used. */
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, unsigned location);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_shader_input_used(spvc_compiler compiler, unsigned location);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_shader_output_used(spvc_compiler compiler, unsigned location);
|
||||
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compiler,
|
||||
SpvExecutionModel model,
|
||||
@@ -991,6 +1054,19 @@ SPVC_PUBLIC_API int spvc_constant_get_scalar_i8(spvc_constant constant, unsigned
|
||||
SPVC_PUBLIC_API void spvc_constant_get_subconstants(spvc_constant constant, const spvc_constant_id **constituents, size_t *count);
|
||||
SPVC_PUBLIC_API spvc_type_id spvc_constant_get_type(spvc_constant constant);
|
||||
|
||||
/*
|
||||
* C implementation of the C++ api.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_constant_set_scalar_fp16(spvc_constant constant, unsigned column, unsigned row, unsigned short value);
|
||||
SPVC_PUBLIC_API void spvc_constant_set_scalar_fp32(spvc_constant constant, unsigned column, unsigned row, float value);
|
||||
SPVC_PUBLIC_API void spvc_constant_set_scalar_fp64(spvc_constant constant, unsigned column, unsigned row, double value);
|
||||
SPVC_PUBLIC_API void spvc_constant_set_scalar_u32(spvc_constant constant, unsigned column, unsigned row, unsigned value);
|
||||
SPVC_PUBLIC_API void spvc_constant_set_scalar_i32(spvc_constant constant, unsigned column, unsigned row, int value);
|
||||
SPVC_PUBLIC_API void spvc_constant_set_scalar_u16(spvc_constant constant, unsigned column, unsigned row, unsigned short value);
|
||||
SPVC_PUBLIC_API void spvc_constant_set_scalar_i16(spvc_constant constant, unsigned column, unsigned row, signed short value);
|
||||
SPVC_PUBLIC_API void spvc_constant_set_scalar_u8(spvc_constant constant, unsigned column, unsigned row, unsigned char value);
|
||||
SPVC_PUBLIC_API void spvc_constant_set_scalar_i8(spvc_constant constant, unsigned column, unsigned row, signed char value);
|
||||
|
||||
/*
|
||||
* Misc reflection
|
||||
* Maps to C++ API.
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "spirv_cross_error_handling.hpp"
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
@@ -210,7 +211,8 @@ public:
|
||||
buffer_capacity = N;
|
||||
}
|
||||
|
||||
SmallVector(const T *arg_list_begin, const T *arg_list_end) SPIRV_CROSS_NOEXCEPT : SmallVector()
|
||||
template <typename U>
|
||||
SmallVector(const U *arg_list_begin, const U *arg_list_end) SPIRV_CROSS_NOEXCEPT : SmallVector()
|
||||
{
|
||||
auto count = size_t(arg_list_end - arg_list_begin);
|
||||
reserve(count);
|
||||
@@ -219,7 +221,13 @@ public:
|
||||
this->buffer_size = count;
|
||||
}
|
||||
|
||||
SmallVector(std::initializer_list<T> init) SPIRV_CROSS_NOEXCEPT : SmallVector(init.begin(), init.end())
|
||||
template <typename U>
|
||||
SmallVector(std::initializer_list<U> init) SPIRV_CROSS_NOEXCEPT : SmallVector(init.begin(), init.end())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U, size_t M>
|
||||
explicit SmallVector(const U (&init)[M]) SPIRV_CROSS_NOEXCEPT : SmallVector(init, init + M)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -54,26 +54,26 @@ ParsedIR::ParsedIR()
|
||||
// Should have been default-implemented, but need this on MSVC 2013.
|
||||
ParsedIR::ParsedIR(ParsedIR &&other) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
*this = move(other);
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
ParsedIR &ParsedIR::operator=(ParsedIR &&other) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
pool_group = move(other.pool_group);
|
||||
spirv = move(other.spirv);
|
||||
meta = move(other.meta);
|
||||
pool_group = std::move(other.pool_group);
|
||||
spirv = std::move(other.spirv);
|
||||
meta = std::move(other.meta);
|
||||
for (int i = 0; i < TypeCount; i++)
|
||||
ids_for_type[i] = move(other.ids_for_type[i]);
|
||||
ids_for_constant_or_type = move(other.ids_for_constant_or_type);
|
||||
ids_for_constant_or_variable = move(other.ids_for_constant_or_variable);
|
||||
declared_capabilities = move(other.declared_capabilities);
|
||||
declared_extensions = move(other.declared_extensions);
|
||||
block_meta = move(other.block_meta);
|
||||
continue_block_to_loop_header = move(other.continue_block_to_loop_header);
|
||||
entry_points = move(other.entry_points);
|
||||
ids = move(other.ids);
|
||||
ids_for_type[i] = std::move(other.ids_for_type[i]);
|
||||
ids_for_constant_undef_or_type = std::move(other.ids_for_constant_undef_or_type);
|
||||
ids_for_constant_or_variable = std::move(other.ids_for_constant_or_variable);
|
||||
declared_capabilities = std::move(other.declared_capabilities);
|
||||
declared_extensions = std::move(other.declared_extensions);
|
||||
block_meta = std::move(other.block_meta);
|
||||
continue_block_to_loop_header = std::move(other.continue_block_to_loop_header);
|
||||
entry_points = std::move(other.entry_points);
|
||||
ids = std::move(other.ids);
|
||||
addressing_model = other.addressing_model;
|
||||
memory_model = other.memory_model;
|
||||
|
||||
@@ -102,7 +102,7 @@ ParsedIR &ParsedIR::operator=(const ParsedIR &other)
|
||||
meta = other.meta;
|
||||
for (int i = 0; i < TypeCount; i++)
|
||||
ids_for_type[i] = other.ids_for_type[i];
|
||||
ids_for_constant_or_type = other.ids_for_constant_or_type;
|
||||
ids_for_constant_undef_or_type = other.ids_for_constant_undef_or_type;
|
||||
ids_for_constant_or_variable = other.ids_for_constant_or_variable;
|
||||
declared_capabilities = other.declared_capabilities;
|
||||
declared_extensions = other.declared_extensions;
|
||||
@@ -330,6 +330,10 @@ void ParsedIR::fixup_reserved_names()
|
||||
{
|
||||
for (uint32_t id : meta_needing_name_fixup)
|
||||
{
|
||||
// Don't rename remapped variables like 'gl_LastFragDepthARM'.
|
||||
if (ids[id].get_type() == TypeVariable && get<SPIRVariable>(id).remapped_variable)
|
||||
continue;
|
||||
|
||||
auto &m = meta[id];
|
||||
sanitize_identifier(m.decoration.alias, false, false);
|
||||
for (auto &memb : m.members)
|
||||
@@ -349,7 +353,7 @@ void ParsedIR::set_name(ID id, const string &name)
|
||||
void ParsedIR::set_member_name(TypeID id, uint32_t index, const string &name)
|
||||
{
|
||||
auto &m = meta[id];
|
||||
m.members.resize(max(meta[id].members.size(), size_t(index) + 1));
|
||||
m.members.resize(max(m.members.size(), size_t(index) + 1));
|
||||
m.members[index].alias = name;
|
||||
if (!is_valid_identifier(name) || is_reserved_identifier(name, true, false))
|
||||
meta_needing_name_fixup.insert(id);
|
||||
@@ -366,6 +370,10 @@ void ParsedIR::set_decoration_string(ID id, Decoration decoration, const string
|
||||
dec.hlsl_semantic = argument;
|
||||
break;
|
||||
|
||||
case DecorationUserTypeGOOGLE:
|
||||
dec.user_type = argument;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -451,8 +459,9 @@ void ParsedIR::set_decoration(ID id, Decoration decoration, uint32_t argument)
|
||||
|
||||
void ParsedIR::set_member_decoration(TypeID id, uint32_t index, Decoration decoration, uint32_t argument)
|
||||
{
|
||||
meta[id].members.resize(max(meta[id].members.size(), size_t(index) + 1));
|
||||
auto &dec = meta[id].members[index];
|
||||
auto &m = meta[id];
|
||||
m.members.resize(max(m.members.size(), size_t(index) + 1));
|
||||
auto &dec = m.members[index];
|
||||
dec.decoration_flags.set(decoration);
|
||||
|
||||
switch (decoration)
|
||||
@@ -654,6 +663,9 @@ const string &ParsedIR::get_decoration_string(ID id, Decoration decoration) cons
|
||||
case DecorationHlslSemanticGOOGLE:
|
||||
return dec.hlsl_semantic;
|
||||
|
||||
case DecorationUserTypeGOOGLE:
|
||||
return dec.user_type;
|
||||
|
||||
default:
|
||||
return empty_string;
|
||||
}
|
||||
@@ -792,7 +804,8 @@ const Bitset &ParsedIR::get_decoration_bitset(ID id) const
|
||||
|
||||
void ParsedIR::set_member_decoration_string(TypeID id, uint32_t index, Decoration decoration, const string &argument)
|
||||
{
|
||||
meta[id].members.resize(max(meta[id].members.size(), size_t(index) + 1));
|
||||
auto &m = meta[id];
|
||||
m.members.resize(max(m.members.size(), size_t(index) + 1));
|
||||
auto &dec = meta[id].members[index];
|
||||
dec.decoration_flags.set(decoration);
|
||||
|
||||
@@ -928,7 +941,7 @@ void ParsedIR::add_typed_id(Types type, ID id)
|
||||
{
|
||||
case TypeConstant:
|
||||
ids_for_constant_or_variable.push_back(id);
|
||||
ids_for_constant_or_type.push_back(id);
|
||||
ids_for_constant_undef_or_type.push_back(id);
|
||||
break;
|
||||
|
||||
case TypeVariable:
|
||||
@@ -937,7 +950,8 @@ void ParsedIR::add_typed_id(Types type, ID id)
|
||||
|
||||
case TypeType:
|
||||
case TypeConstantOp:
|
||||
ids_for_constant_or_type.push_back(id);
|
||||
case TypeUndef:
|
||||
ids_for_constant_undef_or_type.push_back(id);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -999,7 +1013,7 @@ ParsedIR::LoopLock::LoopLock(uint32_t *lock_)
|
||||
|
||||
ParsedIR::LoopLock::LoopLock(LoopLock &&other) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
*this = move(other);
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
ParsedIR::LoopLock &ParsedIR::LoopLock::operator=(LoopLock &&other) SPIRV_CROSS_NOEXCEPT
|
||||
|
||||
@@ -74,8 +74,8 @@ public:
|
||||
// Special purpose lists which contain a union of types.
|
||||
// This is needed so we can declare specialization constants and structs in an interleaved fashion,
|
||||
// among other things.
|
||||
// Constants can be of struct type, and struct array sizes can use specialization constants.
|
||||
SmallVector<ID> ids_for_constant_or_type;
|
||||
// Constants can be undef or of struct type, and struct array sizes can use specialization constants.
|
||||
SmallVector<ID> ids_for_constant_undef_or_type;
|
||||
SmallVector<ID> ids_for_constant_or_variable;
|
||||
|
||||
// We need to keep track of the width the Ops that contains a type for the
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -83,6 +83,11 @@ public:
|
||||
|
||||
// Debug option to always emit temporary variables for all expressions.
|
||||
bool force_temporary = false;
|
||||
// Debug option, can be increased in an attempt to workaround SPIRV-Cross bugs temporarily.
|
||||
// If this limit has to be increased, it points to an implementation bug.
|
||||
// In certain scenarios, the maximum number of debug iterations may increase beyond this limit
|
||||
// as long as we can prove we're making certain kinds of forward progress.
|
||||
uint32_t force_recompile_max_debug_iterations = 3;
|
||||
|
||||
// If true, Vulkan GLSL features are used instead of GL-compatible features.
|
||||
// Mostly useful for debugging SPIR-V files.
|
||||
@@ -133,6 +138,19 @@ public:
|
||||
// what happens on legacy GLSL targets for blocks and structs.
|
||||
bool force_flattened_io_blocks = false;
|
||||
|
||||
// For opcodes where we have to perform explicit additional nan checks, very ugly code is generated.
|
||||
// If we opt-in, ignore these requirements.
|
||||
// In opcodes like NClamp/NMin/NMax and FP compare, ignore NaN behavior.
|
||||
// Use FClamp/FMin/FMax semantics for clamps and lets implementation choose ordered or unordered
|
||||
// compares.
|
||||
bool relax_nan_checks = false;
|
||||
|
||||
// Loading row-major matrices from UBOs on older AMD Windows OpenGL drivers is problematic.
|
||||
// To load these types correctly, we must generate a wrapper. them in a dummy function which only purpose is to
|
||||
// ensure row_major decoration is actually respected.
|
||||
// This workaround may cause significant performance degeneration on some Android devices.
|
||||
bool enable_row_major_load_workaround = true;
|
||||
|
||||
// If non-zero, controls layout(num_views = N) in; in GL_OVR_multiview2.
|
||||
uint32_t ovr_multiview_view_count = 0;
|
||||
|
||||
@@ -240,6 +258,10 @@ public:
|
||||
// require_extension("GL_KHR_my_extension");
|
||||
void require_extension(const std::string &ext);
|
||||
|
||||
// Returns the list of required extensions. After compilation this will contains any other
|
||||
// extensions that the compiler used automatically, in addition to the user specified ones.
|
||||
const SmallVector<std::string> &get_required_extensions() const;
|
||||
|
||||
// Legacy GLSL compatibility method.
|
||||
// Takes a uniform or push constant variable and flattens it into a (i|u)vec4 array[N]; array instead.
|
||||
// For this to work, all types in the block must be the same basic type, e.g. mixing vec2 and vec4 is fine, but
|
||||
@@ -265,6 +287,14 @@ public:
|
||||
void mask_stage_output_by_location(uint32_t location, uint32_t component);
|
||||
void mask_stage_output_by_builtin(spv::BuiltIn builtin);
|
||||
|
||||
// Allow to control how to format float literals in the output.
|
||||
// Set to "nullptr" to use the default "convert_to_string" function.
|
||||
// This handle is not owned by SPIRV-Cross and must remain valid until compile() has been called.
|
||||
void set_float_formatter(FloatFormatter *formatter)
|
||||
{
|
||||
float_formatter = formatter;
|
||||
}
|
||||
|
||||
protected:
|
||||
struct ShaderSubgroupSupportHelper
|
||||
{
|
||||
@@ -274,6 +304,7 @@ protected:
|
||||
KHR_shader_subgroup_ballot,
|
||||
KHR_shader_subgroup_basic,
|
||||
KHR_shader_subgroup_vote,
|
||||
KHR_shader_subgroup_arithmetic,
|
||||
NV_gpu_shader_5,
|
||||
NV_shader_thread_group,
|
||||
NV_shader_thread_shuffle,
|
||||
@@ -306,7 +337,18 @@ protected:
|
||||
SubgroupInverseBallot_InclBitCount_ExclBitCout = 13,
|
||||
SubgroupBallotBitExtract = 14,
|
||||
SubgroupBallotBitCount = 15,
|
||||
|
||||
SubgroupArithmeticIAddReduce = 16,
|
||||
SubgroupArithmeticIAddExclusiveScan = 17,
|
||||
SubgroupArithmeticIAddInclusiveScan = 18,
|
||||
SubgroupArithmeticFAddReduce = 19,
|
||||
SubgroupArithmeticFAddExclusiveScan = 20,
|
||||
SubgroupArithmeticFAddInclusiveScan = 21,
|
||||
SubgroupArithmeticIMulReduce = 22,
|
||||
SubgroupArithmeticIMulExclusiveScan = 23,
|
||||
SubgroupArithmeticIMulInclusiveScan = 24,
|
||||
SubgroupArithmeticFMulReduce = 25,
|
||||
SubgroupArithmeticFMulExclusiveScan = 26,
|
||||
SubgroupArithmeticFMulInclusiveScan = 27,
|
||||
FeatureCount
|
||||
};
|
||||
|
||||
@@ -340,9 +382,9 @@ protected:
|
||||
};
|
||||
|
||||
// TODO remove this function when all subgroup ops are supported (or make it always return true)
|
||||
static bool is_supported_subgroup_op_in_opengl(spv::Op op);
|
||||
static bool is_supported_subgroup_op_in_opengl(spv::Op op, const uint32_t *ops);
|
||||
|
||||
void reset();
|
||||
void reset(uint32_t iteration_count);
|
||||
void emit_function(SPIRFunction &func, const Bitset &return_flags);
|
||||
|
||||
bool has_extension(const std::string &ext) const;
|
||||
@@ -352,11 +394,23 @@ protected:
|
||||
virtual void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags);
|
||||
|
||||
SPIRBlock *current_emitting_block = nullptr;
|
||||
SPIRBlock *current_emitting_switch = nullptr;
|
||||
SmallVector<SPIRBlock *> current_emitting_switch_stack;
|
||||
bool current_emitting_switch_fallthrough = false;
|
||||
|
||||
virtual void emit_instruction(const Instruction &instr);
|
||||
struct TemporaryCopy
|
||||
{
|
||||
uint32_t dst_id;
|
||||
uint32_t src_id;
|
||||
};
|
||||
TemporaryCopy handle_instruction_precision(const Instruction &instr);
|
||||
void emit_block_instructions(SPIRBlock &block);
|
||||
void emit_block_instructions_with_masked_debug(SPIRBlock &block);
|
||||
|
||||
// For relax_nan_checks.
|
||||
GLSLstd450 get_remapped_glsl_op(GLSLstd450 std450_op) const;
|
||||
spv::Op get_remapped_spirv_op(spv::Op op) const;
|
||||
|
||||
virtual void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
uint32_t count);
|
||||
virtual void emit_spv_amd_shader_ballot_op(uint32_t result_type, uint32_t result_id, uint32_t op,
|
||||
@@ -385,7 +439,9 @@ protected:
|
||||
const std::string &qualifier = "", uint32_t base_offset = 0);
|
||||
virtual void emit_struct_padding_target(const SPIRType &type);
|
||||
virtual std::string image_type_glsl(const SPIRType &type, uint32_t id = 0);
|
||||
std::string constant_expression(const SPIRConstant &c);
|
||||
std::string constant_expression(const SPIRConstant &c,
|
||||
bool inside_block_like_struct_scope = false,
|
||||
bool inside_struct_scope = false);
|
||||
virtual std::string constant_op_expression(const SPIRConstantOp &cop);
|
||||
virtual std::string constant_expression_vector(const SPIRConstant &c, uint32_t vector);
|
||||
virtual void emit_fixup();
|
||||
@@ -419,7 +475,7 @@ protected:
|
||||
TextureFunctionArguments() = default;
|
||||
TextureFunctionBaseArguments base;
|
||||
uint32_t coord = 0, coord_components = 0, dref = 0;
|
||||
uint32_t grad_x = 0, grad_y = 0, lod = 0, coffset = 0, offset = 0;
|
||||
uint32_t grad_x = 0, grad_y = 0, lod = 0, offset = 0;
|
||||
uint32_t bias = 0, component = 0, sample = 0, sparse_texel = 0, min_lod = 0;
|
||||
bool nonuniform_expression = false;
|
||||
};
|
||||
@@ -436,6 +492,8 @@ protected:
|
||||
|
||||
virtual bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const;
|
||||
|
||||
virtual bool is_user_type_structured(uint32_t id) const;
|
||||
|
||||
void emit_copy_logical_type(uint32_t lhs_id, uint32_t lhs_type_id, uint32_t rhs_id, uint32_t rhs_type_id,
|
||||
SmallVector<uint32_t> chain);
|
||||
|
||||
@@ -495,6 +553,8 @@ protected:
|
||||
// on a single line separated by comma.
|
||||
SmallVector<std::string> *redirect_statement = nullptr;
|
||||
const SPIRBlock *current_continue_block = nullptr;
|
||||
bool block_temporary_hoisting = false;
|
||||
bool block_debug_directives = false;
|
||||
|
||||
void begin_scope();
|
||||
void end_scope();
|
||||
@@ -522,7 +582,8 @@ protected:
|
||||
bool member_is_remapped_physical_type(const SPIRType &type, uint32_t index) const;
|
||||
bool member_is_packed_physical_type(const SPIRType &type, uint32_t index) const;
|
||||
virtual std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type,
|
||||
uint32_t physical_type_id, bool is_packed);
|
||||
uint32_t physical_type_id, bool is_packed,
|
||||
bool relaxed = false);
|
||||
|
||||
std::unordered_set<std::string> local_variable_names;
|
||||
std::unordered_set<std::string> resource_names;
|
||||
@@ -559,6 +620,7 @@ protected:
|
||||
const char *uint16_t_literal_suffix = "us";
|
||||
const char *nonuniform_qualifier = "nonuniformEXT";
|
||||
const char *boolean_mix_function = "mix";
|
||||
SPIRType::BaseType boolean_in_struct_remapped_type = SPIRType::Boolean;
|
||||
bool swizzle_is_function = false;
|
||||
bool shared_is_implied = false;
|
||||
bool unsized_array_supported = true;
|
||||
@@ -572,12 +634,13 @@ protected:
|
||||
bool allow_precision_qualifiers = false;
|
||||
bool can_swizzle_scalar = false;
|
||||
bool force_gl_in_out_block = false;
|
||||
bool force_merged_mesh_block = false;
|
||||
bool can_return_array = true;
|
||||
bool allow_truncated_access_chain = false;
|
||||
bool supports_extensions = false;
|
||||
bool supports_empty_struct = false;
|
||||
bool array_is_value_type = true;
|
||||
bool buffer_offset_array_is_value_type = true;
|
||||
bool array_is_value_type_in_buffer_blocks = true;
|
||||
bool comparison_image_samples_scalar = false;
|
||||
bool native_pointers = false;
|
||||
bool support_small_type_sampling_result = false;
|
||||
@@ -587,16 +650,21 @@ protected:
|
||||
bool support_pointer_to_pointer = false;
|
||||
bool support_precise_qualifier = false;
|
||||
bool support_64bit_switch = false;
|
||||
bool workgroup_size_is_hidden = false;
|
||||
bool requires_relaxed_precision_analysis = false;
|
||||
bool implicit_c_integer_promotion_rules = false;
|
||||
} backend;
|
||||
|
||||
void emit_struct(SPIRType &type);
|
||||
void emit_resources();
|
||||
void emit_extension_workarounds(spv::ExecutionModel model);
|
||||
void emit_subgroup_arithmetic_workaround(const std::string &func, spv::Op op, spv::GroupOperation group_op);
|
||||
void emit_polyfills(uint32_t polyfills, bool relaxed);
|
||||
void emit_buffer_block_native(const SPIRVariable &var);
|
||||
void emit_buffer_reference_block(uint32_t type_id, bool forward_declaration);
|
||||
void emit_buffer_block_legacy(const SPIRVariable &var);
|
||||
void emit_buffer_block_flattened(const SPIRVariable &type);
|
||||
void fixup_implicit_builtin_block_names();
|
||||
void fixup_implicit_builtin_block_names(spv::ExecutionModel model);
|
||||
void emit_declared_builtin_block(spv::StorageClass storage, spv::ExecutionModel model);
|
||||
bool should_force_emit_builtin_block(spv::StorageClass storage);
|
||||
void emit_push_constant_block_vulkan(const SPIRVariable &var);
|
||||
@@ -610,6 +678,7 @@ protected:
|
||||
void emit_block_chain(SPIRBlock &block);
|
||||
void emit_hoisted_temporaries(SmallVector<std::pair<TypeID, ID>> &temporaries);
|
||||
std::string constant_value_macro_name(uint32_t id);
|
||||
int get_constant_mapping_to_workgroup_component(const SPIRConstant &constant) const;
|
||||
void emit_constant(const SPIRConstant &constant);
|
||||
void emit_specialization_constant_op(const SPIRConstantOp &constant);
|
||||
std::string emit_continue_block(uint32_t continue_block, bool follow_true_block, bool follow_false_block);
|
||||
@@ -628,6 +697,7 @@ protected:
|
||||
bool should_suppress_usage_tracking(uint32_t id) const;
|
||||
void emit_mix_op(uint32_t result_type, uint32_t id, uint32_t left, uint32_t right, uint32_t lerp);
|
||||
void emit_nminmax_op(uint32_t result_type, uint32_t id, uint32_t op0, uint32_t op1, GLSLstd450 op);
|
||||
void emit_emulated_ahyper_op(uint32_t result_type, uint32_t result_id, uint32_t op0, GLSLstd450 op);
|
||||
bool to_trivial_mix_op(const SPIRType &type, std::string &op, uint32_t left, uint32_t right, uint32_t lerp);
|
||||
void emit_quaternary_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, uint32_t op2,
|
||||
uint32_t op3, const char *op);
|
||||
@@ -658,7 +728,7 @@ protected:
|
||||
void emit_unrolled_binary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op,
|
||||
bool negate, SPIRType::BaseType expected_type);
|
||||
void emit_binary_op_cast(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op,
|
||||
SPIRType::BaseType input_type, bool skip_cast_if_equal_type);
|
||||
SPIRType::BaseType input_type, bool skip_cast_if_equal_type, bool implicit_integer_promotion);
|
||||
|
||||
SPIRType binary_op_bitcast_helper(std::string &cast_op0, std::string &cast_op1, SPIRType::BaseType &input_type,
|
||||
uint32_t op0, uint32_t op1, bool skip_cast_if_equal_type);
|
||||
@@ -669,6 +739,8 @@ protected:
|
||||
uint32_t false_value);
|
||||
|
||||
void emit_unary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op);
|
||||
void emit_unary_op_cast(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op);
|
||||
virtual void emit_mesh_tasks(SPIRBlock &block);
|
||||
bool expression_is_forwarded(uint32_t id) const;
|
||||
bool expression_suppresses_usage_tracking(uint32_t id) const;
|
||||
bool expression_read_implies_multiple_reads(uint32_t id) const;
|
||||
@@ -684,7 +756,8 @@ protected:
|
||||
spv::StorageClass get_expression_effective_storage_class(uint32_t ptr);
|
||||
virtual bool access_chain_needs_stage_io_builtin_translation(uint32_t base);
|
||||
|
||||
virtual void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type,
|
||||
virtual void check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type);
|
||||
virtual bool prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type,
|
||||
spv::StorageClass storage, bool &is_packed);
|
||||
|
||||
std::string access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type,
|
||||
@@ -716,8 +789,8 @@ protected:
|
||||
void append_global_func_args(const SPIRFunction &func, uint32_t index, SmallVector<std::string> &arglist);
|
||||
std::string to_non_uniform_aware_expression(uint32_t id);
|
||||
std::string to_expression(uint32_t id, bool register_expression_read = true);
|
||||
std::string to_composite_constructor_expression(uint32_t id, bool uses_buffer_offset);
|
||||
std::string to_rerolled_array_expression(const std::string &expr, const SPIRType &type);
|
||||
std::string to_composite_constructor_expression(const SPIRType &parent_type, uint32_t id, bool block_like_type);
|
||||
std::string to_rerolled_array_expression(const SPIRType &parent_type, const std::string &expr, const SPIRType &type);
|
||||
std::string to_enclosed_expression(uint32_t id, bool register_expression_read = true);
|
||||
std::string to_unpacked_expression(uint32_t id, bool register_expression_read = true);
|
||||
std::string to_unpacked_row_major_matrix_expression(uint32_t id);
|
||||
@@ -728,17 +801,18 @@ protected:
|
||||
std::string to_extract_component_expression(uint32_t id, uint32_t index);
|
||||
std::string to_extract_constant_composite_expression(uint32_t result_type, const SPIRConstant &c,
|
||||
const uint32_t *chain, uint32_t length);
|
||||
static bool needs_enclose_expression(const std::string &expr);
|
||||
std::string enclose_expression(const std::string &expr);
|
||||
std::string dereference_expression(const SPIRType &expression_type, const std::string &expr);
|
||||
std::string address_of_expression(const std::string &expr);
|
||||
void strip_enclosed_expression(std::string &expr);
|
||||
std::string to_member_name(const SPIRType &type, uint32_t index);
|
||||
virtual std::string to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain);
|
||||
virtual std::string to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain_is_resolved);
|
||||
std::string to_multi_member_reference(const SPIRType &type, const SmallVector<uint32_t> &indices);
|
||||
std::string type_to_glsl_constructor(const SPIRType &type);
|
||||
std::string argument_decl(const SPIRFunction::Parameter &arg);
|
||||
virtual std::string to_qualifiers_glsl(uint32_t id);
|
||||
void fixup_io_block_patch_qualifiers(const SPIRVariable &var);
|
||||
void fixup_io_block_patch_primitive_qualifiers(const SPIRVariable &var);
|
||||
void emit_output_variable_initializer(const SPIRVariable &var);
|
||||
std::string to_precision_qualifiers_glsl(uint32_t id);
|
||||
virtual const char *to_storage_qualifiers_glsl(const SPIRVariable &var);
|
||||
@@ -749,7 +823,7 @@ protected:
|
||||
std::string layout_for_variable(const SPIRVariable &variable);
|
||||
std::string to_combined_image_sampler(VariableID image_id, VariableID samp_id);
|
||||
virtual bool skip_argument(uint32_t id) const;
|
||||
virtual void emit_array_copy(const std::string &lhs, uint32_t lhs_id, uint32_t rhs_id,
|
||||
virtual bool emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rhs_id,
|
||||
spv::StorageClass lhs_storage, spv::StorageClass rhs_storage);
|
||||
virtual void emit_block_hints(const SPIRBlock &block);
|
||||
virtual std::string to_initializer_expression(const SPIRVariable &var);
|
||||
@@ -789,6 +863,10 @@ protected:
|
||||
void replace_fragment_outputs();
|
||||
std::string legacy_tex_op(const std::string &op, const SPIRType &imgtype, uint32_t id);
|
||||
|
||||
void forward_relaxed_precision(uint32_t dst_id, const uint32_t *args, uint32_t length);
|
||||
void analyze_precision_requirements(uint32_t type_id, uint32_t dst_id, uint32_t *args, uint32_t length);
|
||||
Options::Precision analyze_expression_precision(const uint32_t *args, uint32_t length) const;
|
||||
|
||||
uint32_t indent = 0;
|
||||
|
||||
std::unordered_set<uint32_t> emitted_functions;
|
||||
@@ -842,10 +920,25 @@ protected:
|
||||
return !options.es && options.version < 130;
|
||||
}
|
||||
|
||||
bool requires_transpose_2x2 = false;
|
||||
bool requires_transpose_3x3 = false;
|
||||
bool requires_transpose_4x4 = false;
|
||||
enum Polyfill : uint32_t
|
||||
{
|
||||
PolyfillTranspose2x2 = 1 << 0,
|
||||
PolyfillTranspose3x3 = 1 << 1,
|
||||
PolyfillTranspose4x4 = 1 << 2,
|
||||
PolyfillDeterminant2x2 = 1 << 3,
|
||||
PolyfillDeterminant3x3 = 1 << 4,
|
||||
PolyfillDeterminant4x4 = 1 << 5,
|
||||
PolyfillMatrixInverse2x2 = 1 << 6,
|
||||
PolyfillMatrixInverse3x3 = 1 << 7,
|
||||
PolyfillMatrixInverse4x4 = 1 << 8,
|
||||
};
|
||||
|
||||
uint32_t required_polyfills = 0;
|
||||
uint32_t required_polyfills_relaxed = 0;
|
||||
void require_polyfill(Polyfill polyfill, bool relaxed);
|
||||
|
||||
bool ray_tracing_is_khr = false;
|
||||
bool barycentric_is_nv = false;
|
||||
void ray_tracing_khr_fixup_locations();
|
||||
|
||||
bool args_will_forward(uint32_t id, const uint32_t *args, uint32_t num_args, bool pure);
|
||||
@@ -879,8 +972,14 @@ protected:
|
||||
|
||||
void check_function_call_constraints(const uint32_t *args, uint32_t length);
|
||||
void handle_invalid_expression(uint32_t id);
|
||||
void force_temporary_and_recompile(uint32_t id);
|
||||
void find_static_extensions();
|
||||
|
||||
uint32_t consume_temporary_in_precision_context(uint32_t type_id, uint32_t id, Options::Precision precision);
|
||||
std::unordered_map<uint32_t, uint32_t> temporary_to_mirror_precision_alias;
|
||||
std::unordered_set<uint32_t> composite_insert_overwritten;
|
||||
std::unordered_set<uint32_t> block_composite_insert_overwrite;
|
||||
|
||||
std::string emit_for_loop_initializers(const SPIRBlock &block);
|
||||
void emit_while_loop_initializers(const SPIRBlock &block);
|
||||
bool for_loop_initializers_are_same_type(const SPIRBlock &block);
|
||||
@@ -889,8 +988,6 @@ protected:
|
||||
|
||||
bool type_is_empty(const SPIRType &type);
|
||||
|
||||
virtual void declare_undefined_values();
|
||||
|
||||
bool can_use_io_location(spv::StorageClass storage, bool block);
|
||||
const Instruction *get_next_instruction_in_block(const Instruction &instr);
|
||||
static uint32_t mask_relevant_memory_semantics(uint32_t semantics);
|
||||
@@ -904,6 +1001,7 @@ protected:
|
||||
// Builtins in GLSL are always specific signedness, but the SPIR-V can declare them
|
||||
// as either unsigned or signed.
|
||||
// Sometimes we will need to automatically perform casts on load and store to make this work.
|
||||
virtual SPIRType::BaseType get_builtin_basetype(spv::BuiltIn builtin, SPIRType::BaseType default_type);
|
||||
virtual void cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type);
|
||||
virtual void cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type);
|
||||
void unroll_array_from_complex_load(uint32_t target_id, uint32_t source_id, std::string &expr);
|
||||
@@ -926,6 +1024,8 @@ protected:
|
||||
|
||||
void fixup_type_alias();
|
||||
void reorder_type_alias();
|
||||
void fixup_anonymous_struct_names();
|
||||
void fixup_anonymous_struct_names(std::unordered_set<uint32_t> &visited, const SPIRType &type);
|
||||
|
||||
static const char *vector_swizzle(int vecsize, int index);
|
||||
|
||||
@@ -933,13 +1033,24 @@ protected:
|
||||
bool is_stage_output_builtin_masked(spv::BuiltIn builtin) const;
|
||||
bool is_stage_output_variable_masked(const SPIRVariable &var) const;
|
||||
bool is_stage_output_block_member_masked(const SPIRVariable &var, uint32_t index, bool strip_array) const;
|
||||
bool is_per_primitive_variable(const SPIRVariable &var) const;
|
||||
uint32_t get_accumulated_member_location(const SPIRVariable &var, uint32_t mbr_idx, bool strip_array) const;
|
||||
uint32_t get_declared_member_location(const SPIRVariable &var, uint32_t mbr_idx, bool strip_array) const;
|
||||
std::unordered_set<LocationComponentPair, InternalHasher> masked_output_locations;
|
||||
std::unordered_set<uint32_t> masked_output_builtins;
|
||||
|
||||
FloatFormatter *float_formatter = nullptr;
|
||||
std::string format_float(float value) const;
|
||||
std::string format_double(double value) const;
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
SmallVector<ConstantID> get_composite_constant_ids(ConstantID const_id);
|
||||
void fill_composite_constant(SPIRConstant &constant, TypeID type_id, const SmallVector<ConstantID> &initializers);
|
||||
void set_composite_constant(ConstantID const_id, TypeID type_id, const SmallVector<ConstantID> &initializers);
|
||||
TypeID get_composite_member_type(TypeID type_id, uint32_t member_idx);
|
||||
std::unordered_map<uint32_t, SmallVector<ConstantID>> const_composite_insert_ids;
|
||||
};
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -98,6 +98,11 @@ struct HLSLResourceBinding
|
||||
} cbv, uav, srv, sampler;
|
||||
};
|
||||
|
||||
enum HLSLAuxBinding
|
||||
{
|
||||
HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE = 0
|
||||
};
|
||||
|
||||
class CompilerHLSL : public CompilerGLSL
|
||||
{
|
||||
public:
|
||||
@@ -105,7 +110,7 @@ public:
|
||||
{
|
||||
uint32_t shader_model = 30; // TODO: map ps_4_0_level_9_0,... somehow
|
||||
|
||||
// Allows the PointSize builtin, and ignores it, as PointSize is not supported in HLSL.
|
||||
// Allows the PointSize builtin in SM 4.0+, and ignores it, as PointSize is not supported in SM 4+.
|
||||
bool point_size_compat = false;
|
||||
|
||||
// Allows the PointCoord builtin, returns float2(0.5, 0.5), as PointCoord is not supported in HLSL.
|
||||
@@ -121,7 +126,7 @@ public:
|
||||
// By default, a readonly storage buffer will be declared as ByteAddressBuffer (SRV) instead.
|
||||
// Alternatively, use set_hlsl_force_storage_buffer_as_uav to specify individually.
|
||||
bool force_storage_buffer_as_uav = false;
|
||||
|
||||
|
||||
// Forces any storage image type marked as NonWritable to be considered an SRV instead.
|
||||
// For this to work with function call parameters, NonWritable must be considered to be part of the type system
|
||||
// so that NonWritable image arguments are also translated to Texture rather than RWTexture.
|
||||
@@ -137,6 +142,14 @@ public:
|
||||
// If add_vertex_attribute_remap is used and this feature is used,
|
||||
// the semantic name will be queried once per active location.
|
||||
bool flatten_matrix_vertex_input_semantics = false;
|
||||
|
||||
// Rather than emitting main() for the entry point, use the name in SPIR-V.
|
||||
bool use_entry_point_name = false;
|
||||
|
||||
// Preserve (RW)StructuredBuffer types if the input source was HLSL.
|
||||
// This relies on UserTypeGOOGLE to encode the buffer type either as "structuredbuffer" or "rwstructuredbuffer"
|
||||
// whereas the type can be extended with an optional subtype, e.g. "structuredbuffer:int".
|
||||
bool preserve_structured_buffers = false;
|
||||
};
|
||||
|
||||
explicit CompilerHLSL(std::vector<uint32_t> spirv_)
|
||||
@@ -208,6 +221,11 @@ public:
|
||||
// Controls which storage buffer bindings will be forced to be declared as UAVs.
|
||||
void set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint32_t binding);
|
||||
|
||||
// By default, these magic buffers are not assigned a specific binding.
|
||||
void set_hlsl_aux_buffer_binding(HLSLAuxBinding binding, uint32_t register_index, uint32_t register_space);
|
||||
void unset_hlsl_aux_buffer_binding(HLSLAuxBinding binding);
|
||||
bool is_hlsl_aux_buffer_binding_used(HLSLAuxBinding binding) const;
|
||||
|
||||
private:
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string image_type_hlsl(const SPIRType &type, uint32_t id);
|
||||
@@ -217,14 +235,13 @@ private:
|
||||
void emit_hlsl_entry_point();
|
||||
void emit_header() override;
|
||||
void emit_resources();
|
||||
void declare_undefined_values() override;
|
||||
void emit_interface_block_globally(const SPIRVariable &type);
|
||||
void emit_interface_block_in_struct(const SPIRVariable &var, std::unordered_set<uint32_t> &active_locations);
|
||||
void emit_interface_block_member_in_struct(const SPIRVariable &var, uint32_t member_index,
|
||||
uint32_t location,
|
||||
void emit_interface_block_member_in_struct(const SPIRVariable &var, uint32_t member_index, uint32_t location,
|
||||
std::unordered_set<uint32_t> &active_locations);
|
||||
void emit_builtin_inputs_in_struct();
|
||||
void emit_builtin_outputs_in_struct();
|
||||
void emit_builtin_primitive_outputs_in_struct();
|
||||
void emit_texture_op(const Instruction &i, bool sparse) override;
|
||||
void emit_instruction(const Instruction &instruction) override;
|
||||
void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
@@ -267,10 +284,14 @@ private:
|
||||
|
||||
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier,
|
||||
uint32_t base_offset = 0) override;
|
||||
void emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops);
|
||||
void emit_mesh_tasks(SPIRBlock &block) override;
|
||||
|
||||
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;
|
||||
void replace_illegal_names() override;
|
||||
|
||||
SPIRType::BaseType get_builtin_basetype(spv::BuiltIn builtin, SPIRType::BaseType default_type) override;
|
||||
|
||||
bool is_hlsl_force_storage_buffer_as_uav(ID id) const;
|
||||
|
||||
Options hlsl_options;
|
||||
@@ -341,6 +362,10 @@ private:
|
||||
TypeUnpackUint64
|
||||
};
|
||||
|
||||
void analyze_meshlet_writes();
|
||||
void analyze_meshlet_writes(uint32_t func_id, uint32_t id_per_vertex, uint32_t id_per_primitive,
|
||||
std::unordered_set<uint32_t> &processed_func_ids);
|
||||
|
||||
BitcastType get_bitcast_type(uint32_t result_type, uint32_t op0);
|
||||
|
||||
void emit_builtin_variables();
|
||||
@@ -369,10 +394,20 @@ private:
|
||||
|
||||
std::unordered_set<SetBindingPair, InternalHasher> force_uav_buffer_bindings;
|
||||
|
||||
// Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but SV_Coverage is a scalar in HLSL.
|
||||
bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override;
|
||||
struct
|
||||
{
|
||||
uint32_t register_index = 0;
|
||||
uint32_t register_space = 0;
|
||||
bool explicit_binding = false;
|
||||
bool used = false;
|
||||
} base_vertex_info;
|
||||
|
||||
// Returns true if the specified ID has a UserTypeGOOGLE decoration for StructuredBuffer or RWStructuredBuffer resources.
|
||||
bool is_user_type_structured(uint32_t id) const override;
|
||||
|
||||
std::vector<TypeID> composite_selection_workaround_types;
|
||||
|
||||
std::string get_inner_entry_point_name() const;
|
||||
};
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
|
||||
+2936
-939
File diff suppressed because it is too large
Load Diff
@@ -34,36 +34,53 @@
|
||||
namespace SPIRV_CROSS_NAMESPACE
|
||||
{
|
||||
|
||||
// Indicates the format of a shader input. Currently limited to specifying
|
||||
// Indicates the format of a shader interface variable. Currently limited to specifying
|
||||
// if the input is an 8-bit unsigned integer, 16-bit unsigned integer, or
|
||||
// some other format.
|
||||
enum MSLShaderInputFormat
|
||||
enum MSLShaderVariableFormat
|
||||
{
|
||||
MSL_SHADER_INPUT_FORMAT_OTHER = 0,
|
||||
MSL_SHADER_INPUT_FORMAT_UINT8 = 1,
|
||||
MSL_SHADER_INPUT_FORMAT_UINT16 = 2,
|
||||
MSL_SHADER_INPUT_FORMAT_ANY16 = 3,
|
||||
MSL_SHADER_INPUT_FORMAT_ANY32 = 4,
|
||||
MSL_SHADER_VARIABLE_FORMAT_OTHER = 0,
|
||||
MSL_SHADER_VARIABLE_FORMAT_UINT8 = 1,
|
||||
MSL_SHADER_VARIABLE_FORMAT_UINT16 = 2,
|
||||
MSL_SHADER_VARIABLE_FORMAT_ANY16 = 3,
|
||||
MSL_SHADER_VARIABLE_FORMAT_ANY32 = 4,
|
||||
|
||||
// Deprecated aliases.
|
||||
MSL_VERTEX_FORMAT_OTHER = MSL_SHADER_INPUT_FORMAT_OTHER,
|
||||
MSL_VERTEX_FORMAT_UINT8 = MSL_SHADER_INPUT_FORMAT_UINT8,
|
||||
MSL_VERTEX_FORMAT_UINT16 = MSL_SHADER_INPUT_FORMAT_UINT16,
|
||||
MSL_VERTEX_FORMAT_OTHER = MSL_SHADER_VARIABLE_FORMAT_OTHER,
|
||||
MSL_VERTEX_FORMAT_UINT8 = MSL_SHADER_VARIABLE_FORMAT_UINT8,
|
||||
MSL_VERTEX_FORMAT_UINT16 = MSL_SHADER_VARIABLE_FORMAT_UINT16,
|
||||
MSL_SHADER_INPUT_FORMAT_OTHER = MSL_SHADER_VARIABLE_FORMAT_OTHER,
|
||||
MSL_SHADER_INPUT_FORMAT_UINT8 = MSL_SHADER_VARIABLE_FORMAT_UINT8,
|
||||
MSL_SHADER_INPUT_FORMAT_UINT16 = MSL_SHADER_VARIABLE_FORMAT_UINT16,
|
||||
MSL_SHADER_INPUT_FORMAT_ANY16 = MSL_SHADER_VARIABLE_FORMAT_ANY16,
|
||||
MSL_SHADER_INPUT_FORMAT_ANY32 = MSL_SHADER_VARIABLE_FORMAT_ANY32,
|
||||
|
||||
MSL_SHADER_INPUT_FORMAT_INT_MAX = 0x7fffffff
|
||||
MSL_SHADER_VARIABLE_FORMAT_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
// Defines MSL characteristics of an input variable at a particular location.
|
||||
// Indicates the rate at which a variable changes value, one of: per-vertex,
|
||||
// per-primitive, or per-patch.
|
||||
enum MSLShaderVariableRate
|
||||
{
|
||||
MSL_SHADER_VARIABLE_RATE_PER_VERTEX = 0,
|
||||
MSL_SHADER_VARIABLE_RATE_PER_PRIMITIVE = 1,
|
||||
MSL_SHADER_VARIABLE_RATE_PER_PATCH = 2,
|
||||
|
||||
MSL_SHADER_VARIABLE_RATE_INT_MAX = 0x7fffffff,
|
||||
};
|
||||
|
||||
// Defines MSL characteristics of a shader interface variable at a particular location.
|
||||
// After compilation, it is possible to query whether or not this location was used.
|
||||
// If vecsize is nonzero, it must be greater than or equal to the vecsize declared in the shader,
|
||||
// or behavior is undefined.
|
||||
struct MSLShaderInput
|
||||
struct MSLShaderInterfaceVariable
|
||||
{
|
||||
uint32_t location = 0;
|
||||
uint32_t component = 0;
|
||||
MSLShaderInputFormat format = MSL_SHADER_INPUT_FORMAT_OTHER;
|
||||
MSLShaderVariableFormat format = MSL_SHADER_VARIABLE_FORMAT_OTHER;
|
||||
spv::BuiltIn builtin = spv::BuiltInMax;
|
||||
uint32_t vecsize = 0;
|
||||
MSLShaderVariableRate rate = MSL_SHADER_VARIABLE_RATE_PER_VERTEX;
|
||||
};
|
||||
|
||||
// Matches the binding index of a MSL resource for a binding within a descriptor set.
|
||||
@@ -301,6 +318,7 @@ public:
|
||||
uint32_t dynamic_offsets_buffer_index = 23;
|
||||
uint32_t shader_input_buffer_index = 22;
|
||||
uint32_t shader_index_buffer_index = 21;
|
||||
uint32_t shader_patch_input_buffer_index = 20;
|
||||
uint32_t shader_input_wg_index = 0;
|
||||
uint32_t device_index = 0;
|
||||
uint32_t enable_frag_output_mask = 0xffffffff;
|
||||
@@ -321,10 +339,28 @@ public:
|
||||
bool dispatch_base = false;
|
||||
bool texture_1D_as_2D = false;
|
||||
|
||||
// Enable use of MSL 2.0 indirect argument buffers.
|
||||
// Enable use of Metal argument buffers.
|
||||
// MSL 2.0 must also be enabled.
|
||||
bool argument_buffers = false;
|
||||
|
||||
// Defines Metal argument buffer tier levels.
|
||||
// Uses same values as Metal MTLArgumentBuffersTier enumeration.
|
||||
enum class ArgumentBuffersTier
|
||||
{
|
||||
Tier1 = 0,
|
||||
Tier2 = 1,
|
||||
};
|
||||
|
||||
// When using Metal argument buffers, indicates the Metal argument buffer tier level supported by the Metal platform.
|
||||
// Ignored when Options::argument_buffers is disabled.
|
||||
// - Tier1 supports writable images on macOS, but not on iOS.
|
||||
// - Tier2 supports writable images on macOS and iOS, and higher resource count limits.
|
||||
// Tier capabilities based on recommendations from Apple engineering.
|
||||
ArgumentBuffersTier argument_buffers_tier = ArgumentBuffersTier::Tier1;
|
||||
|
||||
// Enables specifick argument buffer format with extra information to track SSBO-length
|
||||
bool runtime_array_rich_descriptor = false;
|
||||
|
||||
// Ensures vertex and instance indices start at zero. This reflects the behavior of HLSL with SV_VertexID and SV_InstanceID.
|
||||
bool enable_base_index_zero = false;
|
||||
|
||||
@@ -382,6 +418,11 @@ public:
|
||||
// builtins are processed, but should result in more efficient usage of the GPU.
|
||||
bool multi_patch_workgroup = false;
|
||||
|
||||
// Use storage buffers instead of vertex-style attributes for tessellation evaluation
|
||||
// input. This may require conversion of inputs in the generated post-tessellation
|
||||
// vertex shader, but allows the use of nested arrays.
|
||||
bool raw_buffer_tese_input = false;
|
||||
|
||||
// If set, a vertex shader will be compiled as part of a tessellation pipeline.
|
||||
// It will be translated as a compute kernel, so it can use the global invocation ID
|
||||
// to index the output buffer.
|
||||
@@ -393,7 +434,7 @@ public:
|
||||
// and will be addressed using the current ViewIndex.
|
||||
bool arrayed_subpass_input = false;
|
||||
|
||||
// Whether to use SIMD-group or quadgroup functions to implement group nnon-uniform
|
||||
// Whether to use SIMD-group or quadgroup functions to implement group non-uniform
|
||||
// operations. Some GPUs on iOS do not support the SIMD-group functions, only the
|
||||
// quadgroup functions.
|
||||
bool ios_use_simdgroup_functions = false;
|
||||
@@ -435,6 +476,49 @@ public:
|
||||
// the extra threads away.
|
||||
bool force_sample_rate_shading = false;
|
||||
|
||||
// If set, gl_HelperInvocation will be set manually whenever a fragment is discarded.
|
||||
// Some Metal devices have a bug where simd_is_helper_thread() does not return true
|
||||
// after a fragment has been discarded. This is a workaround that is only expected to be needed
|
||||
// until the bug is fixed in Metal; it is provided as an option to allow disabling it when that occurs.
|
||||
bool manual_helper_invocation_updates = true;
|
||||
|
||||
// If set, extra checks will be emitted in fragment shaders to prevent writes
|
||||
// from discarded fragments. Some Metal devices have a bug where writes to storage resources
|
||||
// from discarded fragment threads continue to occur, despite the fragment being
|
||||
// discarded. This is a workaround that is only expected to be needed until the
|
||||
// bug is fixed in Metal; it is provided as an option so it can be enabled
|
||||
// only when the bug is present.
|
||||
bool check_discarded_frag_stores = false;
|
||||
|
||||
// If set, Lod operands to OpImageSample*DrefExplicitLod for 1D and 2D array images
|
||||
// will be implemented using a gradient instead of passing the level operand directly.
|
||||
// Some Metal devices have a bug where the level() argument to depth2d_array<T>::sample_compare()
|
||||
// in a fragment shader is biased by some unknown amount, possibly dependent on the
|
||||
// partial derivatives of the texture coordinates. This is a workaround that is only
|
||||
// expected to be needed until the bug is fixed in Metal; it is provided as an option
|
||||
// so it can be enabled only when the bug is present.
|
||||
bool sample_dref_lod_array_as_grad = false;
|
||||
|
||||
// MSL doesn't guarantee coherence between writes and subsequent reads of read_write textures.
|
||||
// This inserts fences before each read of a read_write texture to ensure coherency.
|
||||
// If you're sure you never rely on this, you can set this to false for a possible performance improvement.
|
||||
// Note: Only Apple's GPU compiler takes advantage of the lack of coherency, so make sure to test on Apple GPUs if you disable this.
|
||||
bool readwrite_texture_fences = true;
|
||||
|
||||
// Metal 3.1 introduced a Metal regression bug which causes infinite recursion during
|
||||
// Metal's analysis of an entry point input structure that is itself recursive. Enabling
|
||||
// this option will replace the recursive input declaration with a alternate variable of
|
||||
// type void*, and then cast to the correct type at the top of the entry point function.
|
||||
// The bug has been reported to Apple, and will hopefully be fixed in future releases.
|
||||
bool replace_recursive_inputs = false;
|
||||
|
||||
// If set, manual fixups of gradient vectors for cube texture lookups will be performed.
|
||||
// All released Apple Silicon GPUs to date behave incorrectly when sampling a cube texture
|
||||
// with explicit gradients. They will ignore one of the three partial derivatives based
|
||||
// on the selected major axis, and expect the remaining derivatives to be partially
|
||||
// transformed.
|
||||
bool agx_manual_cube_grad_fixup = false;
|
||||
|
||||
bool is_ios() const
|
||||
{
|
||||
return platform == iOS;
|
||||
@@ -445,6 +529,11 @@ public:
|
||||
return platform == macOS;
|
||||
}
|
||||
|
||||
bool use_quadgroup_operation() const
|
||||
{
|
||||
return is_ios() && !ios_use_simdgroup_functions;
|
||||
}
|
||||
|
||||
void set_msl_version(uint32_t major, uint32_t minor = 0, uint32_t patch = 0)
|
||||
{
|
||||
msl_version = make_msl_version(major, minor, patch);
|
||||
@@ -494,6 +583,11 @@ public:
|
||||
return !buffers_requiring_array_length.empty();
|
||||
}
|
||||
|
||||
bool buffer_requires_array_length(VariableID id) const
|
||||
{
|
||||
return buffers_requiring_array_length.count(id) != 0;
|
||||
}
|
||||
|
||||
// Provide feedback to calling API to allow it to pass a buffer
|
||||
// containing the view mask for the current multiview subpass.
|
||||
bool needs_view_mask_buffer() const
|
||||
@@ -534,10 +628,15 @@ public:
|
||||
explicit CompilerMSL(const ParsedIR &ir);
|
||||
explicit CompilerMSL(ParsedIR &&ir);
|
||||
|
||||
// input is a shader input description used to fix up shader input variables.
|
||||
// input is a shader interface variable description used to fix up shader input variables.
|
||||
// If shader inputs are provided, is_msl_shader_input_used() will return true after
|
||||
// calling ::compile() if the location was used by the MSL code.
|
||||
void add_msl_shader_input(const MSLShaderInput &input);
|
||||
// calling ::compile() if the location were used by the MSL code.
|
||||
void add_msl_shader_input(const MSLShaderInterfaceVariable &input);
|
||||
|
||||
// output is a shader interface variable description used to fix up shader output variables.
|
||||
// If shader outputs are provided, is_msl_shader_output_used() will return true after
|
||||
// calling ::compile() if the location were used by the MSL code.
|
||||
void add_msl_shader_output(const MSLShaderInterfaceVariable &output);
|
||||
|
||||
// resource is a resource binding to indicate the MSL buffer,
|
||||
// texture or sampler index to use for a particular SPIR-V description set
|
||||
@@ -572,6 +671,9 @@ public:
|
||||
// Query after compilation is done. This allows you to check if an input location was used by the shader.
|
||||
bool is_msl_shader_input_used(uint32_t location);
|
||||
|
||||
// Query after compilation is done. This allows you to check if an output location were used by the shader.
|
||||
bool is_msl_shader_output_used(uint32_t location);
|
||||
|
||||
// If not using add_msl_shader_input, it's possible
|
||||
// that certain builtin attributes need to be automatically assigned locations.
|
||||
// This is typical for tessellation builtin inputs such as tess levels, gl_Position, etc.
|
||||
@@ -579,6 +681,13 @@ public:
|
||||
// add_msl_shader_input or the builtin is not used, otherwise returns N in [[attribute(N)]].
|
||||
uint32_t get_automatic_builtin_input_location(spv::BuiltIn builtin) const;
|
||||
|
||||
// If not using add_msl_shader_output, it's possible
|
||||
// that certain builtin attributes need to be automatically assigned locations.
|
||||
// This is typical for tessellation builtin outputs such as tess levels, gl_Position, etc.
|
||||
// This returns k_unknown_location if the location were explicitly assigned with
|
||||
// add_msl_shader_output or the builtin were not used, otherwise returns N in [[attribute(N)]].
|
||||
uint32_t get_automatic_builtin_output_location(spv::BuiltIn builtin) const;
|
||||
|
||||
// NOTE: Only resources which are remapped using add_msl_resource_binding will be reported here.
|
||||
// Constexpr samplers are always assumed to be emitted.
|
||||
// No specific MSLResourceBinding remapping is required for constexpr samplers as long as they are remapped
|
||||
@@ -633,7 +742,7 @@ public:
|
||||
protected:
|
||||
// An enum of SPIR-V functions that are implemented in additional
|
||||
// source code that is added to the shader if necessary.
|
||||
enum SPVFuncImpl
|
||||
enum SPVFuncImpl : uint8_t
|
||||
{
|
||||
SPVFuncImplNone,
|
||||
SPVFuncImplMod,
|
||||
@@ -654,12 +763,14 @@ protected:
|
||||
SPVFuncImplArrayOfArrayCopy6Dim = SPVFuncImplArrayCopyMultidimBase + 6,
|
||||
SPVFuncImplTexelBufferCoords,
|
||||
SPVFuncImplImage2DAtomicCoords, // Emulate texture2D atomic operations
|
||||
SPVFuncImplGradientCube,
|
||||
SPVFuncImplFMul,
|
||||
SPVFuncImplFAdd,
|
||||
SPVFuncImplFSub,
|
||||
SPVFuncImplQuantizeToF16,
|
||||
SPVFuncImplCubemapTo2DArrayFace,
|
||||
SPVFuncImplUnsafeArray, // Allow Metal to use the array<T> template to make arrays a value type
|
||||
SPVFuncImplStorageMatrix, // Allow threadgroup construction of matrices
|
||||
SPVFuncImplInverse4x4,
|
||||
SPVFuncImplInverse3x3,
|
||||
SPVFuncImplInverse2x2,
|
||||
@@ -708,11 +819,18 @@ protected:
|
||||
SPVFuncImplConvertYCbCrBT601,
|
||||
SPVFuncImplConvertYCbCrBT2020,
|
||||
SPVFuncImplDynamicImageSampler,
|
||||
SPVFuncImplRayQueryIntersectionParams,
|
||||
SPVFuncImplVariableDescriptor,
|
||||
SPVFuncImplVariableSizedDescriptor,
|
||||
SPVFuncImplVariableDescriptorArray,
|
||||
SPVFuncImplPaddedStd140
|
||||
};
|
||||
|
||||
// If the underlying resource has been used for comparison then duplicate loads of that resource must be too
|
||||
// Use Metal's native frame-buffer fetch API for subpass inputs.
|
||||
void emit_texture_op(const Instruction &i, bool sparse) override;
|
||||
void emit_binary_ptr_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op);
|
||||
std::string to_ptr_expression(uint32_t id, bool register_expression_read = true);
|
||||
void emit_binary_unord_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op);
|
||||
void emit_instruction(const Instruction &instr) override;
|
||||
void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
@@ -731,6 +849,7 @@ protected:
|
||||
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||
const std::string &qualifier = "", uint32_t base_offset = 0) override;
|
||||
void emit_struct_padding_target(const SPIRType &type) override;
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id, bool member);
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
void emit_block_hints(const SPIRBlock &block) override;
|
||||
|
||||
@@ -738,9 +857,6 @@ protected:
|
||||
std::string type_to_array_glsl(const SPIRType &type) override;
|
||||
std::string constant_op_expression(const SPIRConstantOp &cop) override;
|
||||
|
||||
// Threadgroup arrays can't have a wrapper type
|
||||
std::string variable_decl(const SPIRVariable &variable) override;
|
||||
|
||||
bool variable_decl_is_remapped_storage(const SPIRVariable &variable, spv::StorageClass storage) const override;
|
||||
|
||||
// GCC workaround of lambdas calling protected functions (for older GCC versions)
|
||||
@@ -765,10 +881,9 @@ protected:
|
||||
std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override;
|
||||
bool emit_complex_bitcast(uint32_t result_id, uint32_t id, uint32_t op0) override;
|
||||
bool skip_argument(uint32_t id) const override;
|
||||
std::string to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain) override;
|
||||
std::string to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain_is_resolved) override;
|
||||
std::string to_qualifiers_glsl(uint32_t id) override;
|
||||
void replace_illegal_names() override;
|
||||
void declare_undefined_values() override;
|
||||
void declare_constant_arrays();
|
||||
|
||||
void replace_illegal_entry_point_names();
|
||||
@@ -784,13 +899,17 @@ protected:
|
||||
bool is_non_native_row_major_matrix(uint32_t id) override;
|
||||
bool member_is_non_native_row_major_matrix(const SPIRType &type, uint32_t index) override;
|
||||
std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type, uint32_t physical_type_id,
|
||||
bool is_packed) override;
|
||||
bool is_packed, bool relaxed) override;
|
||||
|
||||
bool is_tesc_shader() const;
|
||||
bool is_tese_shader() const;
|
||||
|
||||
void preprocess_op_codes();
|
||||
void localize_global_variables();
|
||||
void extract_global_variables_from_functions();
|
||||
void mark_packable_structs();
|
||||
void mark_as_packable(SPIRType &type);
|
||||
void mark_as_workgroup_struct(SPIRType &type);
|
||||
|
||||
std::unordered_map<uint32_t, std::set<uint32_t>> function_global_vars;
|
||||
void extract_global_variables_from_function(uint32_t func_id, std::set<uint32_t> &added_arg_ids,
|
||||
@@ -826,13 +945,22 @@ protected:
|
||||
bool add_component_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref,
|
||||
SPIRVariable &var, const SPIRType &type,
|
||||
InterfaceBlockMeta &meta);
|
||||
void add_plain_member_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref,
|
||||
SPIRType &ib_type, SPIRVariable &var, uint32_t index,
|
||||
InterfaceBlockMeta &meta);
|
||||
void add_composite_member_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref,
|
||||
SPIRType &ib_type, SPIRVariable &var, uint32_t index,
|
||||
InterfaceBlockMeta &meta);
|
||||
void add_plain_member_variable_to_interface_block(spv::StorageClass storage,
|
||||
const std::string &ib_var_ref, SPIRType &ib_type,
|
||||
SPIRVariable &var, SPIRType &var_type,
|
||||
uint32_t mbr_idx, InterfaceBlockMeta &meta,
|
||||
const std::string &mbr_name_qual,
|
||||
const std::string &var_chain_qual,
|
||||
uint32_t &location, uint32_t &var_mbr_idx);
|
||||
void add_composite_member_variable_to_interface_block(spv::StorageClass storage,
|
||||
const std::string &ib_var_ref, SPIRType &ib_type,
|
||||
SPIRVariable &var, SPIRType &var_type,
|
||||
uint32_t mbr_idx, InterfaceBlockMeta &meta,
|
||||
const std::string &mbr_name_qual,
|
||||
const std::string &var_chain_qual,
|
||||
uint32_t &location, uint32_t &var_mbr_idx);
|
||||
void add_tess_level_input_to_interface_block(const std::string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var);
|
||||
void add_tess_level_input(const std::string &base_ref, const std::string &mbr_name, SPIRVariable &var);
|
||||
|
||||
void fix_up_interface_member_indices(spv::StorageClass storage, uint32_t ib_type_id);
|
||||
|
||||
@@ -848,7 +976,8 @@ protected:
|
||||
void emit_specialization_constants_and_structs();
|
||||
void emit_interface_block(uint32_t ib_var_id);
|
||||
bool maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs);
|
||||
uint32_t get_resource_array_size(uint32_t id) const;
|
||||
bool is_var_runtime_size_array(const SPIRVariable &var) const;
|
||||
uint32_t get_resource_array_size(const SPIRType &type, uint32_t id) const;
|
||||
|
||||
void fix_up_shader_inputs_outputs();
|
||||
|
||||
@@ -858,7 +987,7 @@ protected:
|
||||
std::string entry_point_arg_stage_in();
|
||||
void entry_point_args_builtin(std::string &args);
|
||||
void entry_point_args_discrete_descriptors(std::string &args);
|
||||
std::string to_qualified_member_name(const SPIRType &type, uint32_t index);
|
||||
std::string append_member_name(const std::string &qualifier, const SPIRType &type, uint32_t index);
|
||||
std::string ensure_valid_name(std::string name, std::string pfx);
|
||||
std::string to_sampler_expression(uint32_t id);
|
||||
std::string to_swizzle_expression(uint32_t id);
|
||||
@@ -872,11 +1001,14 @@ protected:
|
||||
std::string member_attribute_qualifier(const SPIRType &type, uint32_t index);
|
||||
std::string member_location_attribute_qualifier(const SPIRType &type, uint32_t index);
|
||||
std::string argument_decl(const SPIRFunction::Parameter &arg);
|
||||
const char *descriptor_address_space(uint32_t id, spv::StorageClass storage, const char *plain_address_space) const;
|
||||
std::string round_fp_tex_coords(std::string tex_coords, bool coord_is_fp);
|
||||
uint32_t get_metal_resource_index(SPIRVariable &var, SPIRType::BaseType basetype, uint32_t plane = 0);
|
||||
uint32_t get_member_location(uint32_t type_id, uint32_t index, uint32_t *comp = nullptr) const;
|
||||
uint32_t get_or_allocate_builtin_input_member_location(spv::BuiltIn builtin,
|
||||
uint32_t type_id, uint32_t index, uint32_t *comp = nullptr);
|
||||
uint32_t get_or_allocate_builtin_output_member_location(spv::BuiltIn builtin,
|
||||
uint32_t type_id, uint32_t index, uint32_t *comp = nullptr);
|
||||
|
||||
uint32_t get_physical_tess_level_array_size(spv::BuiltIn builtin) const;
|
||||
|
||||
@@ -912,7 +1044,7 @@ protected:
|
||||
bool validate_member_packing_rules_msl(const SPIRType &type, uint32_t index) const;
|
||||
std::string get_argument_address_space(const SPIRVariable &argument);
|
||||
std::string get_type_address_space(const SPIRType &type, uint32_t id, bool argument = false);
|
||||
const char *to_restrict(uint32_t id, bool space = true);
|
||||
const char *to_restrict(uint32_t id, bool space);
|
||||
SPIRType &get_stage_in_struct_type();
|
||||
SPIRType &get_stage_out_struct_type();
|
||||
SPIRType &get_patch_stage_in_struct_type();
|
||||
@@ -920,14 +1052,14 @@ protected:
|
||||
std::string get_tess_factor_struct_name();
|
||||
SPIRType &get_uint_type();
|
||||
uint32_t get_uint_type_id();
|
||||
void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, uint32_t mem_order_1,
|
||||
uint32_t mem_order_2, bool has_mem_order_2, uint32_t op0, uint32_t op1 = 0,
|
||||
void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, spv::Op opcode,
|
||||
uint32_t mem_order_1, uint32_t mem_order_2, bool has_mem_order_2, uint32_t op0, uint32_t op1 = 0,
|
||||
bool op1_is_pointer = false, bool op1_is_literal = false, uint32_t op2 = 0);
|
||||
const char *get_memory_order(uint32_t spv_mem_sem);
|
||||
void add_pragma_line(const std::string &line);
|
||||
void add_typedef_line(const std::string &line);
|
||||
void emit_barrier(uint32_t id_exe_scope, uint32_t id_mem_scope, uint32_t id_mem_sem);
|
||||
void emit_array_copy(const std::string &lhs, uint32_t lhs_id, uint32_t rhs_id,
|
||||
bool emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rhs_id,
|
||||
spv::StorageClass lhs_storage, spv::StorageClass rhs_storage) override;
|
||||
void build_implicit_builtins();
|
||||
uint32_t build_constant_uint_array_pointer();
|
||||
@@ -937,6 +1069,7 @@ protected:
|
||||
uint32_t builtin_frag_coord_id = 0;
|
||||
uint32_t builtin_sample_id_id = 0;
|
||||
uint32_t builtin_sample_mask_id = 0;
|
||||
uint32_t builtin_helper_invocation_id = 0;
|
||||
uint32_t builtin_vertex_idx_id = 0;
|
||||
uint32_t builtin_base_vertex_id = 0;
|
||||
uint32_t builtin_instance_idx_id = 0;
|
||||
@@ -961,6 +1094,7 @@ protected:
|
||||
uint32_t argument_buffer_padding_sampler_type_id = 0;
|
||||
|
||||
bool does_shader_write_sample_mask = false;
|
||||
bool frag_shader_needs_discard_checks = false;
|
||||
|
||||
void cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
void cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
@@ -969,9 +1103,11 @@ protected:
|
||||
void analyze_sampled_image_usage();
|
||||
|
||||
bool access_chain_needs_stage_io_builtin_translation(uint32_t base) override;
|
||||
void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage,
|
||||
bool prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage,
|
||||
bool &is_packed) override;
|
||||
void fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t length);
|
||||
void check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type) override;
|
||||
|
||||
bool emit_tessellation_access_chain(const uint32_t *ops, uint32_t length);
|
||||
bool emit_tessellation_io_load(uint32_t result_type, uint32_t id, uint32_t ptr);
|
||||
bool is_out_of_bounds_tessellation_level(uint32_t id_lhs);
|
||||
@@ -985,12 +1121,17 @@ protected:
|
||||
Options msl_options;
|
||||
std::set<SPVFuncImpl> spv_function_implementations;
|
||||
// Must be ordered to ensure declarations are in a specific order.
|
||||
std::map<LocationComponentPair, MSLShaderInput> inputs_by_location;
|
||||
std::unordered_map<uint32_t, MSLShaderInput> inputs_by_builtin;
|
||||
std::map<LocationComponentPair, MSLShaderInterfaceVariable> inputs_by_location;
|
||||
std::unordered_map<uint32_t, MSLShaderInterfaceVariable> inputs_by_builtin;
|
||||
std::map<LocationComponentPair, MSLShaderInterfaceVariable> outputs_by_location;
|
||||
std::unordered_map<uint32_t, MSLShaderInterfaceVariable> outputs_by_builtin;
|
||||
std::unordered_set<uint32_t> location_inputs_in_use;
|
||||
std::unordered_set<uint32_t> location_inputs_in_use_fallback;
|
||||
std::unordered_set<uint32_t> location_outputs_in_use;
|
||||
std::unordered_set<uint32_t> location_outputs_in_use_fallback;
|
||||
std::unordered_map<uint32_t, uint32_t> fragment_output_components;
|
||||
std::unordered_map<uint32_t, uint32_t> builtin_to_automatic_input_location;
|
||||
std::unordered_map<uint32_t, uint32_t> builtin_to_automatic_output_location;
|
||||
std::set<std::string> pragma_lines;
|
||||
std::set<std::string> typedef_lines;
|
||||
SmallVector<uint32_t> vars_needing_early_declaration;
|
||||
@@ -1010,6 +1151,8 @@ protected:
|
||||
VariableID patch_stage_out_var_id = 0;
|
||||
VariableID stage_in_ptr_var_id = 0;
|
||||
VariableID stage_out_ptr_var_id = 0;
|
||||
VariableID tess_level_inner_var_id = 0;
|
||||
VariableID tess_level_outer_var_id = 0;
|
||||
VariableID stage_out_masked_builtin_type_id = 0;
|
||||
|
||||
// Handle HLSL-style 0-based vertex/instance index.
|
||||
@@ -1036,6 +1179,7 @@ protected:
|
||||
bool needs_subgroup_invocation_id = false;
|
||||
bool needs_subgroup_size = false;
|
||||
bool needs_sample_id = false;
|
||||
bool needs_helper_invocation = false;
|
||||
std::string qual_pos_var_name;
|
||||
std::string stage_in_var_name = "in";
|
||||
std::string stage_out_var_name = "out";
|
||||
@@ -1048,6 +1192,7 @@ protected:
|
||||
std::string input_wg_var_name = "gl_in";
|
||||
std::string input_buffer_var_name = "spvIn";
|
||||
std::string output_buffer_var_name = "spvOut";
|
||||
std::string patch_input_buffer_var_name = "spvPatchIn";
|
||||
std::string patch_output_buffer_var_name = "spvPatchOut";
|
||||
std::string tess_factor_buffer_var_name = "spvTessLevel";
|
||||
std::string index_buffer_var_name = "spvIndices";
|
||||
@@ -1059,9 +1204,13 @@ protected:
|
||||
const MSLConstexprSampler *find_constexpr_sampler(uint32_t id) const;
|
||||
|
||||
std::unordered_set<uint32_t> buffers_requiring_array_length;
|
||||
SmallVector<uint32_t> buffer_arrays;
|
||||
std::unordered_set<uint32_t> atomic_image_vars; // Emulate texture2D atomic operations
|
||||
SmallVector<std::pair<uint32_t, uint32_t>> buffer_aliases_argument;
|
||||
SmallVector<uint32_t> buffer_aliases_discrete;
|
||||
std::unordered_set<uint32_t> atomic_image_vars_emulated; // Emulate texture2D atomic operations
|
||||
std::unordered_set<uint32_t> pull_model_inputs;
|
||||
std::unordered_set<uint32_t> recursive_inputs;
|
||||
|
||||
SmallVector<SPIRVariable *> entry_point_bindings;
|
||||
|
||||
// Must be ordered since array is in a specific order.
|
||||
std::map<SetBindingPair, std::pair<uint32_t, uint32_t>> buffers_requiring_dynamic_offset;
|
||||
@@ -1100,6 +1249,16 @@ protected:
|
||||
|
||||
bool variable_storage_requires_stage_io(spv::StorageClass storage) const;
|
||||
|
||||
bool needs_manual_helper_invocation_updates() const
|
||||
{
|
||||
return msl_options.manual_helper_invocation_updates && msl_options.supports_msl_version(2, 3);
|
||||
}
|
||||
bool needs_frag_discard_checks() const
|
||||
{
|
||||
return get_execution_model() == spv::ExecutionModelFragment && msl_options.supports_msl_version(2, 3) &&
|
||||
msl_options.check_discarded_frag_stores && frag_shader_needs_discard_checks;
|
||||
}
|
||||
|
||||
bool has_additional_fixed_sample_mask() const { return msl_options.additional_fixed_sample_mask != 0xffffffff; }
|
||||
std::string additional_fixed_sample_mask_str() const;
|
||||
|
||||
@@ -1117,13 +1276,16 @@ protected:
|
||||
|
||||
CompilerMSL &compiler;
|
||||
std::unordered_map<uint32_t, uint32_t> result_types;
|
||||
std::unordered_map<uint32_t, uint32_t> image_pointers; // Emulate texture2D atomic operations
|
||||
std::unordered_map<uint32_t, uint32_t> image_pointers_emulated; // Emulate texture2D atomic operations
|
||||
bool suppress_missing_prototypes = false;
|
||||
bool uses_atomics = false;
|
||||
bool uses_resource_write = false;
|
||||
bool uses_image_write = false;
|
||||
bool uses_buffer_write = false;
|
||||
bool uses_discard = false;
|
||||
bool needs_subgroup_invocation_id = false;
|
||||
bool needs_subgroup_size = false;
|
||||
bool needs_sample_id = false;
|
||||
bool needs_helper_invocation = false;
|
||||
};
|
||||
|
||||
// OpcodeHandler that scans for uses of sampled images
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace SPIRV_CROSS_NAMESPACE
|
||||
{
|
||||
Parser::Parser(vector<uint32_t> spirv)
|
||||
{
|
||||
ir.spirv = move(spirv);
|
||||
ir.spirv = std::move(spirv);
|
||||
}
|
||||
|
||||
Parser::Parser(const uint32_t *spirv_data, size_t word_count)
|
||||
@@ -68,6 +68,7 @@ static bool is_valid_spirv_version(uint32_t version)
|
||||
case 0x10300: // SPIR-V 1.3
|
||||
case 0x10400: // SPIR-V 1.4
|
||||
case 0x10500: // SPIR-V 1.5
|
||||
case 0x10600: // SPIR-V 1.6
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -182,6 +183,15 @@ void Parser::parse(const Instruction &instruction)
|
||||
auto op = static_cast<Op>(instruction.op);
|
||||
uint32_t length = instruction.length;
|
||||
|
||||
// HACK for glslang that might emit OpEmitMeshTasksEXT followed by return / branch.
|
||||
// Instead of failing hard, just ignore it.
|
||||
if (ignore_trailing_block_opcodes)
|
||||
{
|
||||
ignore_trailing_block_opcodes = false;
|
||||
if (op == OpReturn || op == OpBranch || op == OpUnreachable)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case OpSourceContinued:
|
||||
@@ -258,29 +268,37 @@ void Parser::parse(const Instruction &instruction)
|
||||
case OpExtension:
|
||||
{
|
||||
auto ext = extract_string(ir.spirv, instruction.offset);
|
||||
ir.declared_extensions.push_back(move(ext));
|
||||
ir.declared_extensions.push_back(std::move(ext));
|
||||
break;
|
||||
}
|
||||
|
||||
case OpExtInstImport:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
|
||||
SPIRExtension::Extension spirv_ext = SPIRExtension::Unsupported;
|
||||
|
||||
auto ext = extract_string(ir.spirv, instruction.offset + 1);
|
||||
if (ext == "GLSL.std.450")
|
||||
set<SPIRExtension>(id, SPIRExtension::GLSL);
|
||||
spirv_ext = SPIRExtension::GLSL;
|
||||
else if (ext == "DebugInfo")
|
||||
set<SPIRExtension>(id, SPIRExtension::SPV_debug_info);
|
||||
spirv_ext = SPIRExtension::SPV_debug_info;
|
||||
else if (ext == "SPV_AMD_shader_ballot")
|
||||
set<SPIRExtension>(id, SPIRExtension::SPV_AMD_shader_ballot);
|
||||
spirv_ext = SPIRExtension::SPV_AMD_shader_ballot;
|
||||
else if (ext == "SPV_AMD_shader_explicit_vertex_parameter")
|
||||
set<SPIRExtension>(id, SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter);
|
||||
spirv_ext = SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter;
|
||||
else if (ext == "SPV_AMD_shader_trinary_minmax")
|
||||
set<SPIRExtension>(id, SPIRExtension::SPV_AMD_shader_trinary_minmax);
|
||||
spirv_ext = SPIRExtension::SPV_AMD_shader_trinary_minmax;
|
||||
else if (ext == "SPV_AMD_gcn_shader")
|
||||
set<SPIRExtension>(id, SPIRExtension::SPV_AMD_gcn_shader);
|
||||
else
|
||||
set<SPIRExtension>(id, SPIRExtension::Unsupported);
|
||||
spirv_ext = SPIRExtension::SPV_AMD_gcn_shader;
|
||||
else if (ext == "NonSemantic.DebugPrintf")
|
||||
spirv_ext = SPIRExtension::NonSemanticDebugPrintf;
|
||||
else if (ext == "NonSemantic.Shader.DebugInfo.100")
|
||||
spirv_ext = SPIRExtension::NonSemanticShaderDebugInfo;
|
||||
else if (ext.find("NonSemantic.") == 0)
|
||||
spirv_ext = SPIRExtension::NonSemanticGeneric;
|
||||
|
||||
set<SPIRExtension>(id, spirv_ext);
|
||||
// Other SPIR-V extensions which have ExtInstrs are currently not supported.
|
||||
|
||||
break;
|
||||
@@ -290,7 +308,15 @@ void Parser::parse(const Instruction &instruction)
|
||||
{
|
||||
// The SPIR-V debug information extended instructions might come at global scope.
|
||||
if (current_block)
|
||||
{
|
||||
current_block->ops.push_back(instruction);
|
||||
if (length >= 2)
|
||||
{
|
||||
const auto *type = maybe_get<SPIRType>(ops[0]);
|
||||
if (type)
|
||||
ir.load_type_width.insert({ ops[1], type->width });
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -338,12 +364,32 @@ void Parser::parse(const Instruction &instruction)
|
||||
execution.output_vertices = ops[2];
|
||||
break;
|
||||
|
||||
case ExecutionModeOutputPrimitivesEXT:
|
||||
execution.output_primitives = ops[2];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpExecutionModeId:
|
||||
{
|
||||
auto &execution = ir.entry_points[ops[0]];
|
||||
auto mode = static_cast<ExecutionMode>(ops[1]);
|
||||
execution.flags.set(mode);
|
||||
|
||||
if (mode == ExecutionModeLocalSizeId)
|
||||
{
|
||||
execution.workgroup_size.id_x = ops[2];
|
||||
execution.workgroup_size.id_y = ops[3];
|
||||
execution.workgroup_size.id_z = ops[4];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OpName:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
@@ -471,7 +517,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
case OpTypeVoid:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
type.basetype = SPIRType::Void;
|
||||
break;
|
||||
}
|
||||
@@ -479,7 +525,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
case OpTypeBool:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
type.basetype = SPIRType::Boolean;
|
||||
type.width = 1;
|
||||
break;
|
||||
@@ -489,7 +535,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
uint32_t width = ops[1];
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
if (width == 64)
|
||||
type.basetype = SPIRType::Double;
|
||||
else if (width == 32)
|
||||
@@ -507,7 +553,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
uint32_t id = ops[0];
|
||||
uint32_t width = ops[1];
|
||||
bool signedness = ops[2] != 0;
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
type.basetype = signedness ? to_signed_basetype(width) : to_unsigned_basetype(width);
|
||||
type.width = width;
|
||||
break;
|
||||
@@ -522,9 +568,9 @@ void Parser::parse(const Instruction &instruction)
|
||||
uint32_t vecsize = ops[2];
|
||||
|
||||
auto &base = get<SPIRType>(ops[1]);
|
||||
auto &vecbase = set<SPIRType>(id);
|
||||
auto &vecbase = set<SPIRType>(id, base);
|
||||
|
||||
vecbase = base;
|
||||
vecbase.op = op;
|
||||
vecbase.vecsize = vecsize;
|
||||
vecbase.self = id;
|
||||
vecbase.parent_type = ops[1];
|
||||
@@ -537,9 +583,9 @@ void Parser::parse(const Instruction &instruction)
|
||||
uint32_t colcount = ops[2];
|
||||
|
||||
auto &base = get<SPIRType>(ops[1]);
|
||||
auto &matrixbase = set<SPIRType>(id);
|
||||
auto &matrixbase = set<SPIRType>(id, base);
|
||||
|
||||
matrixbase = base;
|
||||
matrixbase.op = op;
|
||||
matrixbase.columns = colcount;
|
||||
matrixbase.self = id;
|
||||
matrixbase.parent_type = ops[1];
|
||||
@@ -549,12 +595,11 @@ void Parser::parse(const Instruction &instruction)
|
||||
case OpTypeArray:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &arraybase = set<SPIRType>(id);
|
||||
|
||||
uint32_t tid = ops[1];
|
||||
auto &base = get<SPIRType>(tid);
|
||||
auto &arraybase = set<SPIRType>(id, base);
|
||||
|
||||
arraybase = base;
|
||||
arraybase.op = op;
|
||||
arraybase.parent_type = tid;
|
||||
|
||||
uint32_t cid = ops[2];
|
||||
@@ -569,7 +614,9 @@ void Parser::parse(const Instruction &instruction)
|
||||
|
||||
arraybase.array_size_literal.push_back(literal);
|
||||
arraybase.array.push_back(literal ? c->scalar() : cid);
|
||||
// Do NOT set arraybase.self!
|
||||
|
||||
// .self resolves down to non-array/non-pointer type.
|
||||
arraybase.self = base.self;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -578,25 +625,27 @@ void Parser::parse(const Instruction &instruction)
|
||||
uint32_t id = ops[0];
|
||||
|
||||
auto &base = get<SPIRType>(ops[1]);
|
||||
auto &arraybase = set<SPIRType>(id);
|
||||
auto &arraybase = set<SPIRType>(id, base);
|
||||
|
||||
// We're copying type information into Array types, so we'll need a fixup for any physical pointer
|
||||
// references.
|
||||
if (base.forward_pointer)
|
||||
forward_pointer_fixups.push_back({ id, ops[1] });
|
||||
|
||||
arraybase = base;
|
||||
arraybase.op = op;
|
||||
arraybase.array.push_back(0);
|
||||
arraybase.array_size_literal.push_back(true);
|
||||
arraybase.parent_type = ops[1];
|
||||
// Do NOT set arraybase.self!
|
||||
|
||||
// .self resolves down to non-array/non-pointer type.
|
||||
arraybase.self = base.self;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpTypeImage:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
type.basetype = SPIRType::Image;
|
||||
type.image.type = ops[1];
|
||||
type.image.dim = static_cast<Dim>(ops[2]);
|
||||
@@ -613,7 +662,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
uint32_t imagetype = ops[1];
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
type = get<SPIRType>(imagetype);
|
||||
type.basetype = SPIRType::SampledImage;
|
||||
type.self = id;
|
||||
@@ -623,7 +672,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
case OpTypeSampler:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
type.basetype = SPIRType::Sampler;
|
||||
break;
|
||||
}
|
||||
@@ -636,10 +685,13 @@ void Parser::parse(const Instruction &instruction)
|
||||
// We won't be able to compile it, but we shouldn't crash when parsing.
|
||||
// We should be able to reflect.
|
||||
auto *base = maybe_get<SPIRType>(ops[2]);
|
||||
auto &ptrbase = set<SPIRType>(id);
|
||||
auto &ptrbase = set<SPIRType>(id, op);
|
||||
|
||||
if (base)
|
||||
{
|
||||
ptrbase = *base;
|
||||
ptrbase.op = op;
|
||||
}
|
||||
|
||||
ptrbase.pointer = true;
|
||||
ptrbase.pointer_depth++;
|
||||
@@ -660,7 +712,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
case OpTypeForwardPointer:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &ptrbase = set<SPIRType>(id);
|
||||
auto &ptrbase = set<SPIRType>(id, op);
|
||||
ptrbase.pointer = true;
|
||||
ptrbase.pointer_depth++;
|
||||
ptrbase.storage = static_cast<StorageClass>(ops[1]);
|
||||
@@ -675,7 +727,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
case OpTypeStruct:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
type.basetype = SPIRType::Struct;
|
||||
for (uint32_t i = 1; i < length; i++)
|
||||
type.member_types.push_back(ops[i]);
|
||||
@@ -724,7 +776,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
case OpTypeAccelerationStructureKHR:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
type.basetype = SPIRType::AccelerationStructure;
|
||||
break;
|
||||
}
|
||||
@@ -732,7 +784,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
case OpTypeRayQueryKHR:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &type = set<SPIRType>(id);
|
||||
auto &type = set<SPIRType>(id, op);
|
||||
type.basetype = SPIRType::RayQuery;
|
||||
break;
|
||||
}
|
||||
@@ -979,10 +1031,9 @@ void Parser::parse(const Instruction &instruction)
|
||||
{
|
||||
uint32_t ids = ir.increase_bound_by(2);
|
||||
|
||||
SPIRType type;
|
||||
auto &type = set<SPIRType>(ids, OpTypeInt);
|
||||
type.basetype = SPIRType::Int;
|
||||
type.width = 32;
|
||||
set<SPIRType>(ids, type);
|
||||
auto &c = set<SPIRConstant>(ids + 1, ids);
|
||||
|
||||
current_block->condition = c.self;
|
||||
@@ -993,7 +1044,16 @@ void Parser::parse(const Instruction &instruction)
|
||||
}
|
||||
else
|
||||
{
|
||||
ir.block_meta[current_block->next_block] &= ~ParsedIR::BLOCK_META_SELECTION_MERGE_BIT;
|
||||
// Collapse loops if we have to.
|
||||
bool collapsed_loop = current_block->true_block == current_block->merge_block &&
|
||||
current_block->merge == SPIRBlock::MergeLoop;
|
||||
|
||||
if (collapsed_loop)
|
||||
{
|
||||
ir.block_meta[current_block->merge_block] &= ~ParsedIR::BLOCK_META_LOOP_MERGE_BIT;
|
||||
ir.block_meta[current_block->continue_block] &= ~ParsedIR::BLOCK_META_CONTINUE_BIT;
|
||||
}
|
||||
|
||||
current_block->next_block = current_block->true_block;
|
||||
current_block->condition = 0;
|
||||
current_block->true_block = 0;
|
||||
@@ -1042,6 +1102,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
}
|
||||
|
||||
case OpKill:
|
||||
case OpTerminateInvocation:
|
||||
{
|
||||
if (!current_block)
|
||||
SPIRV_CROSS_THROW("Trying to end a non-existing block.");
|
||||
@@ -1066,6 +1127,18 @@ void Parser::parse(const Instruction &instruction)
|
||||
current_block = nullptr;
|
||||
break;
|
||||
|
||||
case OpEmitMeshTasksEXT:
|
||||
if (!current_block)
|
||||
SPIRV_CROSS_THROW("Trying to end a non-existing block.");
|
||||
current_block->terminator = SPIRBlock::EmitMeshTasks;
|
||||
for (uint32_t i = 0; i < 3; i++)
|
||||
current_block->mesh.groups[i] = ops[i];
|
||||
current_block->mesh.payload = length >= 4 ? ops[3] : 0;
|
||||
current_block = nullptr;
|
||||
// Currently glslang is bugged and does not treat EmitMeshTasksEXT as a terminator.
|
||||
ignore_trailing_block_opcodes = true;
|
||||
break;
|
||||
|
||||
case OpReturn:
|
||||
{
|
||||
if (!current_block)
|
||||
@@ -1194,10 +1267,9 @@ void Parser::parse(const Instruction &instruction)
|
||||
{
|
||||
const auto *type = maybe_get<SPIRType>(ops[0]);
|
||||
if (type)
|
||||
{
|
||||
ir.load_type_width.insert({ ops[1], type->width });
|
||||
}
|
||||
}
|
||||
|
||||
if (!current_block)
|
||||
SPIRV_CROSS_THROW("Currently no block to insert opcode.");
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ private:
|
||||
ParsedIR ir;
|
||||
SPIRFunction *current_function = nullptr;
|
||||
SPIRBlock *current_block = nullptr;
|
||||
// For workarounds.
|
||||
bool ignore_trailing_block_opcodes = false;
|
||||
|
||||
void parse(const Instruction &instr);
|
||||
const uint32_t *stream(const Instruction &instr) const;
|
||||
|
||||
@@ -291,8 +291,8 @@ static bool naturally_emit_type(const SPIRType &type)
|
||||
bool CompilerReflection::type_is_reference(const SPIRType &type) const
|
||||
{
|
||||
// Physical pointers and arrays of physical pointers need to refer to the pointee's type.
|
||||
return type_is_top_level_physical_pointer(type) ||
|
||||
(!type.array.empty() && type_is_top_level_physical_pointer(get<SPIRType>(type.parent_type)));
|
||||
return is_physical_pointer(type) ||
|
||||
(type_is_array_of_pointers(type) && type.storage == StorageClassPhysicalStorageBuffer);
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_types()
|
||||
@@ -341,7 +341,7 @@ void CompilerReflection::emit_type(uint32_t type_id, bool &emitted_open_tag)
|
||||
json_stream->emit_json_key_object("_" + std::to_string(type_id));
|
||||
json_stream->emit_json_key_value("name", name);
|
||||
|
||||
if (type_is_top_level_physical_pointer(type))
|
||||
if (is_physical_pointer(type))
|
||||
{
|
||||
json_stream->emit_json_key_value("type", "_" + std::to_string(type.parent_type));
|
||||
json_stream->emit_json_key_value("physical_pointer", true);
|
||||
@@ -404,7 +404,7 @@ void CompilerReflection::emit_type_member(const SPIRType &type, uint32_t index)
|
||||
|
||||
void CompilerReflection::emit_type_array(const SPIRType &type)
|
||||
{
|
||||
if (!type_is_top_level_physical_pointer(type) && !type.array.empty())
|
||||
if (!is_physical_pointer(type) && !type.array.empty())
|
||||
{
|
||||
json_stream->emit_json_key_array("array");
|
||||
// Note that we emit the zeros here as a means of identifying
|
||||
@@ -444,7 +444,7 @@ void CompilerReflection::emit_type_member_qualifiers(const SPIRType &type, uint3
|
||||
if (dec.decoration_flags.get(DecorationRowMajor))
|
||||
json_stream->emit_json_key_value("row_major", true);
|
||||
|
||||
if (type_is_top_level_physical_pointer(membertype))
|
||||
if (is_physical_pointer(membertype))
|
||||
json_stream->emit_json_key_value("physical_pointer", true);
|
||||
}
|
||||
}
|
||||
@@ -587,18 +587,18 @@ void CompilerReflection::emit_resources(const char *tag, const SmallVector<Resou
|
||||
{
|
||||
bool ssbo_block = type.storage == StorageClassStorageBuffer ||
|
||||
(type.storage == StorageClassUniform && typeflags.get(DecorationBufferBlock));
|
||||
if (ssbo_block)
|
||||
{
|
||||
auto buffer_flags = get_buffer_block_flags(res.id);
|
||||
if (buffer_flags.get(DecorationNonReadable))
|
||||
json_stream->emit_json_key_value("writeonly", true);
|
||||
if (buffer_flags.get(DecorationNonWritable))
|
||||
json_stream->emit_json_key_value("readonly", true);
|
||||
if (buffer_flags.get(DecorationRestrict))
|
||||
json_stream->emit_json_key_value("restrict", true);
|
||||
if (buffer_flags.get(DecorationCoherent))
|
||||
json_stream->emit_json_key_value("coherent", true);
|
||||
}
|
||||
Bitset qualifier_mask = ssbo_block ? get_buffer_block_flags(res.id) : mask;
|
||||
|
||||
if (qualifier_mask.get(DecorationNonReadable))
|
||||
json_stream->emit_json_key_value("writeonly", true);
|
||||
if (qualifier_mask.get(DecorationNonWritable))
|
||||
json_stream->emit_json_key_value("readonly", true);
|
||||
if (qualifier_mask.get(DecorationRestrict))
|
||||
json_stream->emit_json_key_value("restrict", true);
|
||||
if (qualifier_mask.get(DecorationCoherent))
|
||||
json_stream->emit_json_key_value("coherent", true);
|
||||
if (qualifier_mask.get(DecorationVolatile))
|
||||
json_stream->emit_json_key_value("volatile", true);
|
||||
}
|
||||
|
||||
emit_type_array(type);
|
||||
|
||||
Reference in New Issue
Block a user