mirror of
https://github.com/love2d/love.git
synced 2026-08-19 04:06:17 +02:00
update spirv-cross
This commit is contained in:
@@ -54,11 +54,11 @@
|
||||
typedef unsigned int SpvId;
|
||||
|
||||
#define SPV_VERSION 0x10500
|
||||
#define SPV_REVISION 3
|
||||
#define SPV_REVISION 4
|
||||
|
||||
static const unsigned int SpvMagicNumber = 0x07230203;
|
||||
static const unsigned int SpvVersion = 0x00010500;
|
||||
static const unsigned int SpvRevision = 3;
|
||||
static const unsigned int SpvRevision = 4;
|
||||
static const unsigned int SpvOpCodeMask = 0xffff;
|
||||
static const unsigned int SpvWordCountShift = 16;
|
||||
|
||||
@@ -172,6 +172,10 @@ typedef enum SpvExecutionMode_ {
|
||||
SpvExecutionModeSampleInterlockUnorderedEXT = 5369,
|
||||
SpvExecutionModeShadingRateInterlockOrderedEXT = 5370,
|
||||
SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371,
|
||||
SpvExecutionModeMaxWorkgroupSizeINTEL = 5893,
|
||||
SpvExecutionModeMaxWorkDimINTEL = 5894,
|
||||
SpvExecutionModeNoGlobalOffsetINTEL = 5895,
|
||||
SpvExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
||||
SpvExecutionModeMax = 0x7fffffff,
|
||||
} SpvExecutionMode;
|
||||
|
||||
@@ -203,6 +207,7 @@ typedef enum SpvStorageClass_ {
|
||||
SpvStorageClassShaderRecordBufferNV = 5343,
|
||||
SpvStorageClassPhysicalStorageBuffer = 5349,
|
||||
SpvStorageClassPhysicalStorageBufferEXT = 5349,
|
||||
SpvStorageClassCodeSectionINTEL = 5605,
|
||||
SpvStorageClassMax = 0x7fffffff,
|
||||
} SpvStorageClass;
|
||||
|
||||
@@ -273,6 +278,8 @@ typedef enum SpvImageFormat_ {
|
||||
SpvImageFormatRg8ui = 37,
|
||||
SpvImageFormatR16ui = 38,
|
||||
SpvImageFormatR8ui = 39,
|
||||
SpvImageFormatR64ui = 40,
|
||||
SpvImageFormatR64i = 41,
|
||||
SpvImageFormatMax = 0x7fffffff,
|
||||
} SpvImageFormat;
|
||||
|
||||
@@ -481,11 +488,24 @@ typedef enum SpvDecoration_ {
|
||||
SpvDecorationRestrictPointerEXT = 5355,
|
||||
SpvDecorationAliasedPointer = 5356,
|
||||
SpvDecorationAliasedPointerEXT = 5356,
|
||||
SpvDecorationReferencedIndirectlyINTEL = 5602,
|
||||
SpvDecorationCounterBuffer = 5634,
|
||||
SpvDecorationHlslCounterBufferGOOGLE = 5634,
|
||||
SpvDecorationHlslSemanticGOOGLE = 5635,
|
||||
SpvDecorationUserSemantic = 5635,
|
||||
SpvDecorationUserTypeGOOGLE = 5636,
|
||||
SpvDecorationRegisterINTEL = 5825,
|
||||
SpvDecorationMemoryINTEL = 5826,
|
||||
SpvDecorationNumbanksINTEL = 5827,
|
||||
SpvDecorationBankwidthINTEL = 5828,
|
||||
SpvDecorationMaxPrivateCopiesINTEL = 5829,
|
||||
SpvDecorationSinglepumpINTEL = 5830,
|
||||
SpvDecorationDoublepumpINTEL = 5831,
|
||||
SpvDecorationMaxReplicatesINTEL = 5832,
|
||||
SpvDecorationSimpleDualPortINTEL = 5833,
|
||||
SpvDecorationMergeINTEL = 5834,
|
||||
SpvDecorationBankBitsINTEL = 5835,
|
||||
SpvDecorationForcePow2DepthINTEL = 5836,
|
||||
SpvDecorationMax = 0x7fffffff,
|
||||
} SpvDecoration;
|
||||
|
||||
@@ -544,8 +564,10 @@ typedef enum SpvBuiltIn_ {
|
||||
SpvBuiltInBaseVertex = 4424,
|
||||
SpvBuiltInBaseInstance = 4425,
|
||||
SpvBuiltInDrawIndex = 4426,
|
||||
SpvBuiltInPrimitiveShadingRateKHR = 4432,
|
||||
SpvBuiltInDeviceIndex = 4438,
|
||||
SpvBuiltInViewIndex = 4440,
|
||||
SpvBuiltInShadingRateKHR = 4444,
|
||||
SpvBuiltInBaryCoordNoPerspAMD = 4992,
|
||||
SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993,
|
||||
SpvBuiltInBaryCoordNoPerspSampleAMD = 4994,
|
||||
@@ -596,7 +618,6 @@ typedef enum SpvBuiltIn_ {
|
||||
SpvBuiltInObjectToWorldNV = 5330,
|
||||
SpvBuiltInWorldToObjectKHR = 5331,
|
||||
SpvBuiltInWorldToObjectNV = 5331,
|
||||
SpvBuiltInHitTKHR = 5332,
|
||||
SpvBuiltInHitTNV = 5332,
|
||||
SpvBuiltInHitKindKHR = 5333,
|
||||
SpvBuiltInHitKindNV = 5333,
|
||||
@@ -632,6 +653,13 @@ typedef enum SpvLoopControlShift_ {
|
||||
SpvLoopControlIterationMultipleShift = 6,
|
||||
SpvLoopControlPeelCountShift = 7,
|
||||
SpvLoopControlPartialCountShift = 8,
|
||||
SpvLoopControlInitiationIntervalINTELShift = 16,
|
||||
SpvLoopControlMaxConcurrencyINTELShift = 17,
|
||||
SpvLoopControlDependencyArrayINTELShift = 18,
|
||||
SpvLoopControlPipelineEnableINTELShift = 19,
|
||||
SpvLoopControlLoopCoalesceINTELShift = 20,
|
||||
SpvLoopControlMaxInterleavingINTELShift = 21,
|
||||
SpvLoopControlSpeculatedIterationsINTELShift = 22,
|
||||
SpvLoopControlMax = 0x7fffffff,
|
||||
} SpvLoopControlShift;
|
||||
|
||||
@@ -646,6 +674,13 @@ typedef enum SpvLoopControlMask_ {
|
||||
SpvLoopControlIterationMultipleMask = 0x00000040,
|
||||
SpvLoopControlPeelCountMask = 0x00000080,
|
||||
SpvLoopControlPartialCountMask = 0x00000100,
|
||||
SpvLoopControlInitiationIntervalINTELMask = 0x00010000,
|
||||
SpvLoopControlMaxConcurrencyINTELMask = 0x00020000,
|
||||
SpvLoopControlDependencyArrayINTELMask = 0x00040000,
|
||||
SpvLoopControlPipelineEnableINTELMask = 0x00080000,
|
||||
SpvLoopControlLoopCoalesceINTELMask = 0x00100000,
|
||||
SpvLoopControlMaxInterleavingINTELMask = 0x00200000,
|
||||
SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000,
|
||||
} SpvLoopControlMask;
|
||||
|
||||
typedef enum SpvFunctionControlShift_ {
|
||||
@@ -842,6 +877,7 @@ typedef enum SpvCapability_ {
|
||||
SpvCapabilityGroupNonUniformQuad = 68,
|
||||
SpvCapabilityShaderLayer = 69,
|
||||
SpvCapabilityShaderViewportIndex = 70,
|
||||
SpvCapabilityFragmentShadingRateKHR = 4422,
|
||||
SpvCapabilitySubgroupBallotKHR = 4423,
|
||||
SpvCapabilityDrawParameters = 4427,
|
||||
SpvCapabilitySubgroupVoteKHR = 4431,
|
||||
@@ -866,12 +902,15 @@ typedef enum SpvCapability_ {
|
||||
SpvCapabilityRoundingModeRTE = 4467,
|
||||
SpvCapabilityRoundingModeRTZ = 4468,
|
||||
SpvCapabilityRayQueryProvisionalKHR = 4471,
|
||||
SpvCapabilityRayTraversalPrimitiveCullingProvisionalKHR = 4478,
|
||||
SpvCapabilityRayQueryKHR = 4472,
|
||||
SpvCapabilityRayTraversalPrimitiveCullingKHR = 4478,
|
||||
SpvCapabilityRayTracingKHR = 4479,
|
||||
SpvCapabilityFloat16ImageAMD = 5008,
|
||||
SpvCapabilityImageGatherBiasLodAMD = 5009,
|
||||
SpvCapabilityFragmentMaskAMD = 5010,
|
||||
SpvCapabilityStencilExportEXT = 5013,
|
||||
SpvCapabilityImageReadWriteLodAMD = 5015,
|
||||
SpvCapabilityInt64ImageEXT = 5016,
|
||||
SpvCapabilityShaderClockKHR = 5055,
|
||||
SpvCapabilitySampleMaskOverrideCoverageNV = 5249,
|
||||
SpvCapabilityGeometryShaderPassthroughNV = 5251,
|
||||
@@ -932,9 +971,20 @@ typedef enum SpvCapability_ {
|
||||
SpvCapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||
SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579,
|
||||
SpvCapabilityIntegerFunctions2INTEL = 5584,
|
||||
SpvCapabilityFunctionPointersINTEL = 5603,
|
||||
SpvCapabilityIndirectReferencesINTEL = 5604,
|
||||
SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696,
|
||||
SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
|
||||
SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
|
||||
SpvCapabilityFPGAMemoryAttributesINTEL = 5824,
|
||||
SpvCapabilityUnstructuredLoopControlsINTEL = 5886,
|
||||
SpvCapabilityFPGALoopControlsINTEL = 5888,
|
||||
SpvCapabilityKernelAttributesINTEL = 5892,
|
||||
SpvCapabilityFPGAKernelAttributesINTEL = 5897,
|
||||
SpvCapabilityBlockingPipesINTEL = 5945,
|
||||
SpvCapabilityFPGARegINTEL = 5948,
|
||||
SpvCapabilityAtomicFloat32AddEXT = 6033,
|
||||
SpvCapabilityAtomicFloat64AddEXT = 6034,
|
||||
SpvCapabilityMax = 0x7fffffff,
|
||||
} SpvCapability;
|
||||
|
||||
@@ -985,6 +1035,22 @@ typedef enum SpvRayQueryCandidateIntersectionType_ {
|
||||
SpvRayQueryCandidateIntersectionTypeMax = 0x7fffffff,
|
||||
} SpvRayQueryCandidateIntersectionType;
|
||||
|
||||
typedef enum SpvFragmentShadingRateShift_ {
|
||||
SpvFragmentShadingRateVertical2PixelsShift = 0,
|
||||
SpvFragmentShadingRateVertical4PixelsShift = 1,
|
||||
SpvFragmentShadingRateHorizontal2PixelsShift = 2,
|
||||
SpvFragmentShadingRateHorizontal4PixelsShift = 3,
|
||||
SpvFragmentShadingRateMax = 0x7fffffff,
|
||||
} SpvFragmentShadingRateShift;
|
||||
|
||||
typedef enum SpvFragmentShadingRateMask_ {
|
||||
SpvFragmentShadingRateMaskNone = 0,
|
||||
SpvFragmentShadingRateVertical2PixelsMask = 0x00000001,
|
||||
SpvFragmentShadingRateVertical4PixelsMask = 0x00000002,
|
||||
SpvFragmentShadingRateHorizontal2PixelsMask = 0x00000004,
|
||||
SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008,
|
||||
} SpvFragmentShadingRateMask;
|
||||
|
||||
typedef enum SpvOp_ {
|
||||
SpvOpNop = 0,
|
||||
SpvOpUndef = 1,
|
||||
@@ -1330,13 +1396,19 @@ typedef enum SpvOp_ {
|
||||
SpvOpPtrEqual = 401,
|
||||
SpvOpPtrNotEqual = 402,
|
||||
SpvOpPtrDiff = 403,
|
||||
SpvOpTerminateInvocation = 4416,
|
||||
SpvOpSubgroupBallotKHR = 4421,
|
||||
SpvOpSubgroupFirstInvocationKHR = 4422,
|
||||
SpvOpSubgroupAllKHR = 4428,
|
||||
SpvOpSubgroupAnyKHR = 4429,
|
||||
SpvOpSubgroupAllEqualKHR = 4430,
|
||||
SpvOpSubgroupReadInvocationKHR = 4432,
|
||||
SpvOpTypeRayQueryProvisionalKHR = 4472,
|
||||
SpvOpTraceRayKHR = 4445,
|
||||
SpvOpExecuteCallableKHR = 4446,
|
||||
SpvOpConvertUToAccelerationStructureKHR = 4447,
|
||||
SpvOpIgnoreIntersectionKHR = 4448,
|
||||
SpvOpTerminateRayKHR = 4449,
|
||||
SpvOpTypeRayQueryKHR = 4472,
|
||||
SpvOpRayQueryInitializeKHR = 4473,
|
||||
SpvOpRayQueryTerminateKHR = 4474,
|
||||
SpvOpRayQueryGenerateIntersectionKHR = 4475,
|
||||
@@ -1359,15 +1431,11 @@ typedef enum SpvOp_ {
|
||||
SpvOpWritePackedPrimitiveIndices4x8NV = 5299,
|
||||
SpvOpReportIntersectionKHR = 5334,
|
||||
SpvOpReportIntersectionNV = 5334,
|
||||
SpvOpIgnoreIntersectionKHR = 5335,
|
||||
SpvOpIgnoreIntersectionNV = 5335,
|
||||
SpvOpTerminateRayKHR = 5336,
|
||||
SpvOpTerminateRayNV = 5336,
|
||||
SpvOpTraceNV = 5337,
|
||||
SpvOpTraceRayKHR = 5337,
|
||||
SpvOpTypeAccelerationStructureKHR = 5341,
|
||||
SpvOpTypeAccelerationStructureNV = 5341,
|
||||
SpvOpExecuteCallableKHR = 5344,
|
||||
SpvOpExecuteCallableNV = 5344,
|
||||
SpvOpTypeCooperativeMatrixNV = 5358,
|
||||
SpvOpCooperativeMatrixLoadNV = 5359,
|
||||
@@ -1402,6 +1470,8 @@ typedef enum SpvOp_ {
|
||||
SpvOpUSubSatINTEL = 5596,
|
||||
SpvOpIMul32x16INTEL = 5597,
|
||||
SpvOpUMul32x16INTEL = 5598,
|
||||
SpvOpFunctionPointerINTEL = 5600,
|
||||
SpvOpFunctionPointerCallINTEL = 5601,
|
||||
SpvOpDecorateString = 5632,
|
||||
SpvOpDecorateStringGOOGLE = 5632,
|
||||
SpvOpMemberDecorateString = 5633,
|
||||
@@ -1524,6 +1594,10 @@ typedef enum SpvOp_ {
|
||||
SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
|
||||
SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
|
||||
SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
|
||||
SpvOpLoopControlINTEL = 5887,
|
||||
SpvOpReadPipeBlockingINTEL = 5946,
|
||||
SpvOpWritePipeBlockingINTEL = 5947,
|
||||
SpvOpFPGARegINTEL = 5949,
|
||||
SpvOpRayQueryGetRayTMinKHR = 6016,
|
||||
SpvOpRayQueryGetRayFlagsKHR = 6017,
|
||||
SpvOpRayQueryGetIntersectionTKHR = 6018,
|
||||
@@ -1541,6 +1615,7 @@ typedef enum SpvOp_ {
|
||||
SpvOpRayQueryGetWorldRayOriginKHR = 6030,
|
||||
SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031,
|
||||
SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032,
|
||||
SpvOpAtomicFAddEXT = 6035,
|
||||
SpvOpMax = 0x7fffffff,
|
||||
} SpvOp;
|
||||
|
||||
@@ -1893,13 +1968,19 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpTerminateInvocation: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpTypeRayQueryProvisionalKHR: *hasResult = true; *hasResultType = false; 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 SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
|
||||
case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break;
|
||||
@@ -1959,6 +2040,8 @@ 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 SpvOpFunctionPointerCallINTEL: *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;
|
||||
@@ -2079,6 +2162,10 @@ 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 SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break;
|
||||
@@ -2096,6 +2183,7 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
|
||||
}
|
||||
}
|
||||
#endif /* SPV_ENABLE_UTILITY_CODE */
|
||||
|
||||
@@ -50,11 +50,11 @@ namespace spv {
|
||||
typedef unsigned int Id;
|
||||
|
||||
#define SPV_VERSION 0x10500
|
||||
#define SPV_REVISION 3
|
||||
#define SPV_REVISION 4
|
||||
|
||||
static const unsigned int MagicNumber = 0x07230203;
|
||||
static const unsigned int Version = 0x00010500;
|
||||
static const unsigned int Revision = 3;
|
||||
static const unsigned int Revision = 4;
|
||||
static const unsigned int OpCodeMask = 0xffff;
|
||||
static const unsigned int WordCountShift = 16;
|
||||
|
||||
@@ -168,6 +168,10 @@ enum ExecutionMode {
|
||||
ExecutionModeSampleInterlockUnorderedEXT = 5369,
|
||||
ExecutionModeShadingRateInterlockOrderedEXT = 5370,
|
||||
ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
|
||||
ExecutionModeMaxWorkgroupSizeINTEL = 5893,
|
||||
ExecutionModeMaxWorkDimINTEL = 5894,
|
||||
ExecutionModeNoGlobalOffsetINTEL = 5895,
|
||||
ExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
||||
ExecutionModeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -199,6 +203,7 @@ enum StorageClass {
|
||||
StorageClassShaderRecordBufferNV = 5343,
|
||||
StorageClassPhysicalStorageBuffer = 5349,
|
||||
StorageClassPhysicalStorageBufferEXT = 5349,
|
||||
StorageClassCodeSectionINTEL = 5605,
|
||||
StorageClassMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -269,6 +274,8 @@ enum ImageFormat {
|
||||
ImageFormatRg8ui = 37,
|
||||
ImageFormatR16ui = 38,
|
||||
ImageFormatR8ui = 39,
|
||||
ImageFormatR64ui = 40,
|
||||
ImageFormatR64i = 41,
|
||||
ImageFormatMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -477,11 +484,24 @@ enum Decoration {
|
||||
DecorationRestrictPointerEXT = 5355,
|
||||
DecorationAliasedPointer = 5356,
|
||||
DecorationAliasedPointerEXT = 5356,
|
||||
DecorationReferencedIndirectlyINTEL = 5602,
|
||||
DecorationCounterBuffer = 5634,
|
||||
DecorationHlslCounterBufferGOOGLE = 5634,
|
||||
DecorationHlslSemanticGOOGLE = 5635,
|
||||
DecorationUserSemantic = 5635,
|
||||
DecorationUserTypeGOOGLE = 5636,
|
||||
DecorationRegisterINTEL = 5825,
|
||||
DecorationMemoryINTEL = 5826,
|
||||
DecorationNumbanksINTEL = 5827,
|
||||
DecorationBankwidthINTEL = 5828,
|
||||
DecorationMaxPrivateCopiesINTEL = 5829,
|
||||
DecorationSinglepumpINTEL = 5830,
|
||||
DecorationDoublepumpINTEL = 5831,
|
||||
DecorationMaxReplicatesINTEL = 5832,
|
||||
DecorationSimpleDualPortINTEL = 5833,
|
||||
DecorationMergeINTEL = 5834,
|
||||
DecorationBankBitsINTEL = 5835,
|
||||
DecorationForcePow2DepthINTEL = 5836,
|
||||
DecorationMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -540,8 +560,10 @@ enum BuiltIn {
|
||||
BuiltInBaseVertex = 4424,
|
||||
BuiltInBaseInstance = 4425,
|
||||
BuiltInDrawIndex = 4426,
|
||||
BuiltInPrimitiveShadingRateKHR = 4432,
|
||||
BuiltInDeviceIndex = 4438,
|
||||
BuiltInViewIndex = 4440,
|
||||
BuiltInShadingRateKHR = 4444,
|
||||
BuiltInBaryCoordNoPerspAMD = 4992,
|
||||
BuiltInBaryCoordNoPerspCentroidAMD = 4993,
|
||||
BuiltInBaryCoordNoPerspSampleAMD = 4994,
|
||||
@@ -592,7 +614,6 @@ enum BuiltIn {
|
||||
BuiltInObjectToWorldNV = 5330,
|
||||
BuiltInWorldToObjectKHR = 5331,
|
||||
BuiltInWorldToObjectNV = 5331,
|
||||
BuiltInHitTKHR = 5332,
|
||||
BuiltInHitTNV = 5332,
|
||||
BuiltInHitKindKHR = 5333,
|
||||
BuiltInHitKindNV = 5333,
|
||||
@@ -628,6 +649,13 @@ enum LoopControlShift {
|
||||
LoopControlIterationMultipleShift = 6,
|
||||
LoopControlPeelCountShift = 7,
|
||||
LoopControlPartialCountShift = 8,
|
||||
LoopControlInitiationIntervalINTELShift = 16,
|
||||
LoopControlMaxConcurrencyINTELShift = 17,
|
||||
LoopControlDependencyArrayINTELShift = 18,
|
||||
LoopControlPipelineEnableINTELShift = 19,
|
||||
LoopControlLoopCoalesceINTELShift = 20,
|
||||
LoopControlMaxInterleavingINTELShift = 21,
|
||||
LoopControlSpeculatedIterationsINTELShift = 22,
|
||||
LoopControlMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -642,6 +670,13 @@ enum LoopControlMask {
|
||||
LoopControlIterationMultipleMask = 0x00000040,
|
||||
LoopControlPeelCountMask = 0x00000080,
|
||||
LoopControlPartialCountMask = 0x00000100,
|
||||
LoopControlInitiationIntervalINTELMask = 0x00010000,
|
||||
LoopControlMaxConcurrencyINTELMask = 0x00020000,
|
||||
LoopControlDependencyArrayINTELMask = 0x00040000,
|
||||
LoopControlPipelineEnableINTELMask = 0x00080000,
|
||||
LoopControlLoopCoalesceINTELMask = 0x00100000,
|
||||
LoopControlMaxInterleavingINTELMask = 0x00200000,
|
||||
LoopControlSpeculatedIterationsINTELMask = 0x00400000,
|
||||
};
|
||||
|
||||
enum FunctionControlShift {
|
||||
@@ -838,6 +873,7 @@ enum Capability {
|
||||
CapabilityGroupNonUniformQuad = 68,
|
||||
CapabilityShaderLayer = 69,
|
||||
CapabilityShaderViewportIndex = 70,
|
||||
CapabilityFragmentShadingRateKHR = 4422,
|
||||
CapabilitySubgroupBallotKHR = 4423,
|
||||
CapabilityDrawParameters = 4427,
|
||||
CapabilitySubgroupVoteKHR = 4431,
|
||||
@@ -862,12 +898,15 @@ enum Capability {
|
||||
CapabilityRoundingModeRTE = 4467,
|
||||
CapabilityRoundingModeRTZ = 4468,
|
||||
CapabilityRayQueryProvisionalKHR = 4471,
|
||||
CapabilityRayTraversalPrimitiveCullingProvisionalKHR = 4478,
|
||||
CapabilityRayQueryKHR = 4472,
|
||||
CapabilityRayTraversalPrimitiveCullingKHR = 4478,
|
||||
CapabilityRayTracingKHR = 4479,
|
||||
CapabilityFloat16ImageAMD = 5008,
|
||||
CapabilityImageGatherBiasLodAMD = 5009,
|
||||
CapabilityFragmentMaskAMD = 5010,
|
||||
CapabilityStencilExportEXT = 5013,
|
||||
CapabilityImageReadWriteLodAMD = 5015,
|
||||
CapabilityInt64ImageEXT = 5016,
|
||||
CapabilityShaderClockKHR = 5055,
|
||||
CapabilitySampleMaskOverrideCoverageNV = 5249,
|
||||
CapabilityGeometryShaderPassthroughNV = 5251,
|
||||
@@ -928,9 +967,20 @@ enum Capability {
|
||||
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||
CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
|
||||
CapabilityIntegerFunctions2INTEL = 5584,
|
||||
CapabilityFunctionPointersINTEL = 5603,
|
||||
CapabilityIndirectReferencesINTEL = 5604,
|
||||
CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
|
||||
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
|
||||
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
|
||||
CapabilityFPGAMemoryAttributesINTEL = 5824,
|
||||
CapabilityUnstructuredLoopControlsINTEL = 5886,
|
||||
CapabilityFPGALoopControlsINTEL = 5888,
|
||||
CapabilityKernelAttributesINTEL = 5892,
|
||||
CapabilityFPGAKernelAttributesINTEL = 5897,
|
||||
CapabilityBlockingPipesINTEL = 5945,
|
||||
CapabilityFPGARegINTEL = 5948,
|
||||
CapabilityAtomicFloat32AddEXT = 6033,
|
||||
CapabilityAtomicFloat64AddEXT = 6034,
|
||||
CapabilityMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -981,6 +1031,22 @@ enum RayQueryCandidateIntersectionType {
|
||||
RayQueryCandidateIntersectionTypeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum FragmentShadingRateShift {
|
||||
FragmentShadingRateVertical2PixelsShift = 0,
|
||||
FragmentShadingRateVertical4PixelsShift = 1,
|
||||
FragmentShadingRateHorizontal2PixelsShift = 2,
|
||||
FragmentShadingRateHorizontal4PixelsShift = 3,
|
||||
FragmentShadingRateMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum FragmentShadingRateMask {
|
||||
FragmentShadingRateMaskNone = 0,
|
||||
FragmentShadingRateVertical2PixelsMask = 0x00000001,
|
||||
FragmentShadingRateVertical4PixelsMask = 0x00000002,
|
||||
FragmentShadingRateHorizontal2PixelsMask = 0x00000004,
|
||||
FragmentShadingRateHorizontal4PixelsMask = 0x00000008,
|
||||
};
|
||||
|
||||
enum Op {
|
||||
OpNop = 0,
|
||||
OpUndef = 1,
|
||||
@@ -1326,13 +1392,19 @@ enum Op {
|
||||
OpPtrEqual = 401,
|
||||
OpPtrNotEqual = 402,
|
||||
OpPtrDiff = 403,
|
||||
OpTerminateInvocation = 4416,
|
||||
OpSubgroupBallotKHR = 4421,
|
||||
OpSubgroupFirstInvocationKHR = 4422,
|
||||
OpSubgroupAllKHR = 4428,
|
||||
OpSubgroupAnyKHR = 4429,
|
||||
OpSubgroupAllEqualKHR = 4430,
|
||||
OpSubgroupReadInvocationKHR = 4432,
|
||||
OpTypeRayQueryProvisionalKHR = 4472,
|
||||
OpTraceRayKHR = 4445,
|
||||
OpExecuteCallableKHR = 4446,
|
||||
OpConvertUToAccelerationStructureKHR = 4447,
|
||||
OpIgnoreIntersectionKHR = 4448,
|
||||
OpTerminateRayKHR = 4449,
|
||||
OpTypeRayQueryKHR = 4472,
|
||||
OpRayQueryInitializeKHR = 4473,
|
||||
OpRayQueryTerminateKHR = 4474,
|
||||
OpRayQueryGenerateIntersectionKHR = 4475,
|
||||
@@ -1355,15 +1427,11 @@ enum Op {
|
||||
OpWritePackedPrimitiveIndices4x8NV = 5299,
|
||||
OpReportIntersectionKHR = 5334,
|
||||
OpReportIntersectionNV = 5334,
|
||||
OpIgnoreIntersectionKHR = 5335,
|
||||
OpIgnoreIntersectionNV = 5335,
|
||||
OpTerminateRayKHR = 5336,
|
||||
OpTerminateRayNV = 5336,
|
||||
OpTraceNV = 5337,
|
||||
OpTraceRayKHR = 5337,
|
||||
OpTypeAccelerationStructureKHR = 5341,
|
||||
OpTypeAccelerationStructureNV = 5341,
|
||||
OpExecuteCallableKHR = 5344,
|
||||
OpExecuteCallableNV = 5344,
|
||||
OpTypeCooperativeMatrixNV = 5358,
|
||||
OpCooperativeMatrixLoadNV = 5359,
|
||||
@@ -1398,6 +1466,8 @@ enum Op {
|
||||
OpUSubSatINTEL = 5596,
|
||||
OpIMul32x16INTEL = 5597,
|
||||
OpUMul32x16INTEL = 5598,
|
||||
OpFunctionPointerINTEL = 5600,
|
||||
OpFunctionPointerCallINTEL = 5601,
|
||||
OpDecorateString = 5632,
|
||||
OpDecorateStringGOOGLE = 5632,
|
||||
OpMemberDecorateString = 5633,
|
||||
@@ -1520,6 +1590,10 @@ enum Op {
|
||||
OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
|
||||
OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
|
||||
OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
|
||||
OpLoopControlINTEL = 5887,
|
||||
OpReadPipeBlockingINTEL = 5946,
|
||||
OpWritePipeBlockingINTEL = 5947,
|
||||
OpFPGARegINTEL = 5949,
|
||||
OpRayQueryGetRayTMinKHR = 6016,
|
||||
OpRayQueryGetRayFlagsKHR = 6017,
|
||||
OpRayQueryGetIntersectionTKHR = 6018,
|
||||
@@ -1537,6 +1611,7 @@ enum Op {
|
||||
OpRayQueryGetWorldRayOriginKHR = 6030,
|
||||
OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
|
||||
OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
|
||||
OpAtomicFAddEXT = 6035,
|
||||
OpMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@@ -1889,13 +1964,19 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpPtrEqual: *hasResult = true; *hasResultType = true; break;
|
||||
case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
|
||||
case OpPtrDiff: *hasResult = true; *hasResultType = true; break;
|
||||
case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break;
|
||||
case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpTypeRayQueryProvisionalKHR: *hasResult = true; *hasResultType = false; 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 OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
|
||||
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break;
|
||||
@@ -1955,6 +2036,8 @@ 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 OpFunctionPointerCallINTEL: *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;
|
||||
@@ -2075,6 +2158,10 @@ 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 OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break;
|
||||
@@ -2092,6 +2179,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
|
||||
}
|
||||
}
|
||||
#endif /* SPV_ENABLE_UTILITY_CODE */
|
||||
@@ -2107,6 +2195,7 @@ inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask
|
||||
inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
|
||||
inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
|
||||
inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); }
|
||||
inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); }
|
||||
|
||||
} // end namespace spv
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2020 Arm Limited
|
||||
* Copyright 2016-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#include "spirv_cfg.hpp"
|
||||
#include "spirv_cross.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2020 Arm Limited
|
||||
* Copyright 2016-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_CFG_HPP
|
||||
#define SPIRV_CROSS_CFG_HPP
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2020 Arm Limited
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_COMMON_HPP
|
||||
#define SPIRV_CROSS_COMMON_HPP
|
||||
|
||||
@@ -262,6 +269,29 @@ inline std::string convert_to_string(double t, char locale_radix_point)
|
||||
return buf;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct ValueSaver
|
||||
{
|
||||
explicit ValueSaver(T ¤t_)
|
||||
: current(current_)
|
||||
, saved(current_)
|
||||
{
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
current = saved;
|
||||
}
|
||||
|
||||
~ValueSaver()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
T ¤t;
|
||||
T saved;
|
||||
};
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
@@ -272,8 +302,20 @@ struct Instruction
|
||||
{
|
||||
uint16_t op = 0;
|
||||
uint16_t count = 0;
|
||||
// If offset is 0 (not a valid offset into the instruction stream),
|
||||
// we have an instruction stream which is embedded in the object.
|
||||
uint32_t offset = 0;
|
||||
uint32_t length = 0;
|
||||
|
||||
inline bool is_embedded() const
|
||||
{
|
||||
return offset == 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct EmbeddedInstruction : Instruction
|
||||
{
|
||||
SmallVector<uint32_t> ops;
|
||||
};
|
||||
|
||||
enum Types
|
||||
@@ -334,28 +376,6 @@ public:
|
||||
return TypedID<U>(*this);
|
||||
}
|
||||
|
||||
bool operator==(const TypedID &other) const
|
||||
{
|
||||
return id == other.id;
|
||||
}
|
||||
|
||||
bool operator!=(const TypedID &other) const
|
||||
{
|
||||
return id != other.id;
|
||||
}
|
||||
|
||||
template <Types type>
|
||||
bool operator==(const TypedID<type> &other) const
|
||||
{
|
||||
return id == uint32_t(other);
|
||||
}
|
||||
|
||||
template <Types type>
|
||||
bool operator!=(const TypedID<type> &other) const
|
||||
{
|
||||
return id != uint32_t(other);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t id = 0;
|
||||
};
|
||||
@@ -380,26 +400,6 @@ public:
|
||||
return id;
|
||||
}
|
||||
|
||||
bool operator==(const TypedID &other) const
|
||||
{
|
||||
return id == other.id;
|
||||
}
|
||||
|
||||
bool operator!=(const TypedID &other) const
|
||||
{
|
||||
return id != other.id;
|
||||
}
|
||||
|
||||
bool operator==(const TypedID<TypeNone> &other) const
|
||||
{
|
||||
return id == uint32_t(other);
|
||||
}
|
||||
|
||||
bool operator!=(const TypedID<TypeNone> &other) const
|
||||
{
|
||||
return id != uint32_t(other);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t id = 0;
|
||||
};
|
||||
@@ -535,6 +535,7 @@ struct SPIRType : IVariant
|
||||
|
||||
// Keep internal types at the end.
|
||||
ControlPointArray,
|
||||
Interpolant,
|
||||
Char
|
||||
};
|
||||
|
||||
@@ -641,7 +642,7 @@ struct SPIREntryPoint
|
||||
SmallVector<VariableID> interface_variables;
|
||||
|
||||
Bitset flags;
|
||||
struct
|
||||
struct WorkgroupSize
|
||||
{
|
||||
uint32_t x = 0, y = 0, z = 0;
|
||||
uint32_t constant = 0; // Workgroup size can be expressed as a constant/spec-constant instead.
|
||||
@@ -699,6 +700,9 @@ struct SPIRExpression : IVariant
|
||||
// Used by access chain Store and Load since we read multiple expressions in this case.
|
||||
SmallVector<ID> implied_read_expressions;
|
||||
|
||||
// The expression was emitted at a certain scope. Lets us track when an expression read means multiple reads.
|
||||
uint32_t emitted_loop_level = 0;
|
||||
|
||||
SPIRV_CROSS_DECLARE_CLONE(SPIRExpression)
|
||||
};
|
||||
|
||||
@@ -737,7 +741,9 @@ struct SPIRBlock : IVariant
|
||||
|
||||
Return, // Block ends with return.
|
||||
Unreachable, // Noop
|
||||
Kill // Discard
|
||||
Kill, // Discard
|
||||
IgnoreIntersection, // Ray Tracing
|
||||
TerminateRay // Ray Tracing
|
||||
};
|
||||
|
||||
enum Merge
|
||||
@@ -1069,7 +1075,8 @@ struct SPIRConstant : IVariant
|
||||
type = TypeConstant
|
||||
};
|
||||
|
||||
union Constant {
|
||||
union Constant
|
||||
{
|
||||
uint32_t u32;
|
||||
int32_t i32;
|
||||
float f32;
|
||||
@@ -1107,7 +1114,8 @@ struct SPIRConstant : IVariant
|
||||
int e = (u16_value >> 10) & 0x1f;
|
||||
int m = (u16_value >> 0) & 0x3ff;
|
||||
|
||||
union {
|
||||
union
|
||||
{
|
||||
float f32;
|
||||
uint32_t u32;
|
||||
} u;
|
||||
@@ -1526,6 +1534,7 @@ struct AccessChainMeta
|
||||
bool need_transpose = false;
|
||||
bool storage_is_packed = false;
|
||||
bool storage_is_invariant = false;
|
||||
bool flattened_struct = false;
|
||||
};
|
||||
|
||||
enum ExtendedDecorations
|
||||
@@ -1560,8 +1569,10 @@ enum ExtendedDecorations
|
||||
// Marks a buffer block for using explicit offsets (GLSL/HLSL).
|
||||
SPIRVCrossDecorationExplicitOffset,
|
||||
|
||||
// Apply to a variable in the Input storage class; marks it as holding the base group passed to vkCmdDispatchBase().
|
||||
// In MSL, this is used to adjust the WorkgroupId and GlobalInvocationId variables.
|
||||
// Apply to a variable in the Input storage class; marks it as holding the base group passed to vkCmdDispatchBase(),
|
||||
// or the base vertex and instance indices passed to vkCmdDrawIndexed().
|
||||
// In MSL, this is used to adjust the WorkgroupId and GlobalInvocationId variables in compute shaders,
|
||||
// and to hold the BaseVertex and BaseInstance variables in vertex shaders.
|
||||
SPIRVCrossDecorationBuiltInDispatchBase,
|
||||
|
||||
// Apply to a variable that is a function parameter; marks it as being a "dynamic"
|
||||
@@ -1570,6 +1581,27 @@ enum ExtendedDecorations
|
||||
// Y'CbCr conversion.
|
||||
SPIRVCrossDecorationDynamicImageSampler,
|
||||
|
||||
// Apply to a variable in the Input storage class; marks it as holding the size of the stage
|
||||
// input grid.
|
||||
// In MSL, this is used to hold the vertex and instance counts in a tessellation pipeline
|
||||
// vertex shader.
|
||||
SPIRVCrossDecorationBuiltInStageInputSize,
|
||||
|
||||
// Apply to any access chain of a tessellation I/O variable; stores the type of the sub-object
|
||||
// that was chained to, as recorded in the input variable itself. This is used in case the pointer
|
||||
// is itself used as the base of an access chain, to calculate the original type of the sub-object
|
||||
// chained to, in case a swizzle needs to be applied. This should not happen normally with valid
|
||||
// SPIR-V, but the MSL backend can change the type of input variables, necessitating the
|
||||
// addition of swizzles to keep the generated code compiling.
|
||||
SPIRVCrossDecorationTessIOOriginalInputTypeID,
|
||||
|
||||
// Apply to any access chain of an interface variable used with pull-model interpolation, where the variable is a
|
||||
// vector but the resulting pointer is a scalar; stores the component index that is to be accessed by the chain.
|
||||
// This is used when emitting calls to interpolation functions on the chain in MSL: in this case, the component
|
||||
// must be applied to the result, since pull-model interpolants in MSL cannot be swizzled directly, but the
|
||||
// results of interpolation can.
|
||||
SPIRVCrossDecorationInterpolantComponentExpr,
|
||||
|
||||
SPIRVCrossDecorationCount
|
||||
};
|
||||
|
||||
@@ -1589,6 +1621,7 @@ struct Meta
|
||||
uint32_t offset = 0;
|
||||
uint32_t xfb_buffer = 0;
|
||||
uint32_t xfb_stride = 0;
|
||||
uint32_t stream = 0;
|
||||
uint32_t array_stride = 0;
|
||||
uint32_t matrix_stride = 0;
|
||||
uint32_t input_attachment = 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2020 Arm Limited
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#include "spirv_cpp.hpp"
|
||||
|
||||
using namespace spv;
|
||||
@@ -306,6 +313,8 @@ void CompilerCPP::emit_resources()
|
||||
|
||||
string CompilerCPP::compile()
|
||||
{
|
||||
ir.fixup_reserved_names();
|
||||
|
||||
// Do not deal with ES-isms like precision, older extensions and such.
|
||||
options.es = false;
|
||||
options.version = 450;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2020 Arm Limited
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_CPP_HPP
|
||||
#define SPIRV_CROSS_CPP_HPP
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2020 Arm Limited
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#include "spirv_cross.hpp"
|
||||
#include "GLSL.std.450.h"
|
||||
#include "spirv_cfg.hpp"
|
||||
@@ -89,7 +96,9 @@ bool Compiler::variable_storage_is_aliased(const SPIRVariable &v)
|
||||
bool Compiler::block_is_pure(const SPIRBlock &block)
|
||||
{
|
||||
// This is a global side effect of the function.
|
||||
if (block.terminator == SPIRBlock::Kill)
|
||||
if (block.terminator == SPIRBlock::Kill ||
|
||||
block.terminator == SPIRBlock::TerminateRay ||
|
||||
block.terminator == SPIRBlock::IgnoreIntersection)
|
||||
return false;
|
||||
|
||||
for (auto &i : block.ops)
|
||||
@@ -151,11 +160,13 @@ bool Compiler::block_is_pure(const SPIRBlock &block)
|
||||
return false;
|
||||
|
||||
// Ray tracing builtins are impure.
|
||||
case OpReportIntersectionNV:
|
||||
case OpReportIntersectionKHR:
|
||||
case OpIgnoreIntersectionNV:
|
||||
case OpTerminateRayNV:
|
||||
case OpTraceNV:
|
||||
case OpTraceRayKHR:
|
||||
case OpExecuteCallableNV:
|
||||
case OpExecuteCallableKHR:
|
||||
return false;
|
||||
|
||||
// OpExtInst is potentially impure depending on extension, but GLSL builtins are at least pure.
|
||||
@@ -273,11 +284,27 @@ SPIRVariable *Compiler::maybe_get_backing_variable(uint32_t chain)
|
||||
return var;
|
||||
}
|
||||
|
||||
StorageClass Compiler::get_backing_variable_storage(uint32_t ptr)
|
||||
StorageClass Compiler::get_expression_effective_storage_class(uint32_t ptr)
|
||||
{
|
||||
auto *var = maybe_get_backing_variable(ptr);
|
||||
if (var)
|
||||
return var->storage;
|
||||
|
||||
// If the expression has been lowered to a temporary, we need to use the Generic storage class.
|
||||
// We're looking for the effective storage class of a given expression.
|
||||
// An access chain or forwarded OpLoads from such access chains
|
||||
// will generally have the storage class of the underlying variable, but if the load was not forwarded
|
||||
// we have lost any address space qualifiers.
|
||||
bool forced_temporary = ir.ids[ptr].get_type() == TypeExpression && !get<SPIRExpression>(ptr).access_chain &&
|
||||
(forced_temporaries.count(ptr) != 0 || forwarded_temporaries.count(ptr) == 0);
|
||||
|
||||
if (var && !forced_temporary)
|
||||
{
|
||||
// Normalize SSBOs to StorageBuffer here.
|
||||
if (var->storage == StorageClassUniform &&
|
||||
has_decoration(get<SPIRType>(var->basetype).self, DecorationBufferBlock))
|
||||
return StorageClassStorageBuffer;
|
||||
else
|
||||
return var->storage;
|
||||
}
|
||||
else
|
||||
return expression_type(ptr).storage;
|
||||
}
|
||||
@@ -519,10 +546,16 @@ bool Compiler::is_hidden_variable(const SPIRVariable &var, bool include_builtins
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hidden = false;
|
||||
if (check_active_interface_variables && storage_class_is_interface(var.storage))
|
||||
hidden = active_interface_variables.find(var.self) == end(active_interface_variables);
|
||||
return hidden;
|
||||
// In SPIR-V 1.4 and up we must also use the active variable interface to disable global variables
|
||||
// which are not part of the entry point.
|
||||
if (ir.get_spirv_version() >= 0x10400 && var.storage != spv::StorageClassGeneric &&
|
||||
var.storage != spv::StorageClassFunction && !interface_variable_exists_in_entry_point(var.self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return check_active_interface_variables && storage_class_is_interface(var.storage) &&
|
||||
active_interface_variables.find(var.self) == end(active_interface_variables);
|
||||
}
|
||||
|
||||
bool Compiler::is_builtin_type(const SPIRType &type) const
|
||||
@@ -683,8 +716,31 @@ bool Compiler::InterfaceVariableAccessHandler::handle(Op opcode, const uint32_t
|
||||
{
|
||||
if (length < 5)
|
||||
return false;
|
||||
uint32_t extension_set = args[2];
|
||||
if (compiler.get<SPIRExtension>(extension_set).ext == SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter)
|
||||
auto &extension_set = compiler.get<SPIRExtension>(args[2]);
|
||||
switch (extension_set.ext)
|
||||
{
|
||||
case SPIRExtension::GLSL:
|
||||
{
|
||||
auto op = static_cast<GLSLstd450>(args[3]);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case GLSLstd450InterpolateAtCentroid:
|
||||
case GLSLstd450InterpolateAtSample:
|
||||
case GLSLstd450InterpolateAtOffset:
|
||||
{
|
||||
auto *var = compiler.maybe_get<SPIRVariable>(args[4]);
|
||||
if (var && storage_class_is_interface(var->storage))
|
||||
variables.insert(args[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter:
|
||||
{
|
||||
enum AMDShaderExplicitVertexParameter
|
||||
{
|
||||
@@ -706,6 +762,10 @@ bool Compiler::InterfaceVariableAccessHandler::handle(Op opcode, const uint32_t
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -755,9 +815,17 @@ unordered_set<VariableID> Compiler::get_active_interface_variables() const
|
||||
InterfaceVariableAccessHandler handler(*this, variables);
|
||||
traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
|
||||
|
||||
// Make sure we preserve output variables which are only initialized, but never accessed by any code.
|
||||
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
|
||||
if (var.storage == StorageClassOutput && var.initializer != ID(0))
|
||||
if (var.storage != StorageClassOutput)
|
||||
return;
|
||||
if (!interface_variable_exists_in_entry_point(var.self))
|
||||
return;
|
||||
|
||||
// An output variable which is just declared (but uninitialized) might be read by subsequent stages
|
||||
// so we should force-enable these outputs,
|
||||
// since compilation will fail if a subsequent stage attempts to read from the variable in question.
|
||||
// Also, make sure we preserve output variables which are only initialized, but never accessed by any code.
|
||||
if (var.initializer != ID(0) || get_execution_model() != ExecutionModelFragment)
|
||||
variables.insert(var.self);
|
||||
});
|
||||
|
||||
@@ -1636,6 +1704,161 @@ size_t Compiler::get_declared_struct_size_runtime_array(const SPIRType &type, si
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t Compiler::evaluate_spec_constant_u32(const SPIRConstantOp &spec) const
|
||||
{
|
||||
auto &result_type = get<SPIRType>(spec.basetype);
|
||||
if (result_type.basetype != SPIRType::UInt && result_type.basetype != SPIRType::Int &&
|
||||
result_type.basetype != SPIRType::Boolean)
|
||||
{
|
||||
SPIRV_CROSS_THROW(
|
||||
"Only 32-bit integers and booleans are currently supported when evaluating specialization constants.\n");
|
||||
}
|
||||
|
||||
if (!is_scalar(result_type))
|
||||
SPIRV_CROSS_THROW("Spec constant evaluation must be a scalar.\n");
|
||||
|
||||
uint32_t value = 0;
|
||||
|
||||
const auto eval_u32 = [&](uint32_t id) -> uint32_t {
|
||||
auto &type = expression_type(id);
|
||||
if (type.basetype != SPIRType::UInt && type.basetype != SPIRType::Int && type.basetype != SPIRType::Boolean)
|
||||
{
|
||||
SPIRV_CROSS_THROW("Only 32-bit integers and booleans are currently supported when evaluating "
|
||||
"specialization constants.\n");
|
||||
}
|
||||
|
||||
if (!is_scalar(type))
|
||||
SPIRV_CROSS_THROW("Spec constant evaluation must be a scalar.\n");
|
||||
if (const auto *c = this->maybe_get<SPIRConstant>(id))
|
||||
return c->scalar();
|
||||
else
|
||||
return evaluate_spec_constant_u32(this->get<SPIRConstantOp>(id));
|
||||
};
|
||||
|
||||
#define binary_spec_op(op, binary_op) \
|
||||
case Op##op: \
|
||||
value = eval_u32(spec.arguments[0]) binary_op eval_u32(spec.arguments[1]); \
|
||||
break
|
||||
#define binary_spec_op_cast(op, binary_op, type) \
|
||||
case Op##op: \
|
||||
value = uint32_t(type(eval_u32(spec.arguments[0])) binary_op type(eval_u32(spec.arguments[1]))); \
|
||||
break
|
||||
|
||||
// Support the basic opcodes which are typically used when computing array sizes.
|
||||
switch (spec.opcode)
|
||||
{
|
||||
binary_spec_op(IAdd, +);
|
||||
binary_spec_op(ISub, -);
|
||||
binary_spec_op(IMul, *);
|
||||
binary_spec_op(BitwiseAnd, &);
|
||||
binary_spec_op(BitwiseOr, |);
|
||||
binary_spec_op(BitwiseXor, ^);
|
||||
binary_spec_op(LogicalAnd, &);
|
||||
binary_spec_op(LogicalOr, |);
|
||||
binary_spec_op(ShiftLeftLogical, <<);
|
||||
binary_spec_op(ShiftRightLogical, >>);
|
||||
binary_spec_op_cast(ShiftRightArithmetic, >>, int32_t);
|
||||
binary_spec_op(LogicalEqual, ==);
|
||||
binary_spec_op(LogicalNotEqual, !=);
|
||||
binary_spec_op(IEqual, ==);
|
||||
binary_spec_op(INotEqual, !=);
|
||||
binary_spec_op(ULessThan, <);
|
||||
binary_spec_op(ULessThanEqual, <=);
|
||||
binary_spec_op(UGreaterThan, >);
|
||||
binary_spec_op(UGreaterThanEqual, >=);
|
||||
binary_spec_op_cast(SLessThan, <, int32_t);
|
||||
binary_spec_op_cast(SLessThanEqual, <=, int32_t);
|
||||
binary_spec_op_cast(SGreaterThan, >, int32_t);
|
||||
binary_spec_op_cast(SGreaterThanEqual, >=, int32_t);
|
||||
#undef binary_spec_op
|
||||
#undef binary_spec_op_cast
|
||||
|
||||
case OpLogicalNot:
|
||||
value = uint32_t(!eval_u32(spec.arguments[0]));
|
||||
break;
|
||||
|
||||
case OpNot:
|
||||
value = ~eval_u32(spec.arguments[0]);
|
||||
break;
|
||||
|
||||
case OpSNegate:
|
||||
value = uint32_t(-int32_t(eval_u32(spec.arguments[0])));
|
||||
break;
|
||||
|
||||
case OpSelect:
|
||||
value = eval_u32(spec.arguments[0]) ? eval_u32(spec.arguments[1]) : eval_u32(spec.arguments[2]);
|
||||
break;
|
||||
|
||||
case OpUMod:
|
||||
{
|
||||
uint32_t a = eval_u32(spec.arguments[0]);
|
||||
uint32_t b = eval_u32(spec.arguments[1]);
|
||||
if (b == 0)
|
||||
SPIRV_CROSS_THROW("Undefined behavior in UMod, b == 0.\n");
|
||||
value = a % b;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpSRem:
|
||||
{
|
||||
auto a = int32_t(eval_u32(spec.arguments[0]));
|
||||
auto b = int32_t(eval_u32(spec.arguments[1]));
|
||||
if (b == 0)
|
||||
SPIRV_CROSS_THROW("Undefined behavior in SRem, b == 0.\n");
|
||||
value = a % b;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpSMod:
|
||||
{
|
||||
auto a = int32_t(eval_u32(spec.arguments[0]));
|
||||
auto b = int32_t(eval_u32(spec.arguments[1]));
|
||||
if (b == 0)
|
||||
SPIRV_CROSS_THROW("Undefined behavior in SMod, b == 0.\n");
|
||||
auto v = a % b;
|
||||
|
||||
// Makes sure we match the sign of b, not a.
|
||||
if ((b < 0 && v > 0) || (b > 0 && v < 0))
|
||||
v += b;
|
||||
value = v;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpUDiv:
|
||||
{
|
||||
uint32_t a = eval_u32(spec.arguments[0]);
|
||||
uint32_t b = eval_u32(spec.arguments[1]);
|
||||
if (b == 0)
|
||||
SPIRV_CROSS_THROW("Undefined behavior in UDiv, b == 0.\n");
|
||||
value = a / b;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpSDiv:
|
||||
{
|
||||
auto a = int32_t(eval_u32(spec.arguments[0]));
|
||||
auto b = int32_t(eval_u32(spec.arguments[1]));
|
||||
if (b == 0)
|
||||
SPIRV_CROSS_THROW("Undefined behavior in SDiv, b == 0.\n");
|
||||
value = a / b;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
SPIRV_CROSS_THROW("Unsupported spec constant opcode for evaluation.\n");
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t Compiler::evaluate_constant_u32(uint32_t id) const
|
||||
{
|
||||
if (const auto *c = maybe_get<SPIRConstant>(id))
|
||||
return c->scalar();
|
||||
else
|
||||
return evaluate_spec_constant_u32(get<SPIRConstantOp>(id));
|
||||
}
|
||||
|
||||
size_t Compiler::get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const
|
||||
{
|
||||
if (struct_type.member_types.empty())
|
||||
@@ -1670,7 +1893,7 @@ size_t Compiler::get_declared_struct_member_size(const SPIRType &struct_type, ui
|
||||
{
|
||||
// For arrays, we can use ArrayStride to get an easy check.
|
||||
bool array_size_literal = type.array_size_literal.back();
|
||||
uint32_t array_size = array_size_literal ? type.array.back() : get<SPIRConstant>(type.array.back()).scalar();
|
||||
uint32_t array_size = array_size_literal ? type.array.back() : evaluate_constant_u32(type.array.back());
|
||||
return type_struct_member_array_stride(struct_type, index) * array_size;
|
||||
}
|
||||
else if (type.basetype == SPIRType::Struct)
|
||||
@@ -1904,6 +2127,13 @@ bool Compiler::is_tessellation_shader(ExecutionModel model)
|
||||
return model == ExecutionModelTessellationControl || model == ExecutionModelTessellationEvaluation;
|
||||
}
|
||||
|
||||
bool Compiler::is_vertex_like_shader() const
|
||||
{
|
||||
auto model = get_execution_model();
|
||||
return model == ExecutionModelVertex || model == ExecutionModelGeometry ||
|
||||
model == ExecutionModelTessellationControl || model == ExecutionModelTessellationEvaluation;
|
||||
}
|
||||
|
||||
bool Compiler::is_tessellation_shader() const
|
||||
{
|
||||
return is_tessellation_shader(get_execution_model());
|
||||
@@ -2067,16 +2297,22 @@ SPIREntryPoint &Compiler::get_entry_point()
|
||||
bool Compiler::interface_variable_exists_in_entry_point(uint32_t id) const
|
||||
{
|
||||
auto &var = get<SPIRVariable>(id);
|
||||
if (var.storage != StorageClassInput && var.storage != StorageClassOutput &&
|
||||
var.storage != StorageClassUniformConstant)
|
||||
SPIRV_CROSS_THROW("Only Input, Output variables and Uniform constants are part of a shader linking interface.");
|
||||
|
||||
// This is to avoid potential problems with very old glslang versions which did
|
||||
// not emit input/output interfaces properly.
|
||||
// We can assume they only had a single entry point, and single entry point
|
||||
// shaders could easily be assumed to use every interface variable anyways.
|
||||
if (ir.entry_points.size() <= 1)
|
||||
return true;
|
||||
if (ir.get_spirv_version() < 0x10400)
|
||||
{
|
||||
if (var.storage != StorageClassInput && var.storage != StorageClassOutput &&
|
||||
var.storage != StorageClassUniformConstant)
|
||||
SPIRV_CROSS_THROW("Only Input, Output variables and Uniform constants are part of a shader linking interface.");
|
||||
|
||||
// This is to avoid potential problems with very old glslang versions which did
|
||||
// not emit input/output interfaces properly.
|
||||
// We can assume they only had a single entry point, and single entry point
|
||||
// shaders could easily be assumed to use every interface variable anyways.
|
||||
if (ir.entry_points.size() <= 1)
|
||||
return true;
|
||||
}
|
||||
|
||||
// In SPIR-V 1.4 and later, all global resource variables must be present.
|
||||
|
||||
auto &execution = get_entry_point();
|
||||
return find(begin(execution.interface_variables), end(execution.interface_variables), VariableID(id)) !=
|
||||
@@ -2599,7 +2835,8 @@ const SPIRConstant &Compiler::get_constant(ConstantID id) const
|
||||
return get<SPIRConstant>(id);
|
||||
}
|
||||
|
||||
static bool exists_unaccessed_path_to_return(const CFG &cfg, uint32_t block, const unordered_set<uint32_t> &blocks)
|
||||
static bool exists_unaccessed_path_to_return(const CFG &cfg, uint32_t block, const unordered_set<uint32_t> &blocks,
|
||||
unordered_set<uint32_t> &visit_cache)
|
||||
{
|
||||
// This block accesses the variable.
|
||||
if (blocks.find(block) != end(blocks))
|
||||
@@ -2611,8 +2848,14 @@ static bool exists_unaccessed_path_to_return(const CFG &cfg, uint32_t block, con
|
||||
|
||||
// If any of our successors have a path to the end, there exists a path from block.
|
||||
for (auto &succ : cfg.get_succeeding_edges(block))
|
||||
if (exists_unaccessed_path_to_return(cfg, succ, blocks))
|
||||
return true;
|
||||
{
|
||||
if (visit_cache.count(succ) == 0)
|
||||
{
|
||||
if (exists_unaccessed_path_to_return(cfg, succ, blocks, visit_cache))
|
||||
return true;
|
||||
visit_cache.insert(succ);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -2669,7 +2912,8 @@ void Compiler::analyze_parameter_preservation(
|
||||
// void foo(int &var) { if (cond) var = 10; }
|
||||
// Using read/write counts, we will think it's just an out variable, but it really needs to be inout,
|
||||
// because if we don't write anything whatever we put into the function must return back to the caller.
|
||||
if (exists_unaccessed_path_to_return(cfg, entry.entry_block, itr->second))
|
||||
unordered_set<uint32_t> visit_cache;
|
||||
if (exists_unaccessed_path_to_return(cfg, entry.entry_block, itr->second, visit_cache))
|
||||
arg.read_count++;
|
||||
}
|
||||
}
|
||||
@@ -3627,23 +3871,55 @@ void Compiler::ActiveBuiltinHandler::handle_builtin(const SPIRType &type, BuiltI
|
||||
}
|
||||
}
|
||||
|
||||
bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args, uint32_t length)
|
||||
void Compiler::ActiveBuiltinHandler::add_if_builtin(uint32_t id, bool allow_blocks)
|
||||
{
|
||||
const auto add_if_builtin = [&](uint32_t id) {
|
||||
// Only handles variables here.
|
||||
// Builtins which are part of a block are handled in AccessChain.
|
||||
auto *var = compiler.maybe_get<SPIRVariable>(id);
|
||||
auto &decorations = compiler.ir.meta[id].decoration;
|
||||
if (var && decorations.builtin)
|
||||
// Only handle plain variables here.
|
||||
// Builtins which are part of a block are handled in AccessChain.
|
||||
// If allow_blocks is used however, this is to handle initializers of blocks,
|
||||
// which implies that all members are written to.
|
||||
|
||||
auto *var = compiler.maybe_get<SPIRVariable>(id);
|
||||
auto *m = compiler.ir.find_meta(id);
|
||||
if (var && m)
|
||||
{
|
||||
auto &type = compiler.get<SPIRType>(var->basetype);
|
||||
auto &decorations = m->decoration;
|
||||
auto &flags = type.storage == StorageClassInput ?
|
||||
compiler.active_input_builtins : compiler.active_output_builtins;
|
||||
if (decorations.builtin)
|
||||
{
|
||||
auto &type = compiler.get<SPIRType>(var->basetype);
|
||||
auto &flags =
|
||||
type.storage == StorageClassInput ? compiler.active_input_builtins : compiler.active_output_builtins;
|
||||
flags.set(decorations.builtin_type);
|
||||
handle_builtin(type, decorations.builtin_type, decorations.decoration_flags);
|
||||
}
|
||||
};
|
||||
else if (allow_blocks && compiler.has_decoration(type.self, DecorationBlock))
|
||||
{
|
||||
uint32_t member_count = uint32_t(type.member_types.size());
|
||||
for (uint32_t i = 0; i < member_count; i++)
|
||||
{
|
||||
if (compiler.has_member_decoration(type.self, i, DecorationBuiltIn))
|
||||
{
|
||||
auto &member_type = compiler.get<SPIRType>(type.member_types[i]);
|
||||
BuiltIn builtin = BuiltIn(compiler.get_member_decoration(type.self, i, DecorationBuiltIn));
|
||||
flags.set(builtin);
|
||||
handle_builtin(member_type, builtin, compiler.get_member_decoration_bitset(type.self, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::ActiveBuiltinHandler::add_if_builtin(uint32_t id)
|
||||
{
|
||||
add_if_builtin(id, false);
|
||||
}
|
||||
|
||||
void Compiler::ActiveBuiltinHandler::add_if_builtin_or_block(uint32_t id)
|
||||
{
|
||||
add_if_builtin(id, true);
|
||||
}
|
||||
|
||||
bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args, uint32_t length)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case OpStore:
|
||||
@@ -3781,6 +4057,17 @@ void Compiler::update_active_builtins()
|
||||
clip_distance_count = 0;
|
||||
ActiveBuiltinHandler handler(*this);
|
||||
traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
|
||||
|
||||
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
|
||||
if (var.storage != StorageClassOutput)
|
||||
return;
|
||||
if (!interface_variable_exists_in_entry_point(var.self))
|
||||
return;
|
||||
|
||||
// Also, make sure we preserve output variables which are only initialized, but never accessed by any code.
|
||||
if (var.initializer != ID(0))
|
||||
handler.add_if_builtin_or_block(var.self);
|
||||
});
|
||||
}
|
||||
|
||||
// Returns whether this shader uses a builtin of the storage class
|
||||
@@ -4658,3 +4945,8 @@ bool Compiler::flush_phi_required(BlockID from, BlockID to) const
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Compiler::add_loop_level()
|
||||
{
|
||||
current_loop_level++;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2020 Arm Limited
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_HPP
|
||||
#define SPIRV_CROSS_HPP
|
||||
|
||||
@@ -491,6 +498,12 @@ public:
|
||||
// The most common use here is to check if a buffer is readonly or writeonly.
|
||||
Bitset get_buffer_block_flags(VariableID id) const;
|
||||
|
||||
// Returns whether the position output is invariant
|
||||
bool is_position_invariant() const
|
||||
{
|
||||
return position_invariant;
|
||||
}
|
||||
|
||||
protected:
|
||||
const uint32_t *stream(const Instruction &instr) const
|
||||
{
|
||||
@@ -500,9 +513,18 @@ protected:
|
||||
if (!instr.length)
|
||||
return nullptr;
|
||||
|
||||
if (instr.offset + instr.length > ir.spirv.size())
|
||||
SPIRV_CROSS_THROW("Compiler::stream() out of range.");
|
||||
return &ir.spirv[instr.offset];
|
||||
if (instr.is_embedded())
|
||||
{
|
||||
auto &embedded = static_cast<const EmbeddedInstruction &>(instr);
|
||||
assert(embedded.ops.size() == instr.length);
|
||||
return embedded.ops.data();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (instr.offset + instr.length > ir.spirv.size())
|
||||
SPIRV_CROSS_THROW("Compiler::stream() out of range.");
|
||||
return &ir.spirv[instr.offset];
|
||||
}
|
||||
}
|
||||
|
||||
ParsedIR ir;
|
||||
@@ -513,9 +535,22 @@ protected:
|
||||
|
||||
SPIRFunction *current_function = nullptr;
|
||||
SPIRBlock *current_block = nullptr;
|
||||
uint32_t current_loop_level = 0;
|
||||
std::unordered_set<VariableID> active_interface_variables;
|
||||
bool check_active_interface_variables = false;
|
||||
|
||||
void add_loop_level();
|
||||
|
||||
void set_initializers(SPIRExpression &e)
|
||||
{
|
||||
e.emitted_loop_level = current_loop_level;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_initializers(const T &)
|
||||
{
|
||||
}
|
||||
|
||||
// If our IDs are out of range here as part of opcodes, throw instead of
|
||||
// undefined behavior.
|
||||
template <typename T, typename... P>
|
||||
@@ -524,6 +559,7 @@ protected:
|
||||
ir.add_typed_id(static_cast<Types>(T::type), id);
|
||||
auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
|
||||
var.self = id;
|
||||
set_initializers(var);
|
||||
return var;
|
||||
}
|
||||
|
||||
@@ -611,7 +647,7 @@ protected:
|
||||
bool expression_is_lvalue(uint32_t id) const;
|
||||
bool variable_storage_is_aliased(const SPIRVariable &var);
|
||||
SPIRVariable *maybe_get_backing_variable(uint32_t chain);
|
||||
spv::StorageClass get_backing_variable_storage(uint32_t ptr);
|
||||
spv::StorageClass get_expression_effective_storage_class(uint32_t ptr);
|
||||
|
||||
void register_read(uint32_t expr, uint32_t chain, bool forwarded);
|
||||
void register_write(uint32_t chain);
|
||||
@@ -812,6 +848,9 @@ protected:
|
||||
Compiler &compiler;
|
||||
|
||||
void handle_builtin(const SPIRType &type, spv::BuiltIn builtin, const Bitset &decoration_flags);
|
||||
void add_if_builtin(uint32_t id);
|
||||
void add_if_builtin_or_block(uint32_t id);
|
||||
void add_if_builtin(uint32_t id, bool allow_blocks);
|
||||
};
|
||||
|
||||
bool traverse_all_reachable_opcodes(const SPIRBlock &block, OpcodeHandler &handler) const;
|
||||
@@ -1046,6 +1085,11 @@ protected:
|
||||
|
||||
bool flush_phi_required(BlockID from, BlockID to) const;
|
||||
|
||||
uint32_t evaluate_spec_constant_u32(const SPIRConstantOp &spec) const;
|
||||
uint32_t evaluate_constant_u32(uint32_t id) const;
|
||||
|
||||
bool is_vertex_like_shader() const;
|
||||
|
||||
private:
|
||||
// Used only to implement the old deprecated get_entry_point() interface.
|
||||
const SPIREntryPoint &get_first_entry_point(const std::string &name) const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Hans-Kristian Arntzen
|
||||
* Copyright 2019-2021 Hans-Kristian Arntzen
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#include "spirv_cross_c.h"
|
||||
|
||||
#if SPIRV_CROSS_C_API_CPP
|
||||
@@ -459,6 +466,9 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
case SPVC_COMPILER_OPTION_GLSL_EMIT_UNIFORM_BUFFER_AS_PLAIN_UNIFORMS:
|
||||
options->glsl.emit_uniform_buffer_as_plain_uniforms = value != 0;
|
||||
break;
|
||||
case SPVC_COMPILER_OPTION_GLSL_FORCE_FLATTENED_IO_BLOCKS:
|
||||
options->glsl.force_flattened_io_blocks = value != 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if SPIRV_CROSS_C_API_HLSL
|
||||
@@ -489,6 +499,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
case SPVC_COMPILER_OPTION_HLSL_ENABLE_16BIT_TYPES:
|
||||
options->hlsl.enable_16bit_types = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_HLSL_FLATTEN_MATRIX_VERTEX_INPUT_SEMANTICS:
|
||||
options->hlsl.flatten_matrix_vertex_input_semantics = value != 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
@@ -596,8 +610,8 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
options->msl.enable_base_index_zero = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_IOS_FRAMEBUFFER_FETCH_SUBPASS:
|
||||
options->msl.ios_use_framebuffer_fetch_subpasses = value != 0;
|
||||
case SPVC_COMPILER_OPTION_MSL_FRAMEBUFFER_FETCH_SUBPASS:
|
||||
options->msl.use_framebuffer_fetch_subpasses = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_INVARIANT_FP_MATH:
|
||||
@@ -635,6 +649,62 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
case SPVC_COMPILER_OPTION_MSL_ENABLE_CLIP_DISTANCE_USER_VARYING:
|
||||
options->msl.enable_clip_distance_user_varying = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_MULTI_PATCH_WORKGROUP:
|
||||
options->msl.multi_patch_workgroup = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_BUFFER_INDEX:
|
||||
options->msl.shader_input_buffer_index = value;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_SHADER_INDEX_BUFFER_INDEX:
|
||||
options->msl.shader_index_buffer_index = value;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_VERTEX_FOR_TESSELLATION:
|
||||
options->msl.vertex_for_tessellation = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_VERTEX_INDEX_TYPE:
|
||||
options->msl.vertex_index_type = static_cast<CompilerMSL::Options::IndexType>(value);
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_MULTIVIEW_LAYERED_RENDERING:
|
||||
options->msl.multiview_layered_rendering = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_ARRAYED_SUBPASS_INPUT:
|
||||
options->msl.arrayed_subpass_input = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_R32UI_LINEAR_TEXTURE_ALIGNMENT:
|
||||
options->msl.r32ui_linear_texture_alignment = value;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_R32UI_ALIGNMENT_CONSTANT_ID:
|
||||
options->msl.r32ui_alignment_constant_id = value;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_IOS_USE_SIMDGROUP_FUNCTIONS:
|
||||
options->msl.ios_use_simdgroup_functions = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_EMULATE_SUBGROUPS:
|
||||
options->msl.emulate_subgroups = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_FIXED_SUBGROUP_SIZE:
|
||||
options->msl.fixed_subgroup_size = value;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_FORCE_SAMPLE_RATE_SHADING:
|
||||
options->msl.force_sample_rate_shading = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_IOS_SUPPORT_BASE_VERTEX_INSTANCE:
|
||||
options->msl.ios_support_base_vertex_instance = value != 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
@@ -1019,11 +1089,11 @@ spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler, const
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLVertexAttr attr;
|
||||
MSLShaderInput attr;
|
||||
attr.location = va->location;
|
||||
attr.format = static_cast<MSLVertexFormat>(va->format);
|
||||
attr.format = static_cast<MSLShaderInputFormat>(va->format);
|
||||
attr.builtin = static_cast<spv::BuiltIn>(va->builtin);
|
||||
msl.add_msl_vertex_attribute(attr);
|
||||
msl.add_msl_shader_input(attr);
|
||||
return SPVC_SUCCESS;
|
||||
#else
|
||||
(void)va;
|
||||
@@ -1032,6 +1102,30 @@ 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)
|
||||
{
|
||||
#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());
|
||||
MSLShaderInput input;
|
||||
input.location = si->location;
|
||||
input.format = static_cast<MSLShaderInputFormat>(si->format);
|
||||
input.builtin = static_cast<spv::BuiltIn>(si->builtin);
|
||||
input.vecsize = si->vecsize;
|
||||
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_resource_binding(spvc_compiler compiler,
|
||||
const spvc_msl_resource_binding *binding)
|
||||
{
|
||||
@@ -1139,7 +1233,7 @@ spvc_result spvc_compiler_msl_set_argument_buffer_device_address_space(spvc_comp
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, unsigned location)
|
||||
spvc_bool spvc_compiler_msl_is_shader_input_used(spvc_compiler compiler, unsigned location)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
@@ -1149,7 +1243,7 @@ spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, uns
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
return msl.is_msl_vertex_attribute_used(location) ? SPVC_TRUE : SPVC_FALSE;
|
||||
return msl.is_msl_shader_input_used(location) ? SPVC_TRUE : SPVC_FALSE;
|
||||
#else
|
||||
(void)location;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
@@ -1157,6 +1251,11 @@ spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, uns
|
||||
#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);
|
||||
}
|
||||
|
||||
spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compiler, SpvExecutionModel model, unsigned set,
|
||||
unsigned binding)
|
||||
{
|
||||
@@ -1179,6 +1278,42 @@ spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compiler, SpvExecutio
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_set_combined_sampler_suffix(spvc_compiler compiler, const char *suffix)
|
||||
{
|
||||
#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());
|
||||
msl.set_combined_sampler_suffix(suffix);
|
||||
return SPVC_SUCCESS;
|
||||
#else
|
||||
(void)suffix;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *spvc_compiler_msl_get_combined_sampler_suffix(spvc_compiler compiler)
|
||||
{
|
||||
#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 "";
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
return msl.get_combined_sampler_suffix();
|
||||
#else
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
static void spvc_convert_msl_sampler(MSLConstexprSampler &samp, const spvc_msl_constexpr_sampler *sampler)
|
||||
{
|
||||
@@ -2258,7 +2393,7 @@ void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
// Crude, but works.
|
||||
MSLVertexAttr attr_default;
|
||||
MSLShaderInput 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);
|
||||
@@ -2267,6 +2402,19 @@ void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr)
|
||||
#endif
|
||||
}
|
||||
|
||||
void spvc_msl_shader_input_init(spvc_msl_shader_input *input)
|
||||
{
|
||||
#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;
|
||||
#else
|
||||
memset(input, 0, sizeof(*input));
|
||||
#endif
|
||||
}
|
||||
|
||||
void spvc_msl_resource_binding_init(spvc_msl_resource_binding *binding)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Hans-Kristian Arntzen
|
||||
* Copyright 2019-2021 Hans-Kristian Arntzen
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_C_API_H
|
||||
#define SPIRV_CROSS_C_API_H
|
||||
|
||||
@@ -33,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 34
|
||||
#define SPVC_C_API_VERSION_MINOR 45
|
||||
/* Bumped if internal implementation details change. */
|
||||
#define SPVC_C_API_VERSION_PATCH 0
|
||||
|
||||
@@ -259,14 +266,32 @@ typedef enum spvc_msl_platform
|
||||
} spvc_msl_platform;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_vertex_format
|
||||
typedef enum spvc_msl_index_type
|
||||
{
|
||||
SPVC_MSL_VERTEX_FORMAT_OTHER = 0,
|
||||
SPVC_MSL_VERTEX_FORMAT_UINT8 = 1,
|
||||
SPVC_MSL_VERTEX_FORMAT_UINT16 = 2
|
||||
} spvc_msl_vertex_format;
|
||||
SPVC_MSL_INDEX_TYPE_NONE = 0,
|
||||
SPVC_MSL_INDEX_TYPE_UINT16 = 1,
|
||||
SPVC_MSL_INDEX_TYPE_UINT32 = 2,
|
||||
SPVC_MSL_INDEX_TYPE_MAX_INT = 0x7fffffff
|
||||
} spvc_msl_index_type;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_shader_input_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,
|
||||
|
||||
/* 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_SHADER_INPUT_FORMAT_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_shader_input_format, spvc_msl_vertex_format;
|
||||
|
||||
/* Maps to C++ API. Deprecated; use spvc_msl_shader_input. */
|
||||
typedef struct spvc_msl_vertex_attribute
|
||||
{
|
||||
unsigned location;
|
||||
@@ -289,6 +314,20 @@ 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
|
||||
{
|
||||
unsigned location;
|
||||
spvc_msl_vertex_format format;
|
||||
SpvBuiltIn builtin;
|
||||
unsigned vecsize;
|
||||
} spvc_msl_shader_input;
|
||||
|
||||
/*
|
||||
* Initializes the shader input struct.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_shader_input_init(spvc_msl_shader_input *input);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_resource_binding
|
||||
{
|
||||
@@ -574,7 +613,11 @@ typedef enum spvc_compiler_option
|
||||
SPVC_COMPILER_OPTION_MSL_DYNAMIC_OFFSETS_BUFFER_INDEX = 43 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_TEXTURE_1D_AS_2D = 44 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_ENABLE_BASE_INDEX_ZERO = 45 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
/* Obsolete. Use MSL_FRAMEBUFFER_FETCH_SUBPASS instead. */
|
||||
SPVC_COMPILER_OPTION_MSL_IOS_FRAMEBUFFER_FETCH_SUBPASS = 46 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_FRAMEBUFFER_FETCH_SUBPASS = 46 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_INVARIANT_FP_MATH = 47 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_EMULATE_CUBEMAP_ARRAY = 48 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING = 49 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
@@ -596,6 +639,27 @@ typedef enum spvc_compiler_option
|
||||
|
||||
SPVC_COMPILER_OPTION_HLSL_ENABLE_16BIT_TYPES = 60 | SPVC_COMPILER_OPTION_HLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_MULTI_PATCH_WORKGROUP = 61 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_BUFFER_INDEX = 62 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SHADER_INDEX_BUFFER_INDEX = 63 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_VERTEX_FOR_TESSELLATION = 64 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_VERTEX_INDEX_TYPE = 65 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_GLSL_FORCE_FLATTENED_IO_BLOCKS = 66 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_MULTIVIEW_LAYERED_RENDERING = 67 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_ARRAYED_SUBPASS_INPUT = 68 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_R32UI_LINEAR_TEXTURE_ALIGNMENT = 69 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_R32UI_ALIGNMENT_CONSTANT_ID = 70 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_HLSL_FLATTEN_MATRIX_VERTEX_INPUT_SEMANTICS = 71 | SPVC_COMPILER_OPTION_HLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_IOS_USE_SIMDGROUP_FUNCTIONS = 72 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_EMULATE_SUBGROUPS = 73 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_FIXED_SUBGROUP_SIZE = 74 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_FORCE_SAMPLE_RATE_SHADING = 75 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_IOS_SUPPORT_BASE_VERTEX_INSTANCE = 76 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
|
||||
} spvc_compiler_option;
|
||||
|
||||
@@ -698,9 +762,15 @@ 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);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler,
|
||||
const spvc_msl_shader_input *input);
|
||||
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_resource_used(spvc_compiler compiler,
|
||||
SpvExecutionModel model,
|
||||
unsigned set,
|
||||
@@ -718,6 +788,9 @@ SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_dynamic_buffer(spvc_compiler c
|
||||
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_inline_uniform_block(spvc_compiler compiler, unsigned desc_set, unsigned binding);
|
||||
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_combined_sampler_suffix(spvc_compiler compiler, const char *suffix);
|
||||
SPVC_PUBLIC_API const char *spvc_compiler_msl_get_combined_sampler_suffix(spvc_compiler compiler);
|
||||
|
||||
/*
|
||||
* Reflect resources.
|
||||
* Maps almost 1:1 to C++ API.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Hans-Kristian Arntzen
|
||||
* Copyright 2019-2021 Hans-Kristian Arntzen
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_CONTAINERS_HPP
|
||||
#define SPIRV_CROSS_CONTAINERS_HPP
|
||||
|
||||
@@ -63,7 +70,8 @@ public:
|
||||
private:
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
// MSVC 2013 workarounds, sigh ...
|
||||
union {
|
||||
union
|
||||
{
|
||||
char aligned_char[sizeof(T) * N];
|
||||
double dummy_aligner;
|
||||
} u;
|
||||
@@ -211,6 +219,10 @@ public:
|
||||
this->buffer_size = count;
|
||||
}
|
||||
|
||||
SmallVector(std::initializer_list<T> init) SPIRV_CROSS_NOEXCEPT : SmallVector(init.begin(), init.end())
|
||||
{
|
||||
}
|
||||
|
||||
SmallVector(SmallVector &&other) SPIRV_CROSS_NOEXCEPT : SmallVector()
|
||||
{
|
||||
*this = std::move(other);
|
||||
@@ -327,8 +339,9 @@ public:
|
||||
size_t target_capacity = buffer_capacity;
|
||||
if (target_capacity == 0)
|
||||
target_capacity = 1;
|
||||
if (target_capacity < N)
|
||||
target_capacity = N;
|
||||
|
||||
// Weird parens works around macro issues on Windows if NOMINMAX is not used.
|
||||
target_capacity = (std::max)(target_capacity, N);
|
||||
|
||||
// Need to ensure there is a POT value of target capacity which is larger than count,
|
||||
// otherwise this will overflow.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2020 Arm Limited
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_ERROR_HANDLING
|
||||
#define SPIRV_CROSS_ERROR_HANDLING
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2020 Arm Limited
|
||||
* Copyright 2018-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#include "spirv_cross_parsed_ir.hpp"
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
@@ -74,6 +81,8 @@ ParsedIR &ParsedIR::operator=(ParsedIR &&other) SPIRV_CROSS_NOEXCEPT
|
||||
source = other.source;
|
||||
loop_iteration_depth_hard = other.loop_iteration_depth_hard;
|
||||
loop_iteration_depth_soft = other.loop_iteration_depth_soft;
|
||||
|
||||
meta_needing_name_fixup = std::move(other.meta_needing_name_fixup);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -106,6 +115,8 @@ ParsedIR &ParsedIR::operator=(const ParsedIR &other)
|
||||
addressing_model = other.addressing_model;
|
||||
memory_model = other.memory_model;
|
||||
|
||||
meta_needing_name_fixup = other.meta_needing_name_fixup;
|
||||
|
||||
// Very deliberate copying of IDs. There is no default copy constructor, nor a simple default constructor.
|
||||
// Construct object first so we have the correct allocator set-up, then we can copy object into our new pool group.
|
||||
ids.clear();
|
||||
@@ -134,42 +145,151 @@ static bool is_alpha(char c)
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||
}
|
||||
|
||||
static bool is_alphanumeric(char c)
|
||||
static bool is_numeric(char c)
|
||||
{
|
||||
return is_alpha(c) || (c >= '0' && c <= '9');
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
static string ensure_valid_identifier(const string &name, bool member)
|
||||
static bool is_alphanumeric(char c)
|
||||
{
|
||||
return is_alpha(c) || is_numeric(c);
|
||||
}
|
||||
|
||||
static bool is_valid_identifier(const string &name)
|
||||
{
|
||||
if (name.empty())
|
||||
return true;
|
||||
|
||||
if (is_numeric(name[0]))
|
||||
return false;
|
||||
|
||||
for (auto c : name)
|
||||
if (!is_alphanumeric(c) && c != '_')
|
||||
return false;
|
||||
|
||||
bool saw_underscore = false;
|
||||
// Two underscores in a row is not a valid identifier either.
|
||||
// Technically reserved, but it's easier to treat it as invalid.
|
||||
for (auto c : name)
|
||||
{
|
||||
bool is_underscore = c == '_';
|
||||
if (is_underscore && saw_underscore)
|
||||
return false;
|
||||
saw_underscore = is_underscore;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_reserved_prefix(const string &name)
|
||||
{
|
||||
// Generic reserved identifiers used by the implementation.
|
||||
return name.compare(0, 3, "gl_", 3) == 0 ||
|
||||
// Ignore this case for now, might rewrite internal code to always use spv prefix.
|
||||
//name.compare(0, 11, "SPIRV_Cross", 11) == 0 ||
|
||||
name.compare(0, 3, "spv", 3) == 0;
|
||||
}
|
||||
|
||||
static bool is_reserved_identifier(const string &name, bool member, bool allow_reserved_prefixes)
|
||||
{
|
||||
if (!allow_reserved_prefixes && is_reserved_prefix(name))
|
||||
return true;
|
||||
|
||||
if (member)
|
||||
{
|
||||
// Reserved member identifiers come in one form:
|
||||
// _m[0-9]+$.
|
||||
if (name.size() < 3)
|
||||
return false;
|
||||
|
||||
if (name.compare(0, 2, "_m", 2) != 0)
|
||||
return false;
|
||||
|
||||
size_t index = 2;
|
||||
while (index < name.size() && is_numeric(name[index]))
|
||||
index++;
|
||||
|
||||
return index == name.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reserved non-member identifiers come in two forms:
|
||||
// _[0-9]+$, used for temporaries which map directly to a SPIR-V ID.
|
||||
// _[0-9]+_, used for auxillary temporaries which derived from a SPIR-V ID.
|
||||
if (name.size() < 2)
|
||||
return false;
|
||||
|
||||
if (name[0] != '_' || !is_numeric(name[1]))
|
||||
return false;
|
||||
|
||||
size_t index = 2;
|
||||
while (index < name.size() && is_numeric(name[index]))
|
||||
index++;
|
||||
|
||||
return index == name.size() || (index < name.size() && name[index] == '_');
|
||||
}
|
||||
}
|
||||
|
||||
bool ParsedIR::is_globally_reserved_identifier(std::string &str, bool allow_reserved_prefixes)
|
||||
{
|
||||
return is_reserved_identifier(str, false, allow_reserved_prefixes);
|
||||
}
|
||||
|
||||
uint32_t ParsedIR::get_spirv_version() const
|
||||
{
|
||||
return spirv[1];
|
||||
}
|
||||
|
||||
static string make_unreserved_identifier(const string &name)
|
||||
{
|
||||
if (is_reserved_prefix(name))
|
||||
return "_RESERVED_IDENTIFIER_FIXUP_" + name;
|
||||
else
|
||||
return "_RESERVED_IDENTIFIER_FIXUP" + name;
|
||||
}
|
||||
|
||||
void ParsedIR::sanitize_underscores(std::string &str)
|
||||
{
|
||||
// Compact adjacent underscores to make it valid.
|
||||
auto dst = str.begin();
|
||||
auto src = dst;
|
||||
bool saw_underscore = false;
|
||||
while (src != str.end())
|
||||
{
|
||||
bool is_underscore = *src == '_';
|
||||
if (saw_underscore && is_underscore)
|
||||
{
|
||||
src++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst != src)
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
saw_underscore = is_underscore;
|
||||
}
|
||||
}
|
||||
str.erase(dst, str.end());
|
||||
}
|
||||
|
||||
static string ensure_valid_identifier(const string &name)
|
||||
{
|
||||
// Functions in glslangValidator are mangled with name(<mangled> stuff.
|
||||
// Normally, we would never see '(' in any legal identifiers, so just strip them out.
|
||||
auto str = name.substr(0, name.find('('));
|
||||
|
||||
for (uint32_t i = 0; i < str.size(); i++)
|
||||
{
|
||||
auto &c = str[i];
|
||||
if (str.empty())
|
||||
return str;
|
||||
|
||||
if (member)
|
||||
{
|
||||
// _m<num> variables are reserved by the internal implementation,
|
||||
// otherwise, make sure the name is a valid identifier.
|
||||
if (i == 0)
|
||||
c = is_alpha(c) ? c : '_';
|
||||
else if (i == 2 && str[0] == '_' && str[1] == 'm')
|
||||
c = is_alpha(c) ? c : '_';
|
||||
else
|
||||
c = is_alphanumeric(c) ? c : '_';
|
||||
}
|
||||
else
|
||||
{
|
||||
// _<num> variables are reserved by the internal implementation,
|
||||
// otherwise, make sure the name is a valid identifier.
|
||||
if (i == 0 || (str[0] == '_' && i == 1))
|
||||
c = is_alpha(c) ? c : '_';
|
||||
else
|
||||
c = is_alphanumeric(c) ? c : '_';
|
||||
}
|
||||
}
|
||||
if (is_numeric(str[0]))
|
||||
str[0] = '_';
|
||||
|
||||
for (auto &c : str)
|
||||
if (!is_alphanumeric(c) && c != '_')
|
||||
c = '_';
|
||||
|
||||
ParsedIR::sanitize_underscores(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -195,35 +315,41 @@ const string &ParsedIR::get_member_name(TypeID id, uint32_t index) const
|
||||
return empty_string;
|
||||
}
|
||||
|
||||
void ParsedIR::sanitize_identifier(std::string &name, bool member, bool allow_reserved_prefixes)
|
||||
{
|
||||
if (!is_valid_identifier(name))
|
||||
name = ensure_valid_identifier(name);
|
||||
if (is_reserved_identifier(name, member, allow_reserved_prefixes))
|
||||
name = make_unreserved_identifier(name);
|
||||
}
|
||||
|
||||
void ParsedIR::fixup_reserved_names()
|
||||
{
|
||||
for (uint32_t id : meta_needing_name_fixup)
|
||||
{
|
||||
auto &m = meta[id];
|
||||
sanitize_identifier(m.decoration.alias, false, false);
|
||||
for (auto &memb : m.members)
|
||||
sanitize_identifier(memb.alias, true, false);
|
||||
}
|
||||
meta_needing_name_fixup.clear();
|
||||
}
|
||||
|
||||
void ParsedIR::set_name(ID id, const string &name)
|
||||
{
|
||||
auto &str = meta[id].decoration.alias;
|
||||
str.clear();
|
||||
|
||||
if (name.empty())
|
||||
return;
|
||||
|
||||
// Reserved for temporaries.
|
||||
if (name[0] == '_' && name.size() >= 2 && isdigit(name[1]))
|
||||
return;
|
||||
|
||||
str = ensure_valid_identifier(name, false);
|
||||
auto &m = meta[id];
|
||||
m.decoration.alias = name;
|
||||
if (!is_valid_identifier(name) || is_reserved_identifier(name, false, false))
|
||||
meta_needing_name_fixup.insert(id);
|
||||
}
|
||||
|
||||
void ParsedIR::set_member_name(TypeID id, uint32_t index, const string &name)
|
||||
{
|
||||
meta[id].members.resize(max(meta[id].members.size(), size_t(index) + 1));
|
||||
|
||||
auto &str = meta[id].members[index].alias;
|
||||
str.clear();
|
||||
if (name.empty())
|
||||
return;
|
||||
|
||||
// Reserved for unnamed members.
|
||||
if (name[0] == '_' && name.size() >= 3 && name[1] == 'm' && isdigit(name[2]))
|
||||
return;
|
||||
|
||||
str = ensure_valid_identifier(name, true);
|
||||
auto &m = meta[id];
|
||||
m.members.resize(max(meta[id].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);
|
||||
}
|
||||
|
||||
void ParsedIR::set_decoration_string(ID id, Decoration decoration, const string &argument)
|
||||
@@ -274,6 +400,10 @@ void ParsedIR::set_decoration(ID id, Decoration decoration, uint32_t argument)
|
||||
dec.xfb_stride = argument;
|
||||
break;
|
||||
|
||||
case DecorationStream:
|
||||
dec.stream = argument;
|
||||
break;
|
||||
|
||||
case DecorationArrayStride:
|
||||
dec.array_stride = argument;
|
||||
break;
|
||||
@@ -353,6 +483,10 @@ void ParsedIR::set_member_decoration(TypeID id, uint32_t index, Decoration decor
|
||||
dec.xfb_stride = argument;
|
||||
break;
|
||||
|
||||
case DecorationStream:
|
||||
dec.stream = argument;
|
||||
break;
|
||||
|
||||
case DecorationSpecId:
|
||||
dec.spec_id = argument;
|
||||
break;
|
||||
@@ -404,6 +538,17 @@ void ParsedIR::mark_used_as_array_length(ID id)
|
||||
}
|
||||
}
|
||||
|
||||
Bitset ParsedIR::get_buffer_block_type_flags(const SPIRType &type) const
|
||||
{
|
||||
if (type.member_types.empty())
|
||||
return {};
|
||||
|
||||
Bitset all_members_flags = get_member_decoration_bitset(type.self, 0);
|
||||
for (uint32_t i = 1; i < uint32_t(type.member_types.size()); i++)
|
||||
all_members_flags.merge_and(get_member_decoration_bitset(type.self, i));
|
||||
return all_members_flags;
|
||||
}
|
||||
|
||||
Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const
|
||||
{
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
@@ -420,10 +565,7 @@ Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const
|
||||
if (type.member_types.empty())
|
||||
return base_flags;
|
||||
|
||||
Bitset all_members_flags = get_member_decoration_bitset(type.self, 0);
|
||||
for (uint32_t i = 1; i < uint32_t(type.member_types.size()); i++)
|
||||
all_members_flags.merge_and(get_member_decoration_bitset(type.self, i));
|
||||
|
||||
auto all_members_flags = get_buffer_block_type_flags(type);
|
||||
base_flags.merge_or(all_members_flags);
|
||||
return base_flags;
|
||||
}
|
||||
@@ -470,6 +612,8 @@ uint32_t ParsedIR::get_decoration(ID id, Decoration decoration) const
|
||||
return dec.xfb_buffer;
|
||||
case DecorationXfbStride:
|
||||
return dec.xfb_stride;
|
||||
case DecorationStream:
|
||||
return dec.stream;
|
||||
case DecorationBinding:
|
||||
return dec.binding;
|
||||
case DecorationDescriptorSet:
|
||||
@@ -542,6 +686,10 @@ void ParsedIR::unset_decoration(ID id, Decoration decoration)
|
||||
dec.xfb_stride = 0;
|
||||
break;
|
||||
|
||||
case DecorationStream:
|
||||
dec.stream = 0;
|
||||
break;
|
||||
|
||||
case DecorationBinding:
|
||||
dec.binding = 0;
|
||||
break;
|
||||
@@ -616,6 +764,8 @@ uint32_t ParsedIR::get_member_decoration(TypeID id, uint32_t index, Decoration d
|
||||
return dec.xfb_buffer;
|
||||
case DecorationXfbStride:
|
||||
return dec.xfb_stride;
|
||||
case DecorationStream:
|
||||
return dec.stream;
|
||||
case DecorationSpecId:
|
||||
return dec.spec_id;
|
||||
case DecorationIndex:
|
||||
@@ -712,6 +862,10 @@ void ParsedIR::unset_member_decoration(TypeID id, uint32_t index, Decoration dec
|
||||
dec.xfb_stride = 0;
|
||||
break;
|
||||
|
||||
case DecorationStream:
|
||||
dec.stream = 0;
|
||||
break;
|
||||
|
||||
case DecorationSpecId:
|
||||
dec.spec_id = 0;
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2020 Arm Limited
|
||||
* Copyright 2018-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_PARSED_IR_HPP
|
||||
#define SPIRV_CROSS_PARSED_IR_HPP
|
||||
|
||||
@@ -139,6 +146,7 @@ public:
|
||||
void mark_used_as_array_length(ID id);
|
||||
uint32_t increase_bound_by(uint32_t count);
|
||||
Bitset get_buffer_block_flags(const SPIRVariable &var) const;
|
||||
Bitset get_buffer_block_type_flags(const SPIRType &type) const;
|
||||
|
||||
void add_typed_id(Types type, ID id);
|
||||
void remove_typed_id(Types type, ID id);
|
||||
@@ -208,6 +216,14 @@ public:
|
||||
|
||||
void make_constant_null(uint32_t id, uint32_t type, bool add_to_typed_id_set);
|
||||
|
||||
void fixup_reserved_names();
|
||||
|
||||
static void sanitize_underscores(std::string &str);
|
||||
static void sanitize_identifier(std::string &str, bool member, bool allow_reserved_prefixes);
|
||||
static bool is_globally_reserved_identifier(std::string &str, bool allow_reserved_prefixes);
|
||||
|
||||
uint32_t get_spirv_version() const;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
T &get(uint32_t id)
|
||||
@@ -225,6 +241,8 @@ private:
|
||||
mutable uint32_t loop_iteration_depth_soft = 0;
|
||||
std::string empty_string;
|
||||
Bitset cleared_bitset;
|
||||
|
||||
std::unordered_set<uint32_t> meta_needing_name_fixup;
|
||||
};
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2020 Arm Limited
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#include "spirv_cross_util.hpp"
|
||||
#include "spirv_common.hpp"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2020 Arm Limited
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_UTIL_HPP
|
||||
#define SPIRV_CROSS_UTIL_HPP
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2020 Arm Limited
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_GLSL_HPP
|
||||
#define SPIRV_CROSS_GLSL_HPP
|
||||
|
||||
@@ -57,7 +64,8 @@ enum AccessChainFlagBits
|
||||
ACCESS_CHAIN_CHAIN_ONLY_BIT = 1 << 1,
|
||||
ACCESS_CHAIN_PTR_CHAIN_BIT = 1 << 2,
|
||||
ACCESS_CHAIN_SKIP_REGISTER_EXPRESSION_READ_BIT = 1 << 3,
|
||||
ACCESS_CHAIN_LITERAL_MSB_FORCE_ID = 1 << 4
|
||||
ACCESS_CHAIN_LITERAL_MSB_FORCE_ID = 1 << 4,
|
||||
ACCESS_CHAIN_FLATTEN_ALL_MEMBERS_BIT = 1 << 5
|
||||
};
|
||||
typedef uint32_t AccessChainFlags;
|
||||
|
||||
@@ -120,6 +128,10 @@ public:
|
||||
// which would otherwise be uninitialized will now be initialized to 0 instead.
|
||||
bool force_zero_initialized_variables = false;
|
||||
|
||||
// In GLSL, force use of I/O block flattening, similar to
|
||||
// what happens on legacy GLSL targets for blocks and structs.
|
||||
bool force_flattened_io_blocks = false;
|
||||
|
||||
enum Precision
|
||||
{
|
||||
DontCare,
|
||||
@@ -128,14 +140,16 @@ public:
|
||||
Highp
|
||||
};
|
||||
|
||||
struct
|
||||
struct VertexOptions
|
||||
{
|
||||
// GLSL: In vertex shaders, rewrite [0, w] depth (Vulkan/D3D style) to [-w, w] depth (GL style).
|
||||
// MSL: In vertex shaders, rewrite [-w, w] depth (GL style) to [0, w] depth.
|
||||
// HLSL: In vertex shaders, rewrite [-w, w] depth (GL style) to [0, w] depth.
|
||||
// "Vertex-like shader" here is any shader stage that can write BuiltInPosition.
|
||||
|
||||
// GLSL: In vertex-like shaders, rewrite [0, w] depth (Vulkan/D3D style) to [-w, w] depth (GL style).
|
||||
// MSL: In vertex-like shaders, rewrite [-w, w] depth (GL style) to [0, w] depth.
|
||||
// HLSL: In vertex-like shaders, rewrite [-w, w] depth (GL style) to [0, w] depth.
|
||||
bool fixup_clipspace = false;
|
||||
|
||||
// Inverts gl_Position.y or equivalent.
|
||||
// In vertex-like shaders, inverts gl_Position.y or equivalent.
|
||||
bool flip_vert_y = false;
|
||||
|
||||
// GLSL only, for HLSL version of this option, see CompilerHLSL.
|
||||
@@ -145,7 +159,7 @@ public:
|
||||
bool support_nonzero_base_instance = true;
|
||||
} vertex;
|
||||
|
||||
struct
|
||||
struct FragmentOptions
|
||||
{
|
||||
// Add precision mediump float in ES targets when emitting GLES source.
|
||||
// Add precision highp int in ES targets when emitting GLES source.
|
||||
@@ -237,6 +251,82 @@ public:
|
||||
bool variable_is_depth_or_compare(VariableID id) const;
|
||||
|
||||
protected:
|
||||
struct ShaderSubgroupSupportHelper
|
||||
{
|
||||
// lower enum value = greater priority
|
||||
enum Candidate
|
||||
{
|
||||
KHR_shader_subgroup_ballot,
|
||||
KHR_shader_subgroup_basic,
|
||||
KHR_shader_subgroup_vote,
|
||||
NV_gpu_shader_5,
|
||||
NV_shader_thread_group,
|
||||
NV_shader_thread_shuffle,
|
||||
ARB_shader_ballot,
|
||||
ARB_shader_group_vote,
|
||||
AMD_gcn_shader,
|
||||
|
||||
CandidateCount
|
||||
};
|
||||
|
||||
static const char *get_extension_name(Candidate c);
|
||||
static SmallVector<std::string> get_extra_required_extension_names(Candidate c);
|
||||
static const char *get_extra_required_extension_predicate(Candidate c);
|
||||
|
||||
enum Feature
|
||||
{
|
||||
SubgroupMask = 0,
|
||||
SubgroupSize = 1,
|
||||
SubgroupInvocationID = 2,
|
||||
SubgroupID = 3,
|
||||
NumSubgroups = 4,
|
||||
SubgroupBroadcast_First = 5,
|
||||
SubgroupBallotFindLSB_MSB = 6,
|
||||
SubgroupAll_Any_AllEqualBool = 7,
|
||||
SubgroupAllEqualT = 8,
|
||||
SubgroupElect = 9,
|
||||
SubgroupBarrier = 10,
|
||||
SubgroupMemBarrier = 11,
|
||||
SubgroupBallot = 12,
|
||||
SubgroupInverseBallot_InclBitCount_ExclBitCout = 13,
|
||||
SubgroupBallotBitExtract = 14,
|
||||
SubgroupBallotBitCount = 15,
|
||||
|
||||
FeatureCount
|
||||
};
|
||||
|
||||
using FeatureMask = uint32_t;
|
||||
static_assert(sizeof(FeatureMask) * 8u >= FeatureCount, "Mask type needs more bits.");
|
||||
|
||||
using CandidateVector = SmallVector<Candidate, CandidateCount>;
|
||||
using FeatureVector = SmallVector<Feature>;
|
||||
|
||||
static FeatureVector get_feature_dependencies(Feature feature);
|
||||
static FeatureMask get_feature_dependency_mask(Feature feature);
|
||||
static bool can_feature_be_implemented_without_extensions(Feature feature);
|
||||
static Candidate get_KHR_extension_for_feature(Feature feature);
|
||||
|
||||
struct Result
|
||||
{
|
||||
Result();
|
||||
uint32_t weights[CandidateCount];
|
||||
};
|
||||
|
||||
void request_feature(Feature feature);
|
||||
bool is_feature_requested(Feature feature) const;
|
||||
Result resolve() const;
|
||||
|
||||
static CandidateVector get_candidates_for_feature(Feature ft, const Result &r);
|
||||
|
||||
private:
|
||||
static CandidateVector get_candidates_for_feature(Feature ft);
|
||||
static FeatureMask build_mask(const SmallVector<Feature> &features);
|
||||
FeatureMask feature_mask = 0;
|
||||
};
|
||||
|
||||
// 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);
|
||||
|
||||
void reset();
|
||||
void emit_function(SPIRFunction &func, const Bitset &return_flags);
|
||||
|
||||
@@ -267,9 +357,11 @@ protected:
|
||||
void build_workgroup_size(SmallVector<std::string> &arguments, const SpecializationConstant &x,
|
||||
const SpecializationConstant &y, const SpecializationConstant &z);
|
||||
|
||||
void request_subgroup_feature(ShaderSubgroupSupportHelper::Feature feature);
|
||||
|
||||
virtual void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id);
|
||||
virtual void emit_texture_op(const Instruction &i);
|
||||
virtual std::string to_texture_op(const Instruction &i, bool *forward,
|
||||
virtual void emit_texture_op(const Instruction &i, bool sparse);
|
||||
virtual std::string to_texture_op(const Instruction &i, bool sparse, bool *forward,
|
||||
SmallVector<uint32_t> &inherited_expressions);
|
||||
virtual void emit_subgroup_op(const Instruction &i);
|
||||
virtual std::string type_to_glsl(const SPIRType &type, uint32_t id = 0);
|
||||
@@ -284,14 +376,42 @@ protected:
|
||||
virtual void emit_fixup();
|
||||
virtual std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0);
|
||||
virtual std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id);
|
||||
virtual std::string to_function_name(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
|
||||
bool is_proj, bool has_array_offsets, bool has_offset, bool has_grad,
|
||||
bool has_dref, uint32_t lod, uint32_t minlod);
|
||||
virtual std::string to_function_args(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
|
||||
bool is_proj, uint32_t coord, uint32_t coord_components, uint32_t dref,
|
||||
uint32_t grad_x, uint32_t grad_y, uint32_t lod, uint32_t coffset,
|
||||
uint32_t offset, uint32_t bias, uint32_t comp, uint32_t sample,
|
||||
uint32_t minlod, bool *p_forward);
|
||||
|
||||
struct TextureFunctionBaseArguments
|
||||
{
|
||||
// GCC 4.8 workarounds, it doesn't understand '{}' constructor here, use explicit default constructor.
|
||||
TextureFunctionBaseArguments() = default;
|
||||
VariableID img = 0;
|
||||
const SPIRType *imgtype = nullptr;
|
||||
bool is_fetch = false, is_gather = false, is_proj = false;
|
||||
};
|
||||
|
||||
struct TextureFunctionNameArguments
|
||||
{
|
||||
// GCC 4.8 workarounds, it doesn't understand '{}' constructor here, use explicit default constructor.
|
||||
TextureFunctionNameArguments() = default;
|
||||
TextureFunctionBaseArguments base;
|
||||
bool has_array_offsets = false, has_offset = false, has_grad = false;
|
||||
bool has_dref = false, is_sparse_feedback = false, has_min_lod = false;
|
||||
uint32_t lod = 0;
|
||||
};
|
||||
virtual std::string to_function_name(const TextureFunctionNameArguments &args);
|
||||
|
||||
struct TextureFunctionArguments
|
||||
{
|
||||
// GCC 4.8 workarounds, it doesn't understand '{}' constructor here, use explicit default constructor.
|
||||
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 bias = 0, component = 0, sample = 0, sparse_texel = 0, min_lod = 0;
|
||||
bool nonuniform_expression = false;
|
||||
};
|
||||
virtual std::string to_function_args(const TextureFunctionArguments &args, bool *p_forward);
|
||||
|
||||
void emit_sparse_feedback_temporaries(uint32_t result_type_id, uint32_t id, uint32_t &feedback_id,
|
||||
uint32_t &texel_id);
|
||||
uint32_t get_sparse_feedback_texel_id(uint32_t id) const;
|
||||
virtual void emit_buffer_block(const SPIRVariable &type);
|
||||
virtual void emit_push_constant_block(const SPIRVariable &var);
|
||||
virtual void emit_uniform(const SPIRVariable &var);
|
||||
@@ -441,25 +561,34 @@ protected:
|
||||
bool supports_extensions = false;
|
||||
bool supports_empty_struct = false;
|
||||
bool array_is_value_type = true;
|
||||
bool buffer_offset_array_is_value_type = true;
|
||||
bool comparison_image_samples_scalar = false;
|
||||
bool native_pointers = false;
|
||||
bool support_small_type_sampling_result = false;
|
||||
bool support_case_fallthrough = true;
|
||||
bool use_array_constructor = false;
|
||||
bool needs_row_major_load_workaround = false;
|
||||
bool support_pointer_to_pointer = false;
|
||||
} backend;
|
||||
|
||||
void emit_struct(SPIRType &type);
|
||||
void emit_resources();
|
||||
void emit_extension_workarounds(spv::ExecutionModel model);
|
||||
void emit_buffer_block_native(const SPIRVariable &var);
|
||||
void emit_buffer_reference_block(SPIRType &type, 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 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);
|
||||
void emit_push_constant_block_glsl(const SPIRVariable &var);
|
||||
void emit_interface_block(const SPIRVariable &type);
|
||||
void emit_flattened_io_block(const SPIRVariable &var, const char *qual);
|
||||
void emit_flattened_io_block_struct(const std::string &basename, const SPIRType &type, const char *qual,
|
||||
const SmallVector<uint32_t> &indices);
|
||||
void emit_flattened_io_block_member(const std::string &basename, const SPIRType &type, const char *qual,
|
||||
const SmallVector<uint32_t> &indices);
|
||||
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);
|
||||
@@ -522,6 +651,7 @@ protected:
|
||||
void emit_unary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op);
|
||||
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;
|
||||
SPIRExpression &emit_op(uint32_t result_type, uint32_t result_id, const std::string &rhs, bool forward_rhs,
|
||||
bool suppress_usage_tracking = false);
|
||||
|
||||
@@ -531,6 +661,9 @@ protected:
|
||||
std::string access_chain_internal(uint32_t base, const uint32_t *indices, uint32_t count, AccessChainFlags flags,
|
||||
AccessChainMeta *meta);
|
||||
|
||||
virtual void 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,
|
||||
AccessChainMeta *meta = nullptr, bool ptr_chain = false);
|
||||
|
||||
@@ -559,7 +692,7 @@ protected:
|
||||
SPIRExpression &emit_uninitialized_temporary_expression(uint32_t type, uint32_t id);
|
||||
void append_global_func_args(const SPIRFunction &func, uint32_t index, SmallVector<std::string> &arglist);
|
||||
std::string to_expression(uint32_t id, bool register_expression_read = true);
|
||||
std::string to_composite_constructor_expression(uint32_t id);
|
||||
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_enclosed_expression(uint32_t id, bool register_expression_read = true);
|
||||
std::string to_unpacked_expression(uint32_t id, bool register_expression_read = true);
|
||||
@@ -569,15 +702,20 @@ protected:
|
||||
std::string to_pointer_expression(uint32_t id, bool register_expression_read = true);
|
||||
std::string to_enclosed_pointer_expression(uint32_t id, bool register_expression_read = true);
|
||||
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);
|
||||
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);
|
||||
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 emit_output_variable_initializer(const SPIRVariable &var);
|
||||
const char *to_precision_qualifiers_glsl(uint32_t id);
|
||||
virtual const char *to_storage_qualifiers_glsl(const SPIRVariable &var);
|
||||
const char *flags_to_qualifiers_glsl(const SPIRType &type, const Bitset &flags);
|
||||
@@ -624,8 +762,7 @@ protected:
|
||||
|
||||
void replace_fragment_output(SPIRVariable &var);
|
||||
void replace_fragment_outputs();
|
||||
bool check_explicit_lod_allowed(uint32_t lod);
|
||||
std::string legacy_tex_op(const std::string &op, const SPIRType &imgtype, uint32_t lod, uint32_t id);
|
||||
std::string legacy_tex_op(const std::string &op, const SPIRType &imgtype, uint32_t id);
|
||||
|
||||
uint32_t indent = 0;
|
||||
|
||||
@@ -635,11 +772,16 @@ protected:
|
||||
std::unordered_set<uint32_t> flushed_phi_variables;
|
||||
|
||||
std::unordered_set<uint32_t> flattened_buffer_blocks;
|
||||
std::unordered_set<uint32_t> flattened_structs;
|
||||
std::unordered_map<uint32_t, bool> flattened_structs;
|
||||
|
||||
std::string load_flattened_struct(SPIRVariable &var);
|
||||
std::string to_flattened_struct_member(const SPIRVariable &var, uint32_t index);
|
||||
void store_flattened_struct(SPIRVariable &var, uint32_t value);
|
||||
ShaderSubgroupSupportHelper shader_subgroup_supporter;
|
||||
|
||||
std::string load_flattened_struct(const std::string &basename, const SPIRType &type);
|
||||
std::string to_flattened_struct_member(const std::string &basename, const SPIRType &type, uint32_t index);
|
||||
void store_flattened_struct(uint32_t lhs_id, uint32_t value);
|
||||
void store_flattened_struct(const std::string &basename, uint32_t rhs, const SPIRType &type,
|
||||
const SmallVector<uint32_t> &indices);
|
||||
std::string to_flattened_access_chain_expression(uint32_t id);
|
||||
|
||||
// Usage tracking. If a temporary is used more than once, use the temporary instead to
|
||||
// avoid AST explosion when SPIRV is generated with pure SSA and doesn't write stuff to variables.
|
||||
@@ -654,6 +796,10 @@ protected:
|
||||
// Currently used by NMin/Max/Clamp implementations.
|
||||
std::unordered_map<uint32_t, uint32_t> extra_sub_expressions;
|
||||
|
||||
SmallVector<TypeID> workaround_ubo_load_overload_types;
|
||||
void request_workaround_wrapper_overload(TypeID id);
|
||||
void rewrite_load_for_wrapped_row_major(std::string &expr, TypeID loaded_type, ID ptr);
|
||||
|
||||
uint32_t statement_count = 0;
|
||||
|
||||
inline bool is_legacy() const
|
||||
@@ -671,6 +817,12 @@ protected:
|
||||
return !options.es && options.version < 130;
|
||||
}
|
||||
|
||||
bool requires_transpose_2x2 = false;
|
||||
bool requires_transpose_3x3 = false;
|
||||
bool requires_transpose_4x4 = false;
|
||||
bool ray_tracing_is_khr = false;
|
||||
void ray_tracing_khr_fixup_locations();
|
||||
|
||||
bool args_will_forward(uint32_t id, const uint32_t *args, uint32_t num_args, bool pure);
|
||||
void register_call_out_argument(uint32_t id);
|
||||
void register_impure_function_call();
|
||||
@@ -712,8 +864,6 @@ protected:
|
||||
|
||||
virtual void declare_undefined_values();
|
||||
|
||||
static std::string sanitize_underscores(const std::string &str);
|
||||
|
||||
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);
|
||||
@@ -726,16 +876,18 @@ 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 bitcasts on load and store to make this work.
|
||||
virtual void bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type);
|
||||
virtual void bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type);
|
||||
// Sometimes we will need to automatically perform casts on load and store to make this work.
|
||||
virtual void cast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type);
|
||||
virtual void cast_from_builtin_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);
|
||||
bool unroll_array_to_complex_store(uint32_t target_id, uint32_t source_id);
|
||||
void convert_non_uniform_expression(const SPIRType &type, std::string &expr);
|
||||
|
||||
void handle_store_to_invariant_variable(uint32_t store_id, uint32_t value_id);
|
||||
void disallow_forwarding_in_expression_chain(const SPIRExpression &expr);
|
||||
|
||||
bool expression_is_constant_null(uint32_t id) const;
|
||||
bool expression_is_non_value_type_array(uint32_t ptr);
|
||||
virtual void emit_store_statement(uint32_t lhs_expression, uint32_t rhs_expression);
|
||||
|
||||
uint32_t get_integer_width_for_instruction(const Instruction &instr) const;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2020 Robert Konrad
|
||||
* Copyright 2016-2021 Robert Konrad
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_HLSL_HPP
|
||||
#define SPIRV_HLSL_HPP
|
||||
|
||||
@@ -124,6 +131,12 @@ public:
|
||||
// Uses half/int16_t/uint16_t instead of min16* types.
|
||||
// Also adds support for 16-bit load-store from (RW)ByteAddressBuffer.
|
||||
bool enable_16bit_types = false;
|
||||
|
||||
// If matrices are used as IO variables, flatten the attribute declaration to use
|
||||
// TEXCOORD{N,N+1,N+2,...} rather than TEXCOORDN_{0,1,2,3}.
|
||||
// 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;
|
||||
};
|
||||
|
||||
explicit CompilerHLSL(std::vector<uint32_t> spirv_)
|
||||
@@ -209,7 +222,7 @@ private:
|
||||
void emit_interface_block_in_struct(const SPIRVariable &type, std::unordered_set<uint32_t> &active_locations);
|
||||
void emit_builtin_inputs_in_struct();
|
||||
void emit_builtin_outputs_in_struct();
|
||||
void emit_texture_op(const Instruction &i) override;
|
||||
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,
|
||||
uint32_t count) override;
|
||||
@@ -231,6 +244,7 @@ private:
|
||||
std::string to_resource_binding(const SPIRVariable &var);
|
||||
std::string to_resource_binding_sampler(const SPIRVariable &var);
|
||||
std::string to_resource_register(HLSLBindingFlagBits flag, char space, uint32_t binding, uint32_t set);
|
||||
std::string to_initializer_expression(const SPIRVariable &var) override;
|
||||
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
||||
void emit_access_chain(const Instruction &instruction);
|
||||
void emit_load(const Instruction &instruction);
|
||||
@@ -291,7 +305,8 @@ private:
|
||||
} required_texture_size_variants;
|
||||
|
||||
void require_texture_query_variant(uint32_t var_id);
|
||||
void emit_texture_size_variants(uint64_t variant_mask, const char *vecsize_qualifier, bool uav, const char *type_qualifier);
|
||||
void emit_texture_size_variants(uint64_t variant_mask, const char *vecsize_qualifier, bool uav,
|
||||
const char *type_qualifier);
|
||||
|
||||
enum TextureQueryVariantDim
|
||||
{
|
||||
@@ -351,6 +366,9 @@ private:
|
||||
void remap_hlsl_resource_binding(HLSLBindingFlagBits type, uint32_t &desc_set, uint32_t &binding);
|
||||
|
||||
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;
|
||||
};
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
|
||||
+3024
-795
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2020 The Brenwill Workshop Ltd.
|
||||
* Copyright 2016-2021 The Brenwill Workshop Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_MSL_HPP
|
||||
#define SPIRV_CROSS_MSL_HPP
|
||||
|
||||
@@ -27,29 +34,44 @@
|
||||
namespace SPIRV_CROSS_NAMESPACE
|
||||
{
|
||||
|
||||
// Indicates the format of the vertex attribute. Currently limited to specifying
|
||||
// if the attribute is an 8-bit unsigned integer, 16-bit unsigned integer, or
|
||||
// Indicates the format of a shader input. Currently limited to specifying
|
||||
// if the input is an 8-bit unsigned integer, 16-bit unsigned integer, or
|
||||
// some other format.
|
||||
enum MSLVertexFormat
|
||||
enum MSLShaderInputFormat
|
||||
{
|
||||
MSL_VERTEX_FORMAT_OTHER = 0,
|
||||
MSL_VERTEX_FORMAT_UINT8 = 1,
|
||||
MSL_VERTEX_FORMAT_UINT16 = 2,
|
||||
MSL_VERTEX_FORMAT_INT_MAX = 0x7fffffff
|
||||
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,
|
||||
|
||||
// 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_SHADER_INPUT_FORMAT_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
// Defines MSL characteristics of a vertex attribute at a particular location.
|
||||
// Defines MSL characteristics of an input variable at a particular location.
|
||||
// After compilation, it is possible to query whether or not this location was used.
|
||||
struct MSLVertexAttr
|
||||
// If vecsize is nonzero, it must be greater than or equal to the vecsize declared in the shader,
|
||||
// or behavior is undefined.
|
||||
struct MSLShaderInput
|
||||
{
|
||||
uint32_t location = 0;
|
||||
MSLVertexFormat format = MSL_VERTEX_FORMAT_OTHER;
|
||||
MSLShaderInputFormat format = MSL_SHADER_INPUT_FORMAT_OTHER;
|
||||
spv::BuiltIn builtin = spv::BuiltInMax;
|
||||
uint32_t vecsize = 0;
|
||||
};
|
||||
|
||||
// Matches the binding index of a MSL resource for a binding within a descriptor set.
|
||||
// Taken together, the stage, desc_set and binding combine to form a reference to a resource
|
||||
// descriptor used in a particular shading stage.
|
||||
// descriptor used in a particular shading stage. The count field indicates the number of
|
||||
// resources consumed by this binding, if the binding represents an array of resources.
|
||||
// If the resource array is a run-time-sized array, which are legal in GLSL or SPIR-V, this value
|
||||
// will be used to declare the array size in MSL, which does not support run-time-sized arrays.
|
||||
// For resources that are not held in a run-time-sized array, the count field does not need to be populated.
|
||||
// If using MSL 2.0 argument buffers, the descriptor set is not marked as a discrete descriptor set,
|
||||
// and (for iOS only) the resource is not a storage image (sampled != 2), the binding reference we
|
||||
// remap to will become an [[id(N)]] attribute within the "descriptor set" argument buffer structure.
|
||||
@@ -60,6 +82,7 @@ struct MSLResourceBinding
|
||||
spv::ExecutionModel stage = spv::ExecutionModelMax;
|
||||
uint32_t desc_set = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t count = 0;
|
||||
uint32_t msl_buffer = 0;
|
||||
uint32_t msl_texture = 0;
|
||||
uint32_t msl_sampler = 0;
|
||||
@@ -238,6 +261,9 @@ static const uint32_t kArgumentBufferBinding = ~(3u);
|
||||
|
||||
static const uint32_t kMaxArgumentBuffers = 8;
|
||||
|
||||
// The arbitrary maximum for the nesting of array of array copies.
|
||||
static const uint32_t kArrayCopyMultidimMax = 6;
|
||||
|
||||
// Decompiles SPIR-V to Metal Shading Language
|
||||
class CompilerMSL : public CompilerGLSL
|
||||
{
|
||||
@@ -254,6 +280,8 @@ public:
|
||||
Platform platform = macOS;
|
||||
uint32_t msl_version = make_msl_version(1, 2);
|
||||
uint32_t texel_buffer_texture_width = 4096; // Width of 2D Metal textures used as 1D texel buffers
|
||||
uint32_t r32ui_linear_texture_alignment = 4;
|
||||
uint32_t r32ui_alignment_constant_id = 65535;
|
||||
uint32_t swizzle_buffer_index = 30;
|
||||
uint32_t indirect_params_buffer_index = 29;
|
||||
uint32_t shader_output_buffer_index = 28;
|
||||
@@ -262,9 +290,15 @@ public:
|
||||
uint32_t buffer_size_buffer_index = 25;
|
||||
uint32_t view_mask_buffer_index = 24;
|
||||
uint32_t dynamic_offsets_buffer_index = 23;
|
||||
uint32_t shader_input_buffer_index = 22;
|
||||
uint32_t shader_index_buffer_index = 21;
|
||||
uint32_t shader_input_wg_index = 0;
|
||||
uint32_t device_index = 0;
|
||||
uint32_t enable_frag_output_mask = 0xffffffff;
|
||||
// Metal doesn't allow setting a fixed sample mask directly in the pipeline.
|
||||
// We can evade this restriction by ANDing the internal sample_mask output
|
||||
// of the shader with the additional fixed sample mask.
|
||||
uint32_t additional_fixed_sample_mask = 0xffffffff;
|
||||
bool enable_point_size_builtin = true;
|
||||
bool enable_frag_depth_builtin = true;
|
||||
bool enable_frag_stencil_ref_builtin = true;
|
||||
@@ -273,6 +307,7 @@ public:
|
||||
bool swizzle_texture_samples = false;
|
||||
bool tess_domain_origin_lower_left = false;
|
||||
bool multiview = false;
|
||||
bool multiview_layered_rendering = true;
|
||||
bool view_index_from_device_index = false;
|
||||
bool dispatch_base = false;
|
||||
bool texture_1D_as_2D = false;
|
||||
@@ -292,7 +327,7 @@ public:
|
||||
bool ios_support_base_vertex_instance = false;
|
||||
|
||||
// Use Metal's native frame-buffer fetch API for subpass inputs.
|
||||
bool ios_use_framebuffer_fetch_subpasses = false;
|
||||
bool use_framebuffer_fetch_subpasses = false;
|
||||
|
||||
// Enables use of "fma" intrinsic for invariant float math
|
||||
bool invariant_float_math = false;
|
||||
@@ -320,6 +355,64 @@ public:
|
||||
// can be read in subsequent stages.
|
||||
bool enable_clip_distance_user_varying = true;
|
||||
|
||||
// In a tessellation control shader, assume that more than one patch can be processed in a
|
||||
// single workgroup. This requires changes to the way the InvocationId and PrimitiveId
|
||||
// builtins are processed, but should result in more efficient usage of the GPU.
|
||||
bool multi_patch_workgroup = 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.
|
||||
bool vertex_for_tessellation = false;
|
||||
|
||||
// Assume that SubpassData images have multiple layers. Layered input attachments
|
||||
// are addressed relative to the Layer output from the vertex pipeline. This option
|
||||
// has no effect with multiview, since all input attachments are assumed to be layered
|
||||
// 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
|
||||
// operations. Some GPUs on iOS do not support the SIMD-group functions, only the
|
||||
// quadgroup functions.
|
||||
bool ios_use_simdgroup_functions = false;
|
||||
|
||||
// If set, the subgroup size will be assumed to be one, and subgroup-related
|
||||
// builtins and operations will be emitted accordingly. This mode is intended to
|
||||
// be used by MoltenVK on hardware/software configurations which do not provide
|
||||
// sufficient support for subgroups.
|
||||
bool emulate_subgroups = false;
|
||||
|
||||
// If nonzero, a fixed subgroup size to assume. Metal, similarly to VK_EXT_subgroup_size_control,
|
||||
// allows the SIMD-group size (aka thread execution width) to vary depending on
|
||||
// register usage and requirements. In certain circumstances--for example, a pipeline
|
||||
// in MoltenVK without VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT--
|
||||
// this is undesirable. This fixes the value of the SubgroupSize builtin, instead of
|
||||
// mapping it to the Metal builtin [[thread_execution_width]]. If the thread
|
||||
// execution width is reduced, the extra invocations will appear to be inactive.
|
||||
// If zero, the SubgroupSize will be allowed to vary, and the builtin will be mapped
|
||||
// to the Metal [[thread_execution_width]] builtin.
|
||||
uint32_t fixed_subgroup_size = 0;
|
||||
|
||||
enum class IndexType
|
||||
{
|
||||
None = 0,
|
||||
UInt16 = 1,
|
||||
UInt32 = 2
|
||||
};
|
||||
|
||||
// The type of index in the index buffer, if present. For a compute shader, Metal
|
||||
// requires specifying the indexing at pipeline creation, rather than at draw time
|
||||
// as with graphics pipelines. This means we must create three different pipelines,
|
||||
// for no indexing, 16-bit indices, and 32-bit indices. Each requires different
|
||||
// handling for the gl_VertexIndex builtin. We may as well, then, create three
|
||||
// different shaders for these three scenarios.
|
||||
IndexType vertex_index_type = IndexType::None;
|
||||
|
||||
// If set, a dummy [[sample_id]] input is added to a fragment shader if none is present.
|
||||
// This will force the shader to run at sample rate, assuming Metal does not optimize
|
||||
// the extra threads away.
|
||||
bool force_sample_rate_shading = false;
|
||||
|
||||
bool is_ios() const
|
||||
{
|
||||
return platform == iOS;
|
||||
@@ -419,11 +512,10 @@ public:
|
||||
explicit CompilerMSL(const ParsedIR &ir);
|
||||
explicit CompilerMSL(ParsedIR &&ir);
|
||||
|
||||
// attr is a vertex attribute binding used to match
|
||||
// vertex content locations to MSL attributes. If vertex attributes are provided,
|
||||
// is_msl_vertex_attribute_used() will return true after calling ::compile() if
|
||||
// the location was used by the MSL code.
|
||||
void add_msl_vertex_attribute(const MSLVertexAttr &attr);
|
||||
// input is a shader input 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);
|
||||
|
||||
// resource is a resource binding to indicate the MSL buffer,
|
||||
// texture or sampler index to use for a particular SPIR-V description set
|
||||
@@ -455,8 +547,15 @@ public:
|
||||
// constant. Opt-in to this behavior here on a per set basis.
|
||||
void set_argument_buffer_device_address_space(uint32_t desc_set, bool device_storage);
|
||||
|
||||
// Query after compilation is done. This allows you to check if a location or set/binding combination was used by the shader.
|
||||
bool is_msl_vertex_attribute_used(uint32_t location);
|
||||
// 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);
|
||||
|
||||
// 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.
|
||||
// This returns k_unknown_location if the location was explicitly assigned with
|
||||
// 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;
|
||||
|
||||
// NOTE: Only resources which are remapped using add_msl_resource_binding will be reported here.
|
||||
// Constexpr samplers are always assumed to be emitted.
|
||||
@@ -475,6 +574,7 @@ public:
|
||||
|
||||
// Same as get_automatic_msl_resource_binding, but should only be used for combined image samplers, in which case the
|
||||
// sampler's binding is returned instead. For any other resource type, -1 is returned.
|
||||
// Secondary bindings are also used for the auxillary image atomic buffer.
|
||||
uint32_t get_automatic_msl_resource_binding_secondary(uint32_t id) const;
|
||||
|
||||
// Same as get_automatic_msl_resource_binding, but should only be used for combined image samplers for multiplanar images,
|
||||
@@ -505,6 +605,9 @@ public:
|
||||
// to use for a particular location. The default is 4 if number of components is not overridden.
|
||||
void set_fragment_output_components(uint32_t location, uint32_t components);
|
||||
|
||||
void set_combined_sampler_suffix(const char *suffix);
|
||||
const char *get_combined_sampler_suffix() const;
|
||||
|
||||
protected:
|
||||
// An enum of SPIR-V functions that are implemented in additional
|
||||
// source code that is added to the shader if necessary.
|
||||
@@ -544,12 +647,20 @@ protected:
|
||||
SPVFuncImplTextureSwizzle,
|
||||
SPVFuncImplGatherSwizzle,
|
||||
SPVFuncImplGatherCompareSwizzle,
|
||||
SPVFuncImplSubgroupBroadcast,
|
||||
SPVFuncImplSubgroupBroadcastFirst,
|
||||
SPVFuncImplSubgroupBallot,
|
||||
SPVFuncImplSubgroupBallotBitExtract,
|
||||
SPVFuncImplSubgroupBallotFindLSB,
|
||||
SPVFuncImplSubgroupBallotFindMSB,
|
||||
SPVFuncImplSubgroupBallotBitCount,
|
||||
SPVFuncImplSubgroupAllEqual,
|
||||
SPVFuncImplSubgroupShuffle,
|
||||
SPVFuncImplSubgroupShuffleXor,
|
||||
SPVFuncImplSubgroupShuffleUp,
|
||||
SPVFuncImplSubgroupShuffleDown,
|
||||
SPVFuncImplQuadBroadcast,
|
||||
SPVFuncImplQuadSwap,
|
||||
SPVFuncImplReflectScalar,
|
||||
SPVFuncImplRefractScalar,
|
||||
SPVFuncImplFaceForwardScalar,
|
||||
@@ -573,13 +684,11 @@ protected:
|
||||
SPVFuncImplConvertYCbCrBT601,
|
||||
SPVFuncImplConvertYCbCrBT2020,
|
||||
SPVFuncImplDynamicImageSampler,
|
||||
|
||||
SPVFuncImplArrayCopyMultidimMax = 6
|
||||
};
|
||||
|
||||
// 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) override;
|
||||
void emit_texture_op(const Instruction &i, bool sparse) override;
|
||||
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,
|
||||
@@ -590,7 +699,7 @@ protected:
|
||||
void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) override;
|
||||
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
||||
void emit_subgroup_op(const Instruction &i) override;
|
||||
std::string to_texture_op(const Instruction &i, bool *forward,
|
||||
std::string to_texture_op(const Instruction &i, bool sparse, bool *forward,
|
||||
SmallVector<uint32_t> &inherited_expressions) override;
|
||||
void emit_fixup() override;
|
||||
std::string to_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||
@@ -610,17 +719,12 @@ protected:
|
||||
std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0) override;
|
||||
|
||||
std::string image_type_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string sampler_type(const SPIRType &type);
|
||||
std::string sampler_type(const SPIRType &type, uint32_t id);
|
||||
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
|
||||
std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) override;
|
||||
std::string to_name(uint32_t id, bool allow_alias = true) const override;
|
||||
std::string to_function_name(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
|
||||
bool has_array_offsets, bool has_offset, bool has_grad, bool has_dref, uint32_t lod,
|
||||
uint32_t minlod) override;
|
||||
std::string to_function_args(VariableID img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
|
||||
uint32_t coord, uint32_t coord_components, uint32_t dref, uint32_t grad_x,
|
||||
uint32_t grad_y, uint32_t lod, uint32_t coffset, uint32_t offset, uint32_t bias,
|
||||
uint32_t comp, uint32_t sample, uint32_t minlod, bool *p_forward) override;
|
||||
std::string to_function_name(const TextureFunctionNameArguments &args) override;
|
||||
std::string to_function_args(const TextureFunctionArguments &args, bool *p_forward) override;
|
||||
std::string to_initializer_expression(const SPIRVariable &var) override;
|
||||
std::string to_zero_initialized_expression(uint32_t type_id) override;
|
||||
|
||||
@@ -639,6 +743,12 @@ protected:
|
||||
void declare_undefined_values() override;
|
||||
void declare_constant_arrays();
|
||||
|
||||
void replace_illegal_entry_point_names();
|
||||
void sync_entry_point_aliases_and_names();
|
||||
|
||||
static const std::unordered_set<std::string> &get_reserved_keyword_set();
|
||||
static const std::unordered_set<std::string> &get_illegal_func_names();
|
||||
|
||||
// Constant arrays of non-primitive types (i.e. matrices) won't link properly into Metal libraries
|
||||
void declare_complex_constant_arrays();
|
||||
|
||||
@@ -689,9 +799,9 @@ protected:
|
||||
|
||||
void fix_up_interface_member_indices(spv::StorageClass storage, uint32_t ib_type_id);
|
||||
|
||||
void mark_location_as_used_by_shader(uint32_t location, spv::StorageClass storage);
|
||||
void mark_location_as_used_by_shader(uint32_t location, const SPIRType &type, spv::StorageClass storage);
|
||||
uint32_t ensure_correct_builtin_type(uint32_t type_id, spv::BuiltIn builtin);
|
||||
uint32_t ensure_correct_attribute_type(uint32_t type_id, uint32_t location, uint32_t num_components = 0);
|
||||
uint32_t ensure_correct_input_type(uint32_t type_id, uint32_t location, uint32_t num_components = 0);
|
||||
|
||||
void emit_custom_templates();
|
||||
void emit_custom_functions();
|
||||
@@ -699,6 +809,7 @@ 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;
|
||||
|
||||
void fix_up_shader_inputs_outputs();
|
||||
|
||||
@@ -713,6 +824,8 @@ protected:
|
||||
std::string to_sampler_expression(uint32_t id);
|
||||
std::string to_swizzle_expression(uint32_t id);
|
||||
std::string to_buffer_size_expression(uint32_t id);
|
||||
bool is_sample_rate() const;
|
||||
bool is_direct_input_builtin(spv::BuiltIn builtin);
|
||||
std::string builtin_qualifier(spv::BuiltIn builtin);
|
||||
std::string builtin_type_decl(spv::BuiltIn builtin, uint32_t id = 0);
|
||||
std::string built_in_func_arg(spv::BuiltIn builtin, bool prefix_comma);
|
||||
@@ -720,7 +833,11 @@ protected:
|
||||
std::string argument_decl(const SPIRFunction::Parameter &arg);
|
||||
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_ordered_member_location(uint32_t type_id, uint32_t index, uint32_t *comp = nullptr);
|
||||
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_physical_tess_level_array_size(spv::BuiltIn builtin) const;
|
||||
|
||||
// MSL packing rules. These compute the effective packing rules as observed by the MSL compiler in the MSL output.
|
||||
// These values can change depending on various extended decorations which control packing rules.
|
||||
@@ -735,7 +852,13 @@ protected:
|
||||
uint32_t get_declared_struct_member_matrix_stride_msl(const SPIRType &struct_type, uint32_t index) const;
|
||||
uint32_t get_declared_struct_member_alignment_msl(const SPIRType &struct_type, uint32_t index) const;
|
||||
|
||||
uint32_t get_declared_input_size_msl(const SPIRType &struct_type, uint32_t index) const;
|
||||
uint32_t get_declared_input_array_stride_msl(const SPIRType &struct_type, uint32_t index) const;
|
||||
uint32_t get_declared_input_matrix_stride_msl(const SPIRType &struct_type, uint32_t index) const;
|
||||
uint32_t get_declared_input_alignment_msl(const SPIRType &struct_type, uint32_t index) const;
|
||||
|
||||
const SPIRType &get_physical_member_type(const SPIRType &struct_type, uint32_t index) const;
|
||||
SPIRType get_presumed_input_type(const SPIRType &struct_type, uint32_t index) const;
|
||||
|
||||
uint32_t get_declared_struct_size_msl(const SPIRType &struct_type, bool ignore_alignment = false,
|
||||
bool ignore_padding = false) const;
|
||||
@@ -754,6 +877,8 @@ protected:
|
||||
SPIRType &get_patch_stage_in_struct_type();
|
||||
SPIRType &get_patch_stage_out_struct_type();
|
||||
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,
|
||||
bool op1_is_pointer = false, bool op1_is_literal = false, uint32_t op2 = 0);
|
||||
@@ -768,6 +893,7 @@ protected:
|
||||
void emit_entry_point_declarations() override;
|
||||
uint32_t builtin_frag_coord_id = 0;
|
||||
uint32_t builtin_sample_id_id = 0;
|
||||
uint32_t builtin_sample_mask_id = 0;
|
||||
uint32_t builtin_vertex_idx_id = 0;
|
||||
uint32_t builtin_base_vertex_id = 0;
|
||||
uint32_t builtin_instance_idx_id = 0;
|
||||
@@ -779,17 +905,26 @@ protected:
|
||||
uint32_t builtin_subgroup_invocation_id_id = 0;
|
||||
uint32_t builtin_subgroup_size_id = 0;
|
||||
uint32_t builtin_dispatch_base_id = 0;
|
||||
uint32_t builtin_stage_input_size_id = 0;
|
||||
uint32_t builtin_local_invocation_index_id = 0;
|
||||
uint32_t builtin_workgroup_size_id = 0;
|
||||
uint32_t swizzle_buffer_id = 0;
|
||||
uint32_t buffer_size_buffer_id = 0;
|
||||
uint32_t view_mask_buffer_id = 0;
|
||||
uint32_t dynamic_offsets_buffer_id = 0;
|
||||
uint32_t uint_type_id = 0;
|
||||
|
||||
void bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
void bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
bool does_shader_write_sample_mask = false;
|
||||
|
||||
void cast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
void cast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
void emit_store_statement(uint32_t lhs_expression, uint32_t rhs_expression) override;
|
||||
|
||||
void analyze_sampled_image_usage();
|
||||
|
||||
void 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);
|
||||
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);
|
||||
@@ -802,15 +937,18 @@ protected:
|
||||
|
||||
Options msl_options;
|
||||
std::set<SPVFuncImpl> spv_function_implementations;
|
||||
std::unordered_map<uint32_t, MSLVertexAttr> vtx_attrs_by_location;
|
||||
std::unordered_map<uint32_t, MSLVertexAttr> vtx_attrs_by_builtin;
|
||||
std::unordered_set<uint32_t> vtx_attrs_in_use;
|
||||
// Must be ordered to ensure declarations are in a specific order.
|
||||
std::map<uint32_t, MSLShaderInput> inputs_by_location;
|
||||
std::unordered_map<uint32_t, MSLShaderInput> inputs_by_builtin;
|
||||
std::unordered_set<uint32_t> location_inputs_in_use;
|
||||
std::unordered_map<uint32_t, uint32_t> fragment_output_components;
|
||||
std::unordered_map<uint32_t, uint32_t> builtin_to_automatic_input_location;
|
||||
std::set<std::string> pragma_lines;
|
||||
std::set<std::string> typedef_lines;
|
||||
SmallVector<uint32_t> vars_needing_early_declaration;
|
||||
|
||||
std::unordered_map<StageSetBinding, std::pair<MSLResourceBinding, bool>, InternalHasher> resource_bindings;
|
||||
uint32_t type_to_location_count(const SPIRType &type) const;
|
||||
|
||||
uint32_t next_metal_resource_index_buffer = 0;
|
||||
uint32_t next_metal_resource_index_texture = 0;
|
||||
@@ -847,6 +985,8 @@ protected:
|
||||
bool used_swizzle_buffer = false;
|
||||
bool added_builtin_tess_level = false;
|
||||
bool needs_subgroup_invocation_id = false;
|
||||
bool needs_subgroup_size = false;
|
||||
bool needs_sample_id = false;
|
||||
std::string qual_pos_var_name;
|
||||
std::string stage_in_var_name = "in";
|
||||
std::string stage_out_var_name = "out";
|
||||
@@ -857,9 +997,11 @@ protected:
|
||||
std::string buffer_size_name_suffix = "BufferSize";
|
||||
std::string plane_name_suffix = "Plane";
|
||||
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_output_buffer_var_name = "spvPatchOut";
|
||||
std::string tess_factor_buffer_var_name = "spvTessLevel";
|
||||
std::string index_buffer_var_name = "spvIndices";
|
||||
spv::Op previous_instruction_opcode = spv::OpNop;
|
||||
|
||||
// Must be ordered since declaration is in a specific order.
|
||||
@@ -870,6 +1012,7 @@ protected:
|
||||
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
|
||||
std::unordered_set<uint32_t> pull_model_inputs;
|
||||
|
||||
// Must be ordered since array is in a specific order.
|
||||
std::map<SetBindingPair, std::pair<uint32_t, uint32_t>> buffers_requiring_dynamic_offset;
|
||||
@@ -886,7 +1029,9 @@ protected:
|
||||
bool descriptor_set_is_argument_buffer(uint32_t desc_set) const;
|
||||
|
||||
uint32_t get_target_components_for_fragment_location(uint32_t location) const;
|
||||
uint32_t build_extended_vector_type(uint32_t type_id, uint32_t components);
|
||||
uint32_t build_extended_vector_type(uint32_t type_id, uint32_t components,
|
||||
SPIRType::BaseType basetype = SPIRType::Unknown);
|
||||
uint32_t build_msl_interpolant_type(uint32_t type_id, bool is_noperspective);
|
||||
|
||||
bool suppress_missing_prototypes = false;
|
||||
|
||||
@@ -895,6 +1040,9 @@ protected:
|
||||
void activate_argument_buffer_resources();
|
||||
|
||||
bool type_is_msl_framebuffer_fetch(const SPIRType &type) const;
|
||||
bool type_is_pointer(const SPIRType &type) const;
|
||||
bool type_is_pointer_to_pointer(const SPIRType &type) const;
|
||||
bool is_supported_argument_buffer_type(const SPIRType &type) const;
|
||||
|
||||
// OpcodeHandler that handles several MSL preprocessing operations.
|
||||
struct OpCodePreprocessor : OpcodeHandler
|
||||
@@ -915,6 +1063,8 @@ protected:
|
||||
bool uses_atomics = false;
|
||||
bool uses_resource_write = false;
|
||||
bool needs_subgroup_invocation_id = false;
|
||||
bool needs_subgroup_size = false;
|
||||
bool needs_sample_id = false;
|
||||
};
|
||||
|
||||
// OpcodeHandler that scans for uses of sampled images
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2020 Arm Limited
|
||||
* Copyright 2018-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#include "spirv_parser.hpp"
|
||||
#include <assert.h>
|
||||
|
||||
@@ -133,6 +140,8 @@ void Parser::parse()
|
||||
SPIRV_CROSS_THROW("Function was not terminated.");
|
||||
if (current_block)
|
||||
SPIRV_CROSS_THROW("Block was not terminated.");
|
||||
if (ir.default_entry_point == 0)
|
||||
SPIRV_CROSS_THROW("There is no entry point in the SPIR-V module.");
|
||||
}
|
||||
|
||||
const uint32_t *Parser::stream(const Instruction &instr) const
|
||||
@@ -623,10 +632,15 @@ void Parser::parse(const Instruction &instruction)
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
|
||||
auto &base = get<SPIRType>(ops[2]);
|
||||
// Very rarely, we might receive a FunctionPrototype here.
|
||||
// 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);
|
||||
|
||||
ptrbase = base;
|
||||
if (base)
|
||||
ptrbase = *base;
|
||||
|
||||
ptrbase.pointer = true;
|
||||
ptrbase.pointer_depth++;
|
||||
ptrbase.storage = static_cast<StorageClass>(ops[1]);
|
||||
@@ -634,7 +648,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
if (ptrbase.storage == StorageClassAtomicCounter)
|
||||
ptrbase.basetype = SPIRType::AtomicCounter;
|
||||
|
||||
if (base.forward_pointer)
|
||||
if (base && base->forward_pointer)
|
||||
forward_pointer_fixups.push_back({ id, ops[2] });
|
||||
|
||||
ptrbase.parent_type = ops[2];
|
||||
@@ -715,7 +729,7 @@ void Parser::parse(const Instruction &instruction)
|
||||
break;
|
||||
}
|
||||
|
||||
case OpTypeRayQueryProvisionalKHR:
|
||||
case OpTypeRayQueryKHR:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto &type = set<SPIRType>(id);
|
||||
@@ -980,6 +994,22 @@ void Parser::parse(const Instruction &instruction)
|
||||
break;
|
||||
}
|
||||
|
||||
case OpTerminateRayKHR:
|
||||
// NV variant is not a terminator.
|
||||
if (!current_block)
|
||||
SPIRV_CROSS_THROW("Trying to end a non-existing block.");
|
||||
current_block->terminator = SPIRBlock::TerminateRay;
|
||||
current_block = nullptr;
|
||||
break;
|
||||
|
||||
case OpIgnoreIntersectionKHR:
|
||||
// NV variant is not a terminator.
|
||||
if (!current_block)
|
||||
SPIRV_CROSS_THROW("Trying to end a non-existing block.");
|
||||
current_block->terminator = SPIRBlock::IgnoreIntersection;
|
||||
current_block = nullptr;
|
||||
break;
|
||||
|
||||
case OpReturn:
|
||||
{
|
||||
if (!current_block)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2020 Arm Limited
|
||||
* Copyright 2018-2021 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_PARSER_HPP
|
||||
#define SPIRV_CROSS_PARSER_HPP
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2020 Bradley Austin Davis
|
||||
* Copyright 2018-2021 Bradley Austin Davis
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#include "spirv_reflect.hpp"
|
||||
#include "spirv_glsl.hpp"
|
||||
#include <iomanip>
|
||||
@@ -267,7 +274,6 @@ string CompilerReflection::compile()
|
||||
json_stream = std::make_shared<simple_json::Stream>();
|
||||
json_stream->set_current_locale_radix_character(current_locale_radix_character);
|
||||
json_stream->begin_json_object();
|
||||
fixup_type_alias();
|
||||
reorder_type_alias();
|
||||
emit_entry_points();
|
||||
emit_types();
|
||||
@@ -305,8 +311,8 @@ void CompilerReflection::emit_types()
|
||||
else if (type_is_reference(type))
|
||||
{
|
||||
if (!naturally_emit_type(this->get<SPIRType>(type.parent_type)) &&
|
||||
find(physical_pointee_types.begin(), physical_pointee_types.end(),
|
||||
type.parent_type) == physical_pointee_types.end())
|
||||
find(physical_pointee_types.begin(), physical_pointee_types.end(), type.parent_type) ==
|
||||
physical_pointee_types.end())
|
||||
{
|
||||
physical_pointee_types.push_back(type.parent_type);
|
||||
}
|
||||
@@ -327,9 +333,6 @@ void CompilerReflection::emit_type(uint32_t type_id, bool &emitted_open_tag)
|
||||
auto &type = get<SPIRType>(type_id);
|
||||
auto name = type_to_glsl(type);
|
||||
|
||||
if (type.type_alias != TypeID(0))
|
||||
return;
|
||||
|
||||
if (!emitted_open_tag)
|
||||
{
|
||||
json_stream->emit_json_key_object("types");
|
||||
@@ -651,7 +654,7 @@ void CompilerReflection::emit_specialization_constants()
|
||||
return;
|
||||
|
||||
json_stream->emit_json_key_array("specialization_constants");
|
||||
for (const auto spec_const : specialization_constants)
|
||||
for (const auto &spec_const : specialization_constants)
|
||||
{
|
||||
auto &c = get<SPIRConstant>(spec_const.id);
|
||||
auto type = get<SPIRType>(c.constant_type);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2020 Bradley Austin Davis
|
||||
* Copyright 2018-2021 Bradley Austin Davis
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,6 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_REFLECT_HPP
|
||||
#define SPIRV_CROSS_REFLECT_HPP
|
||||
|
||||
|
||||
Reference in New Issue
Block a user