Updated spirv-cross.
This commit is contained in:
parent
6c09cb564a
commit
939e9233c8
2
3rdparty/spirv-cross/main.cpp
vendored
2
3rdparty/spirv-cross/main.cpp
vendored
@ -908,7 +908,7 @@ static void print_help_common()
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
fprintf(stderr, "\nCommon options:\n"
|
fprintf(stderr, "\nCommon options:\n"
|
||||||
"\t[--entry name]:\n\t\tUse a specific entry point. By default, the first entry point in the module is used.\n"
|
"\t[--entry name]:\n\t\tUse a specific entry point. By default, the first entry point in the module is used.\n"
|
||||||
"\t[--stage <stage (vert, frag, geom, tesc, tese comp)>]:\n\t\tForces use of a certain shader stage.\n"
|
"\t[--stage <stage (vert, frag, geom, tesc, tese, comp)>]:\n\t\tForces use of a certain shader stage.\n"
|
||||||
"\t\tCan disambiguate the entry point if more than one entry point exists with same name, but different stage.\n"
|
"\t\tCan disambiguate the entry point if more than one entry point exists with same name, but different stage.\n"
|
||||||
"\t[--emit-line-directives]:\n\t\tIf SPIR-V has OpLine directives, aim to emit those accurately in output code as well.\n"
|
"\t[--emit-line-directives]:\n\t\tIf SPIR-V has OpLine directives, aim to emit those accurately in output code as well.\n"
|
||||||
"\t[--rename-entry-point <old> <new> <stage>]:\n\t\tRenames an entry point from what is declared in SPIR-V to code output.\n"
|
"\t[--rename-entry-point <old> <new> <stage>]:\n\t\tRenames an entry point from what is declared in SPIR-V to code output.\n"
|
||||||
|
49
3rdparty/spirv-cross/spirv.h
vendored
49
3rdparty/spirv-cross/spirv.h
vendored
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Enumeration tokens for SPIR-V, in various styles:
|
** Enumeration tokens for SPIR-V, in various styles:
|
||||||
** C, C++, C++11, JSON, Lua, Python, C#, D
|
** C, C++, C++11, JSON, Lua, Python, C#, D, Beef
|
||||||
**
|
**
|
||||||
** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
||||||
** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
||||||
@ -41,6 +41,8 @@
|
|||||||
** - C# will use enum classes in the Specification class located in the "Spv" namespace,
|
** - C# will use enum classes in the Specification class located in the "Spv" namespace,
|
||||||
** e.g.: Spv.Specification.SourceLanguage.GLSL
|
** e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||||
** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
|
** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
|
||||||
|
** - Beef will use enum classes in the Specification class located in the "Spv" namespace,
|
||||||
|
** e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||||
**
|
**
|
||||||
** Some tokens act like mask values, which can be OR'd together,
|
** Some tokens act like mask values, which can be OR'd together,
|
||||||
** while others are mutually exclusive. The mask-like ones have
|
** while others are mutually exclusive. The mask-like ones have
|
||||||
@ -70,6 +72,7 @@ typedef enum SpvSourceLanguage_ {
|
|||||||
SpvSourceLanguageOpenCL_CPP = 4,
|
SpvSourceLanguageOpenCL_CPP = 4,
|
||||||
SpvSourceLanguageHLSL = 5,
|
SpvSourceLanguageHLSL = 5,
|
||||||
SpvSourceLanguageCPP_for_OpenCL = 6,
|
SpvSourceLanguageCPP_for_OpenCL = 6,
|
||||||
|
SpvSourceLanguageSYCL = 7,
|
||||||
SpvSourceLanguageMax = 0x7fffffff,
|
SpvSourceLanguageMax = 0x7fffffff,
|
||||||
} SpvSourceLanguage;
|
} SpvSourceLanguage;
|
||||||
|
|
||||||
@ -184,6 +187,7 @@ typedef enum SpvExecutionMode_ {
|
|||||||
SpvExecutionModeNoGlobalOffsetINTEL = 5895,
|
SpvExecutionModeNoGlobalOffsetINTEL = 5895,
|
||||||
SpvExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
SpvExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
||||||
SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
|
SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
|
||||||
|
SpvExecutionModeNamedBarrierCountINTEL = 6417,
|
||||||
SpvExecutionModeMax = 0x7fffffff,
|
SpvExecutionModeMax = 0x7fffffff,
|
||||||
} SpvExecutionMode;
|
} SpvExecutionMode;
|
||||||
|
|
||||||
@ -546,6 +550,8 @@ typedef enum SpvDecoration_ {
|
|||||||
SpvDecorationPrefetchINTEL = 5902,
|
SpvDecorationPrefetchINTEL = 5902,
|
||||||
SpvDecorationStallEnableINTEL = 5905,
|
SpvDecorationStallEnableINTEL = 5905,
|
||||||
SpvDecorationFuseLoopsInFunctionINTEL = 5907,
|
SpvDecorationFuseLoopsInFunctionINTEL = 5907,
|
||||||
|
SpvDecorationAliasScopeINTEL = 5914,
|
||||||
|
SpvDecorationNoAliasINTEL = 5915,
|
||||||
SpvDecorationBufferLocationINTEL = 5921,
|
SpvDecorationBufferLocationINTEL = 5921,
|
||||||
SpvDecorationIOPipeStorageINTEL = 5944,
|
SpvDecorationIOPipeStorageINTEL = 5944,
|
||||||
SpvDecorationFunctionFloatingPointModeINTEL = 6080,
|
SpvDecorationFunctionFloatingPointModeINTEL = 6080,
|
||||||
@ -677,6 +683,7 @@ typedef enum SpvBuiltIn_ {
|
|||||||
SpvBuiltInSMCountNV = 5375,
|
SpvBuiltInSMCountNV = 5375,
|
||||||
SpvBuiltInWarpIDNV = 5376,
|
SpvBuiltInWarpIDNV = 5376,
|
||||||
SpvBuiltInSMIDNV = 5377,
|
SpvBuiltInSMIDNV = 5377,
|
||||||
|
SpvBuiltInCullMaskKHR = 6021,
|
||||||
SpvBuiltInMax = 0x7fffffff,
|
SpvBuiltInMax = 0x7fffffff,
|
||||||
} SpvBuiltIn;
|
} SpvBuiltIn;
|
||||||
|
|
||||||
@ -804,6 +811,8 @@ typedef enum SpvMemoryAccessShift_ {
|
|||||||
SpvMemoryAccessMakePointerVisibleKHRShift = 4,
|
SpvMemoryAccessMakePointerVisibleKHRShift = 4,
|
||||||
SpvMemoryAccessNonPrivatePointerShift = 5,
|
SpvMemoryAccessNonPrivatePointerShift = 5,
|
||||||
SpvMemoryAccessNonPrivatePointerKHRShift = 5,
|
SpvMemoryAccessNonPrivatePointerKHRShift = 5,
|
||||||
|
SpvMemoryAccessAliasScopeINTELMaskShift = 16,
|
||||||
|
SpvMemoryAccessNoAliasINTELMaskShift = 17,
|
||||||
SpvMemoryAccessMax = 0x7fffffff,
|
SpvMemoryAccessMax = 0x7fffffff,
|
||||||
} SpvMemoryAccessShift;
|
} SpvMemoryAccessShift;
|
||||||
|
|
||||||
@ -818,6 +827,8 @@ typedef enum SpvMemoryAccessMask_ {
|
|||||||
SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
||||||
SpvMemoryAccessNonPrivatePointerMask = 0x00000020,
|
SpvMemoryAccessNonPrivatePointerMask = 0x00000020,
|
||||||
SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
||||||
|
SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000,
|
||||||
|
SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000,
|
||||||
} SpvMemoryAccessMask;
|
} SpvMemoryAccessMask;
|
||||||
|
|
||||||
typedef enum SpvScope_ {
|
typedef enum SpvScope_ {
|
||||||
@ -1059,6 +1070,7 @@ typedef enum SpvCapability_ {
|
|||||||
SpvCapabilityFPGAMemoryAccessesINTEL = 5898,
|
SpvCapabilityFPGAMemoryAccessesINTEL = 5898,
|
||||||
SpvCapabilityFPGAClusterAttributesINTEL = 5904,
|
SpvCapabilityFPGAClusterAttributesINTEL = 5904,
|
||||||
SpvCapabilityLoopFuseINTEL = 5906,
|
SpvCapabilityLoopFuseINTEL = 5906,
|
||||||
|
SpvCapabilityMemoryAccessAliasingINTEL = 5910,
|
||||||
SpvCapabilityFPGABufferLocationINTEL = 5920,
|
SpvCapabilityFPGABufferLocationINTEL = 5920,
|
||||||
SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922,
|
SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922,
|
||||||
SpvCapabilityUSMStorageClassesINTEL = 5935,
|
SpvCapabilityUSMStorageClassesINTEL = 5935,
|
||||||
@ -1073,13 +1085,17 @@ typedef enum SpvCapability_ {
|
|||||||
SpvCapabilityDotProductInput4x8BitPackedKHR = 6018,
|
SpvCapabilityDotProductInput4x8BitPackedKHR = 6018,
|
||||||
SpvCapabilityDotProduct = 6019,
|
SpvCapabilityDotProduct = 6019,
|
||||||
SpvCapabilityDotProductKHR = 6019,
|
SpvCapabilityDotProductKHR = 6019,
|
||||||
|
SpvCapabilityRayCullMaskKHR = 6020,
|
||||||
SpvCapabilityBitInstructions = 6025,
|
SpvCapabilityBitInstructions = 6025,
|
||||||
|
SpvCapabilityGroupNonUniformRotateKHR = 6026,
|
||||||
SpvCapabilityAtomicFloat32AddEXT = 6033,
|
SpvCapabilityAtomicFloat32AddEXT = 6033,
|
||||||
SpvCapabilityAtomicFloat64AddEXT = 6034,
|
SpvCapabilityAtomicFloat64AddEXT = 6034,
|
||||||
SpvCapabilityLongConstantCompositeINTEL = 6089,
|
SpvCapabilityLongConstantCompositeINTEL = 6089,
|
||||||
SpvCapabilityOptNoneINTEL = 6094,
|
SpvCapabilityOptNoneINTEL = 6094,
|
||||||
SpvCapabilityAtomicFloat16AddEXT = 6095,
|
SpvCapabilityAtomicFloat16AddEXT = 6095,
|
||||||
SpvCapabilityDebugInfoModuleINTEL = 6114,
|
SpvCapabilityDebugInfoModuleINTEL = 6114,
|
||||||
|
SpvCapabilitySplitBarrierINTEL = 6141,
|
||||||
|
SpvCapabilityGroupUniformArithmeticKHR = 6400,
|
||||||
SpvCapabilityMax = 0x7fffffff,
|
SpvCapabilityMax = 0x7fffffff,
|
||||||
} SpvCapability;
|
} SpvCapability;
|
||||||
|
|
||||||
@ -1535,6 +1551,7 @@ typedef enum SpvOp_ {
|
|||||||
SpvOpSubgroupAllKHR = 4428,
|
SpvOpSubgroupAllKHR = 4428,
|
||||||
SpvOpSubgroupAnyKHR = 4429,
|
SpvOpSubgroupAnyKHR = 4429,
|
||||||
SpvOpSubgroupAllEqualKHR = 4430,
|
SpvOpSubgroupAllEqualKHR = 4430,
|
||||||
|
SpvOpGroupNonUniformRotateKHR = 4431,
|
||||||
SpvOpSubgroupReadInvocationKHR = 4432,
|
SpvOpSubgroupReadInvocationKHR = 4432,
|
||||||
SpvOpTraceRayKHR = 4445,
|
SpvOpTraceRayKHR = 4445,
|
||||||
SpvOpExecuteCallableKHR = 4446,
|
SpvOpExecuteCallableKHR = 4446,
|
||||||
@ -1801,6 +1818,9 @@ typedef enum SpvOp_ {
|
|||||||
SpvOpArbitraryFloatPowRINTEL = 5881,
|
SpvOpArbitraryFloatPowRINTEL = 5881,
|
||||||
SpvOpArbitraryFloatPowNINTEL = 5882,
|
SpvOpArbitraryFloatPowNINTEL = 5882,
|
||||||
SpvOpLoopControlINTEL = 5887,
|
SpvOpLoopControlINTEL = 5887,
|
||||||
|
SpvOpAliasDomainDeclINTEL = 5911,
|
||||||
|
SpvOpAliasScopeDeclINTEL = 5912,
|
||||||
|
SpvOpAliasScopeListDeclINTEL = 5913,
|
||||||
SpvOpFixedSqrtINTEL = 5923,
|
SpvOpFixedSqrtINTEL = 5923,
|
||||||
SpvOpFixedRecipINTEL = 5924,
|
SpvOpFixedRecipINTEL = 5924,
|
||||||
SpvOpFixedRsqrtINTEL = 5925,
|
SpvOpFixedRsqrtINTEL = 5925,
|
||||||
@ -1839,10 +1859,23 @@ typedef enum SpvOp_ {
|
|||||||
SpvOpTypeStructContinuedINTEL = 6090,
|
SpvOpTypeStructContinuedINTEL = 6090,
|
||||||
SpvOpConstantCompositeContinuedINTEL = 6091,
|
SpvOpConstantCompositeContinuedINTEL = 6091,
|
||||||
SpvOpSpecConstantCompositeContinuedINTEL = 6092,
|
SpvOpSpecConstantCompositeContinuedINTEL = 6092,
|
||||||
|
SpvOpControlBarrierArriveINTEL = 6142,
|
||||||
|
SpvOpControlBarrierWaitINTEL = 6143,
|
||||||
|
SpvOpGroupIMulKHR = 6401,
|
||||||
|
SpvOpGroupFMulKHR = 6402,
|
||||||
|
SpvOpGroupBitwiseAndKHR = 6403,
|
||||||
|
SpvOpGroupBitwiseOrKHR = 6404,
|
||||||
|
SpvOpGroupBitwiseXorKHR = 6405,
|
||||||
|
SpvOpGroupLogicalAndKHR = 6406,
|
||||||
|
SpvOpGroupLogicalOrKHR = 6407,
|
||||||
|
SpvOpGroupLogicalXorKHR = 6408,
|
||||||
SpvOpMax = 0x7fffffff,
|
SpvOpMax = 0x7fffffff,
|
||||||
} SpvOp;
|
} SpvOp;
|
||||||
|
|
||||||
#ifdef SPV_ENABLE_UTILITY_CODE
|
#ifdef SPV_ENABLE_UTILITY_CODE
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) {
|
inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) {
|
||||||
*hasResult = *hasResultType = false;
|
*hasResult = *hasResultType = false;
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
@ -2197,6 +2230,7 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
|||||||
case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
|
case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
|
case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
@ -2452,6 +2486,9 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
|||||||
case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break;
|
case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break;
|
case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||||
|
case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||||
|
case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||||
case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
|
case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
@ -2490,6 +2527,16 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
|||||||
case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* SPV_ENABLE_UTILITY_CODE */
|
#endif /* SPV_ENABLE_UTILITY_CODE */
|
||||||
|
49
3rdparty/spirv-cross/spirv.hpp
vendored
49
3rdparty/spirv-cross/spirv.hpp
vendored
@ -26,7 +26,7 @@
|
|||||||
// the Binary Section of the SPIR-V specification.
|
// the Binary Section of the SPIR-V specification.
|
||||||
|
|
||||||
// Enumeration tokens for SPIR-V, in various styles:
|
// Enumeration tokens for SPIR-V, in various styles:
|
||||||
// C, C++, C++11, JSON, Lua, Python, C#, D
|
// C, C++, C++11, JSON, Lua, Python, C#, D, Beef
|
||||||
//
|
//
|
||||||
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
||||||
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
||||||
@ -36,6 +36,8 @@
|
|||||||
// - C# will use enum classes in the Specification class located in the "Spv" namespace,
|
// - C# will use enum classes in the Specification class located in the "Spv" namespace,
|
||||||
// e.g.: Spv.Specification.SourceLanguage.GLSL
|
// e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||||
// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
|
// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
|
||||||
|
// - Beef will use enum classes in the Specification class located in the "Spv" namespace,
|
||||||
|
// e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||||
//
|
//
|
||||||
// Some tokens act like mask values, which can be OR'd together,
|
// Some tokens act like mask values, which can be OR'd together,
|
||||||
// while others are mutually exclusive. The mask-like ones have
|
// while others are mutually exclusive. The mask-like ones have
|
||||||
@ -66,6 +68,7 @@ enum SourceLanguage {
|
|||||||
SourceLanguageOpenCL_CPP = 4,
|
SourceLanguageOpenCL_CPP = 4,
|
||||||
SourceLanguageHLSL = 5,
|
SourceLanguageHLSL = 5,
|
||||||
SourceLanguageCPP_for_OpenCL = 6,
|
SourceLanguageCPP_for_OpenCL = 6,
|
||||||
|
SourceLanguageSYCL = 7,
|
||||||
SourceLanguageMax = 0x7fffffff,
|
SourceLanguageMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -180,6 +183,7 @@ enum ExecutionMode {
|
|||||||
ExecutionModeNoGlobalOffsetINTEL = 5895,
|
ExecutionModeNoGlobalOffsetINTEL = 5895,
|
||||||
ExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
ExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
||||||
ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
|
ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
|
||||||
|
ExecutionModeNamedBarrierCountINTEL = 6417,
|
||||||
ExecutionModeMax = 0x7fffffff,
|
ExecutionModeMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -542,6 +546,8 @@ enum Decoration {
|
|||||||
DecorationPrefetchINTEL = 5902,
|
DecorationPrefetchINTEL = 5902,
|
||||||
DecorationStallEnableINTEL = 5905,
|
DecorationStallEnableINTEL = 5905,
|
||||||
DecorationFuseLoopsInFunctionINTEL = 5907,
|
DecorationFuseLoopsInFunctionINTEL = 5907,
|
||||||
|
DecorationAliasScopeINTEL = 5914,
|
||||||
|
DecorationNoAliasINTEL = 5915,
|
||||||
DecorationBufferLocationINTEL = 5921,
|
DecorationBufferLocationINTEL = 5921,
|
||||||
DecorationIOPipeStorageINTEL = 5944,
|
DecorationIOPipeStorageINTEL = 5944,
|
||||||
DecorationFunctionFloatingPointModeINTEL = 6080,
|
DecorationFunctionFloatingPointModeINTEL = 6080,
|
||||||
@ -673,6 +679,7 @@ enum BuiltIn {
|
|||||||
BuiltInSMCountNV = 5375,
|
BuiltInSMCountNV = 5375,
|
||||||
BuiltInWarpIDNV = 5376,
|
BuiltInWarpIDNV = 5376,
|
||||||
BuiltInSMIDNV = 5377,
|
BuiltInSMIDNV = 5377,
|
||||||
|
BuiltInCullMaskKHR = 6021,
|
||||||
BuiltInMax = 0x7fffffff,
|
BuiltInMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -800,6 +807,8 @@ enum MemoryAccessShift {
|
|||||||
MemoryAccessMakePointerVisibleKHRShift = 4,
|
MemoryAccessMakePointerVisibleKHRShift = 4,
|
||||||
MemoryAccessNonPrivatePointerShift = 5,
|
MemoryAccessNonPrivatePointerShift = 5,
|
||||||
MemoryAccessNonPrivatePointerKHRShift = 5,
|
MemoryAccessNonPrivatePointerKHRShift = 5,
|
||||||
|
MemoryAccessAliasScopeINTELMaskShift = 16,
|
||||||
|
MemoryAccessNoAliasINTELMaskShift = 17,
|
||||||
MemoryAccessMax = 0x7fffffff,
|
MemoryAccessMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -814,6 +823,8 @@ enum MemoryAccessMask {
|
|||||||
MemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
MemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
||||||
MemoryAccessNonPrivatePointerMask = 0x00000020,
|
MemoryAccessNonPrivatePointerMask = 0x00000020,
|
||||||
MemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
MemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
||||||
|
MemoryAccessAliasScopeINTELMaskMask = 0x00010000,
|
||||||
|
MemoryAccessNoAliasINTELMaskMask = 0x00020000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Scope {
|
enum Scope {
|
||||||
@ -1055,6 +1066,7 @@ enum Capability {
|
|||||||
CapabilityFPGAMemoryAccessesINTEL = 5898,
|
CapabilityFPGAMemoryAccessesINTEL = 5898,
|
||||||
CapabilityFPGAClusterAttributesINTEL = 5904,
|
CapabilityFPGAClusterAttributesINTEL = 5904,
|
||||||
CapabilityLoopFuseINTEL = 5906,
|
CapabilityLoopFuseINTEL = 5906,
|
||||||
|
CapabilityMemoryAccessAliasingINTEL = 5910,
|
||||||
CapabilityFPGABufferLocationINTEL = 5920,
|
CapabilityFPGABufferLocationINTEL = 5920,
|
||||||
CapabilityArbitraryPrecisionFixedPointINTEL = 5922,
|
CapabilityArbitraryPrecisionFixedPointINTEL = 5922,
|
||||||
CapabilityUSMStorageClassesINTEL = 5935,
|
CapabilityUSMStorageClassesINTEL = 5935,
|
||||||
@ -1069,13 +1081,17 @@ enum Capability {
|
|||||||
CapabilityDotProductInput4x8BitPackedKHR = 6018,
|
CapabilityDotProductInput4x8BitPackedKHR = 6018,
|
||||||
CapabilityDotProduct = 6019,
|
CapabilityDotProduct = 6019,
|
||||||
CapabilityDotProductKHR = 6019,
|
CapabilityDotProductKHR = 6019,
|
||||||
|
CapabilityRayCullMaskKHR = 6020,
|
||||||
CapabilityBitInstructions = 6025,
|
CapabilityBitInstructions = 6025,
|
||||||
|
CapabilityGroupNonUniformRotateKHR = 6026,
|
||||||
CapabilityAtomicFloat32AddEXT = 6033,
|
CapabilityAtomicFloat32AddEXT = 6033,
|
||||||
CapabilityAtomicFloat64AddEXT = 6034,
|
CapabilityAtomicFloat64AddEXT = 6034,
|
||||||
CapabilityLongConstantCompositeINTEL = 6089,
|
CapabilityLongConstantCompositeINTEL = 6089,
|
||||||
CapabilityOptNoneINTEL = 6094,
|
CapabilityOptNoneINTEL = 6094,
|
||||||
CapabilityAtomicFloat16AddEXT = 6095,
|
CapabilityAtomicFloat16AddEXT = 6095,
|
||||||
CapabilityDebugInfoModuleINTEL = 6114,
|
CapabilityDebugInfoModuleINTEL = 6114,
|
||||||
|
CapabilitySplitBarrierINTEL = 6141,
|
||||||
|
CapabilityGroupUniformArithmeticKHR = 6400,
|
||||||
CapabilityMax = 0x7fffffff,
|
CapabilityMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1531,6 +1547,7 @@ enum Op {
|
|||||||
OpSubgroupAllKHR = 4428,
|
OpSubgroupAllKHR = 4428,
|
||||||
OpSubgroupAnyKHR = 4429,
|
OpSubgroupAnyKHR = 4429,
|
||||||
OpSubgroupAllEqualKHR = 4430,
|
OpSubgroupAllEqualKHR = 4430,
|
||||||
|
OpGroupNonUniformRotateKHR = 4431,
|
||||||
OpSubgroupReadInvocationKHR = 4432,
|
OpSubgroupReadInvocationKHR = 4432,
|
||||||
OpTraceRayKHR = 4445,
|
OpTraceRayKHR = 4445,
|
||||||
OpExecuteCallableKHR = 4446,
|
OpExecuteCallableKHR = 4446,
|
||||||
@ -1797,6 +1814,9 @@ enum Op {
|
|||||||
OpArbitraryFloatPowRINTEL = 5881,
|
OpArbitraryFloatPowRINTEL = 5881,
|
||||||
OpArbitraryFloatPowNINTEL = 5882,
|
OpArbitraryFloatPowNINTEL = 5882,
|
||||||
OpLoopControlINTEL = 5887,
|
OpLoopControlINTEL = 5887,
|
||||||
|
OpAliasDomainDeclINTEL = 5911,
|
||||||
|
OpAliasScopeDeclINTEL = 5912,
|
||||||
|
OpAliasScopeListDeclINTEL = 5913,
|
||||||
OpFixedSqrtINTEL = 5923,
|
OpFixedSqrtINTEL = 5923,
|
||||||
OpFixedRecipINTEL = 5924,
|
OpFixedRecipINTEL = 5924,
|
||||||
OpFixedRsqrtINTEL = 5925,
|
OpFixedRsqrtINTEL = 5925,
|
||||||
@ -1835,10 +1855,23 @@ enum Op {
|
|||||||
OpTypeStructContinuedINTEL = 6090,
|
OpTypeStructContinuedINTEL = 6090,
|
||||||
OpConstantCompositeContinuedINTEL = 6091,
|
OpConstantCompositeContinuedINTEL = 6091,
|
||||||
OpSpecConstantCompositeContinuedINTEL = 6092,
|
OpSpecConstantCompositeContinuedINTEL = 6092,
|
||||||
|
OpControlBarrierArriveINTEL = 6142,
|
||||||
|
OpControlBarrierWaitINTEL = 6143,
|
||||||
|
OpGroupIMulKHR = 6401,
|
||||||
|
OpGroupFMulKHR = 6402,
|
||||||
|
OpGroupBitwiseAndKHR = 6403,
|
||||||
|
OpGroupBitwiseOrKHR = 6404,
|
||||||
|
OpGroupBitwiseXorKHR = 6405,
|
||||||
|
OpGroupLogicalAndKHR = 6406,
|
||||||
|
OpGroupLogicalOrKHR = 6407,
|
||||||
|
OpGroupLogicalXorKHR = 6408,
|
||||||
OpMax = 0x7fffffff,
|
OpMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef SPV_ENABLE_UTILITY_CODE
|
#ifdef SPV_ENABLE_UTILITY_CODE
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||||
*hasResult = *hasResultType = false;
|
*hasResult = *hasResultType = false;
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
@ -2193,6 +2226,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
|||||||
case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
|
case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
|
case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
@ -2448,6 +2482,9 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
|||||||
case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||||
|
case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||||
|
case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||||
case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
@ -2486,6 +2523,16 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
|||||||
case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* SPV_ENABLE_UTILITY_CODE */
|
#endif /* SPV_ENABLE_UTILITY_CODE */
|
||||||
|
33
3rdparty/spirv-cross/spirv_cfg.cpp
vendored
33
3rdparty/spirv-cross/spirv_cfg.cpp
vendored
@ -306,15 +306,36 @@ bool CFG::node_terminates_control_flow_in_sub_graph(BlockID from, BlockID to) co
|
|||||||
|
|
||||||
bool true_path_ignore = false;
|
bool true_path_ignore = false;
|
||||||
bool false_path_ignore = false;
|
bool false_path_ignore = false;
|
||||||
if (ignore_block_id && dom.terminator == SPIRBlock::Select)
|
|
||||||
|
bool merges_to_nothing = dom.merge == SPIRBlock::MergeNone ||
|
||||||
|
(dom.merge == SPIRBlock::MergeSelection && dom.next_block &&
|
||||||
|
compiler.get<SPIRBlock>(dom.next_block).terminator == SPIRBlock::Unreachable) ||
|
||||||
|
(dom.merge == SPIRBlock::MergeLoop && dom.merge_block &&
|
||||||
|
compiler.get<SPIRBlock>(dom.merge_block).terminator == SPIRBlock::Unreachable);
|
||||||
|
|
||||||
|
if (dom.self == from || merges_to_nothing)
|
||||||
{
|
{
|
||||||
auto &true_block = compiler.get<SPIRBlock>(dom.true_block);
|
// We can only ignore inner branchy paths if there is no merge,
|
||||||
auto &false_block = compiler.get<SPIRBlock>(dom.false_block);
|
// i.e. no code is generated afterwards. E.g. this allows us to elide continue:
|
||||||
auto &ignore_block = compiler.get<SPIRBlock>(ignore_block_id);
|
// for (;;) { if (cond) { continue; } else { break; } }.
|
||||||
true_path_ignore = compiler.execution_is_branchless(true_block, ignore_block);
|
// Codegen here in SPIR-V will be something like either no merge if one path directly breaks, or
|
||||||
false_path_ignore = compiler.execution_is_branchless(false_block, ignore_block);
|
// we merge to Unreachable.
|
||||||
|
if (ignore_block_id && dom.terminator == SPIRBlock::Select)
|
||||||
|
{
|
||||||
|
auto &true_block = compiler.get<SPIRBlock>(dom.true_block);
|
||||||
|
auto &false_block = compiler.get<SPIRBlock>(dom.false_block);
|
||||||
|
auto &ignore_block = compiler.get<SPIRBlock>(ignore_block_id);
|
||||||
|
true_path_ignore = compiler.execution_is_branchless(true_block, ignore_block);
|
||||||
|
false_path_ignore = compiler.execution_is_branchless(false_block, ignore_block);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cases where we allow traversal. This serves as a proxy for post-dominance in a loop body.
|
||||||
|
// TODO: Might want to do full post-dominance analysis, but it's a lot of churn for something like this ...
|
||||||
|
// - We're the merge block of a selection construct. Jump to header.
|
||||||
|
// - We're the merge block of a loop. Jump to header.
|
||||||
|
// - Direct branch. Trivial.
|
||||||
|
// - Allow cases inside a branch if the header cannot merge execution before loop exit.
|
||||||
if ((dom.merge == SPIRBlock::MergeSelection && dom.next_block == to) ||
|
if ((dom.merge == SPIRBlock::MergeSelection && dom.next_block == to) ||
|
||||||
(dom.merge == SPIRBlock::MergeLoop && dom.merge_block == to) ||
|
(dom.merge == SPIRBlock::MergeLoop && dom.merge_block == to) ||
|
||||||
(dom.terminator == SPIRBlock::Direct && dom.next_block == to) ||
|
(dom.terminator == SPIRBlock::Direct && dom.next_block == to) ||
|
||||||
|
13
3rdparty/spirv-cross/spirv_cross.cpp
vendored
13
3rdparty/spirv-cross/spirv_cross.cpp
vendored
@ -3229,7 +3229,20 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
|
|||||||
// Keep track of the types of temporaries, so we can hoist them out as necessary.
|
// Keep track of the types of temporaries, so we can hoist them out as necessary.
|
||||||
uint32_t result_type, result_id;
|
uint32_t result_type, result_id;
|
||||||
if (compiler.instruction_to_result_type(result_type, result_id, op, args, length))
|
if (compiler.instruction_to_result_type(result_type, result_id, op, args, length))
|
||||||
|
{
|
||||||
|
// For some opcodes, we will need to override the result id.
|
||||||
|
// If we need to hoist the temporary, the temporary type is the input, not the result.
|
||||||
|
// FIXME: This will likely break with OpCopyObject + hoisting, but we'll have to
|
||||||
|
// solve it if we ever get there ...
|
||||||
|
if (op == OpConvertUToAccelerationStructureKHR)
|
||||||
|
{
|
||||||
|
auto itr = result_id_to_type.find(args[2]);
|
||||||
|
if (itr != result_id_to_type.end())
|
||||||
|
result_type = itr->second;
|
||||||
|
}
|
||||||
|
|
||||||
result_id_to_type[result_id] = result_type;
|
result_id_to_type[result_id] = result_type;
|
||||||
|
}
|
||||||
|
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
|
279
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
279
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
@ -405,10 +405,9 @@ void CompilerGLSL::find_static_extensions()
|
|||||||
}
|
}
|
||||||
else if (type.basetype == SPIRType::Int64 || type.basetype == SPIRType::UInt64)
|
else if (type.basetype == SPIRType::Int64 || type.basetype == SPIRType::UInt64)
|
||||||
{
|
{
|
||||||
if (options.es)
|
if (options.es && options.version < 310) // GL_NV_gpu_shader5 fallback requires 310.
|
||||||
SPIRV_CROSS_THROW("64-bit integers not supported in ES profile.");
|
SPIRV_CROSS_THROW("64-bit integers not supported in ES profile before version 310.");
|
||||||
if (!options.es)
|
require_extension_internal("GL_ARB_gpu_shader_int64");
|
||||||
require_extension_internal("GL_ARB_gpu_shader_int64");
|
|
||||||
}
|
}
|
||||||
else if (type.basetype == SPIRType::Half)
|
else if (type.basetype == SPIRType::Half)
|
||||||
{
|
{
|
||||||
@ -619,6 +618,11 @@ void CompilerGLSL::find_static_extensions()
|
|||||||
SPIRV_CROSS_THROW("OVR_multiview2 can only be used with Vertex shaders.");
|
SPIRV_CROSS_THROW("OVR_multiview2 can only be used with Vertex shaders.");
|
||||||
require_extension_internal("GL_OVR_multiview2");
|
require_extension_internal("GL_OVR_multiview2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KHR one is likely to get promoted at some point, so if we don't see an explicit SPIR-V extension, assume KHR.
|
||||||
|
for (auto &ext : ir.declared_extensions)
|
||||||
|
if (ext == "SPV_NV_fragment_shader_barycentric")
|
||||||
|
barycentric_is_nv = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerGLSL::ray_tracing_khr_fixup_locations()
|
void CompilerGLSL::ray_tracing_khr_fixup_locations()
|
||||||
@ -821,7 +825,20 @@ void CompilerGLSL::emit_header()
|
|||||||
|
|
||||||
for (auto &ext : forced_extensions)
|
for (auto &ext : forced_extensions)
|
||||||
{
|
{
|
||||||
if (ext == "GL_EXT_shader_explicit_arithmetic_types_float16")
|
if (ext == "GL_ARB_gpu_shader_int64")
|
||||||
|
{
|
||||||
|
statement("#if defined(GL_ARB_gpu_shader_int64)");
|
||||||
|
statement("#extension GL_ARB_gpu_shader_int64 : require");
|
||||||
|
if (!options.vulkan_semantics || options.es)
|
||||||
|
{
|
||||||
|
statement("#elif defined(GL_NV_gpu_shader5)");
|
||||||
|
statement("#extension GL_NV_gpu_shader5 : require");
|
||||||
|
}
|
||||||
|
statement("#else");
|
||||||
|
statement("#error No extension available for 64-bit integers.");
|
||||||
|
statement("#endif");
|
||||||
|
}
|
||||||
|
else if (ext == "GL_EXT_shader_explicit_arithmetic_types_float16")
|
||||||
{
|
{
|
||||||
// Special case, this extension has a potential fallback to another vendor extension in normal GLSL.
|
// Special case, this extension has a potential fallback to another vendor extension in normal GLSL.
|
||||||
// GL_AMD_gpu_shader_half_float is a superset, so try that first.
|
// GL_AMD_gpu_shader_half_float is a superset, so try that first.
|
||||||
@ -841,13 +858,30 @@ void CompilerGLSL::emit_header()
|
|||||||
statement("#error No extension available for FP16.");
|
statement("#error No extension available for FP16.");
|
||||||
statement("#endif");
|
statement("#endif");
|
||||||
}
|
}
|
||||||
|
else if (ext == "GL_EXT_shader_explicit_arithmetic_types_int8")
|
||||||
|
{
|
||||||
|
if (options.vulkan_semantics)
|
||||||
|
statement("#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statement("#if defined(GL_EXT_shader_explicit_arithmetic_types_int8)");
|
||||||
|
statement("#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require");
|
||||||
|
statement("#elif defined(GL_NV_gpu_shader5)");
|
||||||
|
statement("#extension GL_NV_gpu_shader5 : require");
|
||||||
|
statement("#else");
|
||||||
|
statement("#error No extension available for Int8.");
|
||||||
|
statement("#endif");
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (ext == "GL_EXT_shader_explicit_arithmetic_types_int16")
|
else if (ext == "GL_EXT_shader_explicit_arithmetic_types_int16")
|
||||||
{
|
{
|
||||||
if (options.vulkan_semantics)
|
if (options.vulkan_semantics)
|
||||||
statement("#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require");
|
statement("#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
statement("#if defined(GL_AMD_gpu_shader_int16)");
|
statement("#if defined(GL_EXT_shader_explicit_arithmetic_types_int16)");
|
||||||
|
statement("#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require");
|
||||||
|
statement("#elif defined(GL_AMD_gpu_shader_int16)");
|
||||||
statement("#extension GL_AMD_gpu_shader_int16 : require");
|
statement("#extension GL_AMD_gpu_shader_int16 : require");
|
||||||
statement("#elif defined(GL_NV_gpu_shader5)");
|
statement("#elif defined(GL_NV_gpu_shader5)");
|
||||||
statement("#extension GL_NV_gpu_shader5 : require");
|
statement("#extension GL_NV_gpu_shader5 : require");
|
||||||
@ -1206,14 +1240,23 @@ string CompilerGLSL::to_interpolation_qualifiers(const Bitset &flags)
|
|||||||
res += "__explicitInterpAMD ";
|
res += "__explicitInterpAMD ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags.get(DecorationPerVertexNV))
|
if (flags.get(DecorationPerVertexKHR))
|
||||||
{
|
{
|
||||||
if (options.es && options.version < 320)
|
if (options.es && options.version < 320)
|
||||||
SPIRV_CROSS_THROW("pervertexNV requires ESSL 320.");
|
SPIRV_CROSS_THROW("pervertexEXT requires ESSL 320.");
|
||||||
else if (!options.es && options.version < 450)
|
else if (!options.es && options.version < 450)
|
||||||
SPIRV_CROSS_THROW("pervertexNV requires GLSL 450.");
|
SPIRV_CROSS_THROW("pervertexEXT requires GLSL 450.");
|
||||||
require_extension_internal("GL_NV_fragment_shader_barycentric");
|
|
||||||
res += "pervertexNV ";
|
if (barycentric_is_nv)
|
||||||
|
{
|
||||||
|
require_extension_internal("GL_NV_fragment_shader_barycentric");
|
||||||
|
res += "pervertexNV ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
require_extension_internal("GL_EXT_fragment_shader_barycentric");
|
||||||
|
res += "pervertexEXT ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -5171,8 +5214,8 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c, bool inside_bloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// sprintf warning.
|
// snprintf does not exist or is buggy on older MSVC versions, some of them
|
||||||
// We cannot rely on snprintf existing because, ..., MSVC.
|
// being used by MinGW. Use sprintf instead and disable corresponding warning.
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4996)
|
#pragma warning(disable : 4996)
|
||||||
#endif
|
#endif
|
||||||
@ -5232,7 +5275,11 @@ string CompilerGLSL::convert_float_to_string(const SPIRConstant &c, uint32_t col
|
|||||||
in_type.width = 32;
|
in_type.width = 32;
|
||||||
|
|
||||||
char print_buffer[32];
|
char print_buffer[32];
|
||||||
|
#ifdef _WIN32
|
||||||
sprintf(print_buffer, "0x%xu", c.scalar(col, row));
|
sprintf(print_buffer, "0x%xu", c.scalar(col, row));
|
||||||
|
#else
|
||||||
|
snprintf(print_buffer, sizeof(print_buffer), "0x%xu", c.scalar(col, row));
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *comment = "inf";
|
const char *comment = "inf";
|
||||||
if (float_value == -numeric_limits<float>::infinity())
|
if (float_value == -numeric_limits<float>::infinity())
|
||||||
@ -5299,13 +5346,18 @@ std::string CompilerGLSL::convert_double_to_string(const SPIRConstant &c, uint32
|
|||||||
|
|
||||||
uint64_t u64_value = c.scalar_u64(col, row);
|
uint64_t u64_value = c.scalar_u64(col, row);
|
||||||
|
|
||||||
if (options.es)
|
if (options.es && options.version < 310) // GL_NV_gpu_shader5 fallback requires 310.
|
||||||
SPIRV_CROSS_THROW("64-bit integers/float not supported in ES profile.");
|
SPIRV_CROSS_THROW("64-bit integers not supported in ES profile before version 310.");
|
||||||
require_extension_internal("GL_ARB_gpu_shader_int64");
|
require_extension_internal("GL_ARB_gpu_shader_int64");
|
||||||
|
|
||||||
char print_buffer[64];
|
char print_buffer[64];
|
||||||
|
#ifdef _WIN32
|
||||||
sprintf(print_buffer, "0x%llx%s", static_cast<unsigned long long>(u64_value),
|
sprintf(print_buffer, "0x%llx%s", static_cast<unsigned long long>(u64_value),
|
||||||
backend.long_long_literal_suffix ? "ull" : "ul");
|
backend.long_long_literal_suffix ? "ull" : "ul");
|
||||||
|
#else
|
||||||
|
snprintf(print_buffer, sizeof(print_buffer), "0x%llx%s", static_cast<unsigned long long>(u64_value),
|
||||||
|
backend.long_long_literal_suffix ? "ull" : "ul");
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *comment = "inf";
|
const char *comment = "inf";
|
||||||
if (double_value == -numeric_limits<double>::infinity())
|
if (double_value == -numeric_limits<double>::infinity())
|
||||||
@ -6066,6 +6118,16 @@ void CompilerGLSL::emit_binary_func_op(uint32_t result_type, uint32_t result_id,
|
|||||||
void CompilerGLSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1,
|
void CompilerGLSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1,
|
||||||
const char *op)
|
const char *op)
|
||||||
{
|
{
|
||||||
|
auto &type = get<SPIRType>(result_type);
|
||||||
|
if (type_is_floating_point(type))
|
||||||
|
{
|
||||||
|
if (!options.vulkan_semantics)
|
||||||
|
SPIRV_CROSS_THROW("Floating point atomics requires Vulkan semantics.");
|
||||||
|
if (options.es)
|
||||||
|
SPIRV_CROSS_THROW("Floating point atomics requires desktop GLSL.");
|
||||||
|
require_extension_internal("GL_EXT_shader_atomic_float");
|
||||||
|
}
|
||||||
|
|
||||||
forced_temporaries.insert(result_id);
|
forced_temporaries.insert(result_id);
|
||||||
emit_op(result_type, result_id,
|
emit_op(result_type, result_id,
|
||||||
join(op, "(", to_non_uniform_aware_expression(op0), ", ",
|
join(op, "(", to_non_uniform_aware_expression(op0), ", ",
|
||||||
@ -6340,7 +6402,11 @@ string CompilerGLSL::legacy_tex_op(const std::string &op, const SPIRType &imgtyp
|
|||||||
switch (imgtype.image.dim)
|
switch (imgtype.image.dim)
|
||||||
{
|
{
|
||||||
case spv::Dim1D:
|
case spv::Dim1D:
|
||||||
type = (imgtype.image.arrayed && !options.es) ? "1DArray" : "1D";
|
// Force 2D path for ES.
|
||||||
|
if (options.es)
|
||||||
|
type = (imgtype.image.arrayed && !options.es) ? "2DArray" : "2D";
|
||||||
|
else
|
||||||
|
type = (imgtype.image.arrayed && !options.es) ? "1DArray" : "1D";
|
||||||
break;
|
break;
|
||||||
case spv::Dim2D:
|
case spv::Dim2D:
|
||||||
type = (imgtype.image.arrayed && !options.es) ? "2DArray" : "2D";
|
type = (imgtype.image.arrayed && !options.es) ? "2DArray" : "2D";
|
||||||
@ -7018,8 +7084,8 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool
|
|||||||
expr += to_function_args(args, forward);
|
expr += to_function_args(args, forward);
|
||||||
expr += ")";
|
expr += ")";
|
||||||
|
|
||||||
// texture(samplerXShadow) returns float. shadowX() returns vec4. Swizzle here.
|
// texture(samplerXShadow) returns float. shadowX() returns vec4, but only in desktop GLSL. Swizzle here.
|
||||||
if (is_legacy() && is_depth_image(imgtype, img))
|
if (is_legacy() && !options.es && is_depth_image(imgtype, img))
|
||||||
expr += ".r";
|
expr += ".r";
|
||||||
|
|
||||||
// Sampling from a texture which was deduced to be a depth image, might actually return 1 component here.
|
// Sampling from a texture which was deduced to be a depth image, might actually return 1 component here.
|
||||||
@ -7300,10 +7366,29 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool
|
|||||||
// Create a composite which merges coord/dref into a single vector.
|
// Create a composite which merges coord/dref into a single vector.
|
||||||
auto type = expression_type(args.coord);
|
auto type = expression_type(args.coord);
|
||||||
type.vecsize = args.coord_components + 1;
|
type.vecsize = args.coord_components + 1;
|
||||||
|
if (imgtype.image.dim == Dim1D && options.es)
|
||||||
|
type.vecsize++;
|
||||||
farg_str += ", ";
|
farg_str += ", ";
|
||||||
farg_str += type_to_glsl_constructor(type);
|
farg_str += type_to_glsl_constructor(type);
|
||||||
farg_str += "(";
|
farg_str += "(";
|
||||||
farg_str += coord_expr;
|
|
||||||
|
if (imgtype.image.dim == Dim1D && options.es)
|
||||||
|
{
|
||||||
|
if (imgtype.image.arrayed)
|
||||||
|
{
|
||||||
|
farg_str += enclose_expression(coord_expr) + ".x";
|
||||||
|
farg_str += ", 0.0, ";
|
||||||
|
farg_str += enclose_expression(coord_expr) + ".y";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
farg_str += coord_expr;
|
||||||
|
farg_str += ", 0.0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
farg_str += coord_expr;
|
||||||
|
|
||||||
farg_str += ", ";
|
farg_str += ", ";
|
||||||
farg_str += to_expression(args.dref);
|
farg_str += to_expression(args.dref);
|
||||||
farg_str += ")";
|
farg_str += ")";
|
||||||
@ -7311,6 +7396,33 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (imgtype.image.dim == Dim1D && options.es)
|
||||||
|
{
|
||||||
|
// Have to fake a second coordinate.
|
||||||
|
if (type_is_floating_point(coord_type))
|
||||||
|
{
|
||||||
|
// Cannot mix proj and array.
|
||||||
|
if (imgtype.image.arrayed || args.base.is_proj)
|
||||||
|
{
|
||||||
|
coord_expr = join("vec3(", enclose_expression(coord_expr), ".x, 0.0, ",
|
||||||
|
enclose_expression(coord_expr), ".y)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
coord_expr = join("vec2(", coord_expr, ", 0.0)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (imgtype.image.arrayed)
|
||||||
|
{
|
||||||
|
coord_expr = join("ivec3(", enclose_expression(coord_expr),
|
||||||
|
".x, 0, ",
|
||||||
|
enclose_expression(coord_expr), ".y)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
coord_expr = join("ivec2(", coord_expr, ", 0)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
farg_str += ", ";
|
farg_str += ", ";
|
||||||
farg_str += coord_expr;
|
farg_str += coord_expr;
|
||||||
}
|
}
|
||||||
@ -8698,24 +8810,42 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
|
|||||||
case BuiltInIncomingRayFlagsKHR:
|
case BuiltInIncomingRayFlagsKHR:
|
||||||
return ray_tracing_is_khr ? "gl_IncomingRayFlagsEXT" : "gl_IncomingRayFlagsNV";
|
return ray_tracing_is_khr ? "gl_IncomingRayFlagsEXT" : "gl_IncomingRayFlagsNV";
|
||||||
|
|
||||||
case BuiltInBaryCoordNV:
|
case BuiltInBaryCoordKHR:
|
||||||
{
|
{
|
||||||
if (options.es && options.version < 320)
|
if (options.es && options.version < 320)
|
||||||
SPIRV_CROSS_THROW("gl_BaryCoordNV requires ESSL 320.");
|
SPIRV_CROSS_THROW("gl_BaryCoordEXT requires ESSL 320.");
|
||||||
else if (!options.es && options.version < 450)
|
else if (!options.es && options.version < 450)
|
||||||
SPIRV_CROSS_THROW("gl_BaryCoordNV requires GLSL 450.");
|
SPIRV_CROSS_THROW("gl_BaryCoordEXT requires GLSL 450.");
|
||||||
require_extension_internal("GL_NV_fragment_shader_barycentric");
|
|
||||||
return "gl_BaryCoordNV";
|
if (barycentric_is_nv)
|
||||||
|
{
|
||||||
|
require_extension_internal("GL_NV_fragment_shader_barycentric");
|
||||||
|
return "gl_BaryCoordNV";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
require_extension_internal("GL_EXT_fragment_shader_barycentric");
|
||||||
|
return "gl_BaryCoordEXT";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case BuiltInBaryCoordNoPerspNV:
|
case BuiltInBaryCoordNoPerspNV:
|
||||||
{
|
{
|
||||||
if (options.es && options.version < 320)
|
if (options.es && options.version < 320)
|
||||||
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspNV requires ESSL 320.");
|
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspEXT requires ESSL 320.");
|
||||||
else if (!options.es && options.version < 450)
|
else if (!options.es && options.version < 450)
|
||||||
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspNV requires GLSL 450.");
|
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspEXT requires GLSL 450.");
|
||||||
require_extension_internal("GL_NV_fragment_shader_barycentric");
|
|
||||||
return "gl_BaryCoordNoPerspNV";
|
if (barycentric_is_nv)
|
||||||
|
{
|
||||||
|
require_extension_internal("GL_NV_fragment_shader_barycentric");
|
||||||
|
return "gl_BaryCoordNoPerspNV";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
require_extension_internal("GL_EXT_fragment_shader_barycentric");
|
||||||
|
return "gl_BaryCoordNoPerspEXT";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case BuiltInFragStencilRefEXT:
|
case BuiltInFragStencilRefEXT:
|
||||||
@ -8860,6 +8990,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
|||||||
if (!is_literal)
|
if (!is_literal)
|
||||||
mod_flags &= ~ACCESS_CHAIN_INDEX_IS_LITERAL_BIT;
|
mod_flags &= ~ACCESS_CHAIN_INDEX_IS_LITERAL_BIT;
|
||||||
access_chain_internal_append_index(expr, base, type, mod_flags, access_chain_is_arrayed, index);
|
access_chain_internal_append_index(expr, base, type, mod_flags, access_chain_is_arrayed, index);
|
||||||
|
check_physical_type_cast(expr, type, physical_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uint32_t i = 0; i < count; i++)
|
for (uint32_t i = 0; i < count; i++)
|
||||||
@ -9192,6 +9323,10 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CompilerGLSL::check_physical_type_cast(std::string &, const SPIRType *, uint32_t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void CompilerGLSL::prepare_access_chain_for_scalar_access(std::string &, const SPIRType &, spv::StorageClass, bool &)
|
void CompilerGLSL::prepare_access_chain_for_scalar_access(std::string &, const SPIRType &, spv::StorageClass, bool &)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -12132,6 +12267,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case OpAtomicIAdd:
|
case OpAtomicIAdd:
|
||||||
|
case OpAtomicFAddEXT:
|
||||||
{
|
{
|
||||||
const char *op = check_atomic_image(ops[2]) ? "imageAtomicAdd" : "atomicAdd";
|
const char *op = check_atomic_image(ops[2]) ? "imageAtomicAdd" : "atomicAdd";
|
||||||
emit_atomic_func_op(ops[0], ops[1], ops[2], ops[5], op);
|
emit_atomic_func_op(ops[0], ops[1], ops[2], ops[5], op);
|
||||||
@ -12484,6 +12620,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
target_coord_type.basetype = SPIRType::Int;
|
target_coord_type.basetype = SPIRType::Int;
|
||||||
coord_expr = bitcast_expression(target_coord_type, expression_type(ops[3]).basetype, coord_expr);
|
coord_expr = bitcast_expression(target_coord_type, expression_type(ops[3]).basetype, coord_expr);
|
||||||
|
|
||||||
|
// ES needs to emulate 1D images as 2D.
|
||||||
|
if (type.image.dim == Dim1D && options.es)
|
||||||
|
coord_expr = join("ivec2(", coord_expr, ", 0)");
|
||||||
|
|
||||||
// Plain image load/store.
|
// Plain image load/store.
|
||||||
if (sparse)
|
if (sparse)
|
||||||
{
|
{
|
||||||
@ -12596,6 +12736,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
target_coord_type.basetype = SPIRType::Int;
|
target_coord_type.basetype = SPIRType::Int;
|
||||||
coord_expr = bitcast_expression(target_coord_type, expression_type(ops[1]).basetype, coord_expr);
|
coord_expr = bitcast_expression(target_coord_type, expression_type(ops[1]).basetype, coord_expr);
|
||||||
|
|
||||||
|
// ES needs to emulate 1D images as 2D.
|
||||||
|
if (type.image.dim == Dim1D && options.es)
|
||||||
|
coord_expr = join("ivec2(", coord_expr, ", 0)");
|
||||||
|
|
||||||
if (type.image.ms)
|
if (type.image.ms)
|
||||||
{
|
{
|
||||||
uint32_t operands = ops[3];
|
uint32_t operands = ops[3];
|
||||||
@ -13249,9 +13393,30 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
#undef GLSL_RAY_QUERY_GET_OP2
|
#undef GLSL_RAY_QUERY_GET_OP2
|
||||||
|
|
||||||
case OpConvertUToAccelerationStructureKHR:
|
case OpConvertUToAccelerationStructureKHR:
|
||||||
|
{
|
||||||
require_extension_internal("GL_EXT_ray_tracing");
|
require_extension_internal("GL_EXT_ray_tracing");
|
||||||
GLSL_UFOP(accelerationStructureEXT);
|
|
||||||
|
bool elide_temporary = should_forward(ops[2]) && forced_temporaries.count(ops[1]) == 0 &&
|
||||||
|
!hoisted_temporaries.count(ops[1]);
|
||||||
|
|
||||||
|
if (elide_temporary)
|
||||||
|
{
|
||||||
|
GLSL_UFOP(accelerationStructureEXT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Force this path in subsequent iterations.
|
||||||
|
forced_temporaries.insert(ops[1]);
|
||||||
|
|
||||||
|
// We cannot declare a temporary acceleration structure in GLSL.
|
||||||
|
// If we get to this point, we'll have to emit a temporary uvec2,
|
||||||
|
// and cast to RTAS on demand.
|
||||||
|
statement(declare_temporary(expression_type_id(ops[2]), ops[1]), to_unpacked_expression(ops[2]), ";");
|
||||||
|
// Use raw SPIRExpression interface to block all usage tracking.
|
||||||
|
set<SPIRExpression>(ops[1], join("accelerationStructureEXT(", to_name(ops[1]), ")"), ops[0], true);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case OpConvertUToPtr:
|
case OpConvertUToPtr:
|
||||||
{
|
{
|
||||||
@ -13956,7 +14121,8 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
|||||||
switch (type.image.dim)
|
switch (type.image.dim)
|
||||||
{
|
{
|
||||||
case Dim1D:
|
case Dim1D:
|
||||||
res += "1D";
|
// ES doesn't support 1D. Fake it with 2D.
|
||||||
|
res += options.es ? "2D" : "1D";
|
||||||
break;
|
break;
|
||||||
case Dim2D:
|
case Dim2D:
|
||||||
res += "2D";
|
res += "2D";
|
||||||
@ -15587,26 +15753,32 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||||||
// If there is only one default block, and no cases, this is a case where SPIRV-opt decided to emulate
|
// If there is only one default block, and no cases, this is a case where SPIRV-opt decided to emulate
|
||||||
// non-structured exits with the help of a switch block.
|
// non-structured exits with the help of a switch block.
|
||||||
// This is buggy on FXC, so just emit the logical equivalent of a do { } while(false), which is more idiomatic.
|
// This is buggy on FXC, so just emit the logical equivalent of a do { } while(false), which is more idiomatic.
|
||||||
bool degenerate_switch = block.default_block != block.merge_block && cases.empty();
|
bool block_like_switch = cases.empty();
|
||||||
|
|
||||||
if (degenerate_switch || is_legacy_es())
|
// If this is true, the switch is completely meaningless, and we should just avoid it.
|
||||||
|
bool collapsed_switch = block_like_switch && block.default_block == block.next_block;
|
||||||
|
|
||||||
|
if (!collapsed_switch)
|
||||||
{
|
{
|
||||||
// ESSL 1.0 is not guaranteed to support do/while.
|
if (block_like_switch || is_legacy_es())
|
||||||
if (is_legacy_es())
|
|
||||||
{
|
{
|
||||||
uint32_t counter = statement_count;
|
// ESSL 1.0 is not guaranteed to support do/while.
|
||||||
statement("for (int spvDummy", counter, " = 0; spvDummy", counter,
|
if (is_legacy_es())
|
||||||
" < 1; spvDummy", counter, "++)");
|
{
|
||||||
|
uint32_t counter = statement_count;
|
||||||
|
statement("for (int spvDummy", counter, " = 0; spvDummy", counter, " < 1; spvDummy", counter,
|
||||||
|
"++)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
statement("do");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
statement("do");
|
{
|
||||||
|
emit_block_hints(block);
|
||||||
|
statement("switch (", to_unpacked_expression(block.condition), ")");
|
||||||
|
}
|
||||||
|
begin_scope();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
emit_block_hints(block);
|
|
||||||
statement("switch (", to_unpacked_expression(block.condition), ")");
|
|
||||||
}
|
|
||||||
begin_scope();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_blocks; i++)
|
for (size_t i = 0; i < num_blocks; i++)
|
||||||
{
|
{
|
||||||
@ -15616,7 +15788,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||||||
if (literals.empty())
|
if (literals.empty())
|
||||||
{
|
{
|
||||||
// Default case.
|
// Default case.
|
||||||
if (!degenerate_switch)
|
if (!block_like_switch)
|
||||||
{
|
{
|
||||||
if (is_legacy_es())
|
if (is_legacy_es())
|
||||||
statement("else");
|
statement("else");
|
||||||
@ -15654,10 +15826,10 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||||||
else
|
else
|
||||||
current_emitting_switch_fallthrough = false;
|
current_emitting_switch_fallthrough = false;
|
||||||
|
|
||||||
if (!degenerate_switch)
|
if (!block_like_switch)
|
||||||
begin_scope();
|
begin_scope();
|
||||||
branch(block.self, target_block);
|
branch(block.self, target_block);
|
||||||
if (!degenerate_switch)
|
if (!block_like_switch)
|
||||||
end_scope();
|
end_scope();
|
||||||
|
|
||||||
current_emitting_switch_fallthrough = false;
|
current_emitting_switch_fallthrough = false;
|
||||||
@ -15671,7 +15843,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||||||
// - Header -> Merge requires flushing PHI. In this case, we need to collect all cases and flush PHI there.
|
// - Header -> Merge requires flushing PHI. In this case, we need to collect all cases and flush PHI there.
|
||||||
bool header_merge_requires_phi = flush_phi_required(block.self, block.next_block);
|
bool header_merge_requires_phi = flush_phi_required(block.self, block.next_block);
|
||||||
bool need_fallthrough_block = block.default_block == block.next_block || !literals_to_merge.empty();
|
bool need_fallthrough_block = block.default_block == block.next_block || !literals_to_merge.empty();
|
||||||
if ((header_merge_requires_phi && need_fallthrough_block) || !literals_to_merge.empty())
|
if (!collapsed_switch && ((header_merge_requires_phi && need_fallthrough_block) || !literals_to_merge.empty()))
|
||||||
{
|
{
|
||||||
for (auto &case_literal : literals_to_merge)
|
for (auto &case_literal : literals_to_merge)
|
||||||
statement("case ", to_case_label(case_literal, type.width, unsigned_case), label_suffix, ":");
|
statement("case ", to_case_label(case_literal, type.width, unsigned_case), label_suffix, ":");
|
||||||
@ -15690,10 +15862,15 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||||||
end_scope();
|
end_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (degenerate_switch && !is_legacy_es())
|
if (!collapsed_switch)
|
||||||
end_scope_decl("while(false)");
|
{
|
||||||
|
if (block_like_switch && !is_legacy_es())
|
||||||
|
end_scope_decl("while(false)");
|
||||||
|
else
|
||||||
|
end_scope();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
end_scope();
|
flush_phi(block.self, block.next_block);
|
||||||
|
|
||||||
if (block.need_ladder_break)
|
if (block.need_ladder_break)
|
||||||
{
|
{
|
||||||
|
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
@ -711,6 +711,7 @@ protected:
|
|||||||
spv::StorageClass get_expression_effective_storage_class(uint32_t ptr);
|
spv::StorageClass get_expression_effective_storage_class(uint32_t ptr);
|
||||||
virtual bool access_chain_needs_stage_io_builtin_translation(uint32_t base);
|
virtual bool access_chain_needs_stage_io_builtin_translation(uint32_t base);
|
||||||
|
|
||||||
|
virtual void check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type);
|
||||||
virtual void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type,
|
virtual void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type,
|
||||||
spv::StorageClass storage, bool &is_packed);
|
spv::StorageClass storage, bool &is_packed);
|
||||||
|
|
||||||
@ -877,6 +878,7 @@ protected:
|
|||||||
bool requires_transpose_3x3 = false;
|
bool requires_transpose_3x3 = false;
|
||||||
bool requires_transpose_4x4 = false;
|
bool requires_transpose_4x4 = false;
|
||||||
bool ray_tracing_is_khr = false;
|
bool ray_tracing_is_khr = false;
|
||||||
|
bool barycentric_is_nv = false;
|
||||||
void ray_tracing_khr_fixup_locations();
|
void ray_tracing_khr_fixup_locations();
|
||||||
|
|
||||||
bool args_will_forward(uint32_t id, const uint32_t *args, uint32_t num_args, bool pure);
|
bool args_will_forward(uint32_t id, const uint32_t *args, uint32_t num_args, bool pure);
|
||||||
|
20
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
20
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
@ -645,9 +645,9 @@ void CompilerHLSL::emit_builtin_outputs_in_struct()
|
|||||||
|
|
||||||
case BuiltInLayer:
|
case BuiltInLayer:
|
||||||
if (hlsl_options.shader_model < 50 || get_entry_point().model != ExecutionModelGeometry)
|
if (hlsl_options.shader_model < 50 || get_entry_point().model != ExecutionModelGeometry)
|
||||||
SPIRV_CROSS_THROW("Render target index output is only supported in GS 5.0 or higher.");
|
SPIRV_CROSS_THROW("Render target array index output is only supported in GS 5.0 or higher.");
|
||||||
type = "uint";
|
type = "uint";
|
||||||
semantic = "SV_RenderTargetIndex";
|
semantic = "SV_RenderTargetArrayIndex";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -797,9 +797,9 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
|
|||||||
|
|
||||||
case BuiltInLayer:
|
case BuiltInLayer:
|
||||||
if (hlsl_options.shader_model < 50 || get_entry_point().model != ExecutionModelFragment)
|
if (hlsl_options.shader_model < 50 || get_entry_point().model != ExecutionModelFragment)
|
||||||
SPIRV_CROSS_THROW("Render target index input is only supported in PS 5.0 or higher.");
|
SPIRV_CROSS_THROW("Render target array index input is only supported in PS 5.0 or higher.");
|
||||||
type = "uint";
|
type = "uint";
|
||||||
semantic = "SV_RenderTargetIndex";
|
semantic = "SV_RenderTargetArrayIndex";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -3598,6 +3598,18 @@ string CompilerHLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &i
|
|||||||
}
|
}
|
||||||
return "spvPackFloat2x16";
|
return "spvPackFloat2x16";
|
||||||
}
|
}
|
||||||
|
else if (out_type.basetype == SPIRType::UShort && in_type.basetype == SPIRType::Half)
|
||||||
|
{
|
||||||
|
if (hlsl_options.shader_model < 40)
|
||||||
|
SPIRV_CROSS_THROW("Half to UShort requires Shader Model 4.");
|
||||||
|
return "(" + type_to_glsl(out_type) + ")f32tof16";
|
||||||
|
}
|
||||||
|
else if (out_type.basetype == SPIRType::Half && in_type.basetype == SPIRType::UShort)
|
||||||
|
{
|
||||||
|
if (hlsl_options.shader_model < 40)
|
||||||
|
SPIRV_CROSS_THROW("UShort to Half requires Shader Model 4.");
|
||||||
|
return "(" + type_to_glsl(out_type) + ")f16tof32";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
179
3rdparty/spirv-cross/spirv_msl.cpp
vendored
179
3rdparty/spirv-cross/spirv_msl.cpp
vendored
@ -1967,6 +1967,13 @@ void CompilerMSL::mark_packable_structs()
|
|||||||
mark_as_packable(type);
|
mark_as_packable(type);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Physical storage buffer pointers can appear outside of the context of a variable, if the address
|
||||||
|
// is calculated from a ulong or uvec2 and cast to a pointer, so check if they need to be packed too.
|
||||||
|
ir.for_each_typed_id<SPIRType>([&](uint32_t, SPIRType &type) {
|
||||||
|
if (type.basetype == SPIRType::Struct && type.pointer && type.storage == StorageClassPhysicalStorageBuffer)
|
||||||
|
mark_as_packable(type);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the specified type is a struct, it and any nested structs
|
// If the specified type is a struct, it and any nested structs
|
||||||
@ -1980,7 +1987,8 @@ void CompilerMSL::mark_as_packable(SPIRType &type)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.basetype == SPIRType::Struct)
|
// Handle possible recursion when a struct contains a pointer to its own type nested somewhere.
|
||||||
|
if (type.basetype == SPIRType::Struct && !has_extended_decoration(type.self, SPIRVCrossDecorationBufferBlockRepacked))
|
||||||
{
|
{
|
||||||
set_extended_decoration(type.self, SPIRVCrossDecorationBufferBlockRepacked);
|
set_extended_decoration(type.self, SPIRVCrossDecorationBufferBlockRepacked);
|
||||||
|
|
||||||
@ -3175,6 +3183,9 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (storage == StorageClassInput && has_decoration(var.self, DecorationPerVertexKHR))
|
||||||
|
SPIRV_CROSS_THROW("PerVertexKHR decoration is not supported in MSL.");
|
||||||
|
|
||||||
// If variable names alias, they will end up with wrong names in the interface struct, because
|
// If variable names alias, they will end up with wrong names in the interface struct, because
|
||||||
// there might be aliases in the member name cache and there would be a mismatch in fixup_in code.
|
// there might be aliases in the member name cache and there would be a mismatch in fixup_in code.
|
||||||
// Make sure to register the variables as unique resource names ahead of time.
|
// Make sure to register the variables as unique resource names ahead of time.
|
||||||
@ -3458,7 +3469,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
|
|||||||
|
|
||||||
bool builtin_is_stage_in_out = builtin_is_gl_in_out ||
|
bool builtin_is_stage_in_out = builtin_is_gl_in_out ||
|
||||||
bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex ||
|
bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex ||
|
||||||
bi_type == BuiltInBaryCoordNV || bi_type == BuiltInBaryCoordNoPerspNV ||
|
bi_type == BuiltInBaryCoordKHR || bi_type == BuiltInBaryCoordNoPerspKHR ||
|
||||||
bi_type == BuiltInFragDepth ||
|
bi_type == BuiltInFragDepth ||
|
||||||
bi_type == BuiltInFragStencilRefEXT || bi_type == BuiltInSampleMask;
|
bi_type == BuiltInFragStencilRefEXT || bi_type == BuiltInSampleMask;
|
||||||
|
|
||||||
@ -3515,7 +3526,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Barycentric inputs must be emitted in stage-in, because they can have interpolation arguments.
|
// Barycentric inputs must be emitted in stage-in, because they can have interpolation arguments.
|
||||||
if (is_active && (bi_type == BuiltInBaryCoordNV || bi_type == BuiltInBaryCoordNoPerspNV))
|
if (is_active && (bi_type == BuiltInBaryCoordKHR || bi_type == BuiltInBaryCoordNoPerspKHR))
|
||||||
{
|
{
|
||||||
if (has_seen_barycentric)
|
if (has_seen_barycentric)
|
||||||
SPIRV_CROSS_THROW("Cannot declare both BaryCoordNV and BaryCoordNoPerspNV in same shader in MSL.");
|
SPIRV_CROSS_THROW("Cannot declare both BaryCoordNV and BaryCoordNoPerspNV in same shader in MSL.");
|
||||||
@ -4036,6 +4047,10 @@ uint32_t CompilerMSL::ensure_correct_input_type(uint32_t type_id, uint32_t locat
|
|||||||
|
|
||||||
void CompilerMSL::mark_struct_members_packed(const SPIRType &type)
|
void CompilerMSL::mark_struct_members_packed(const SPIRType &type)
|
||||||
{
|
{
|
||||||
|
// Handle possible recursion when a struct contains a pointer to its own type nested somewhere.
|
||||||
|
if (has_extended_decoration(type.self, SPIRVCrossDecorationPhysicalTypePacked))
|
||||||
|
return;
|
||||||
|
|
||||||
set_extended_decoration(type.self, SPIRVCrossDecorationPhysicalTypePacked);
|
set_extended_decoration(type.self, SPIRVCrossDecorationPhysicalTypePacked);
|
||||||
|
|
||||||
// Problem case! Struct needs to be placed at an awkward alignment.
|
// Problem case! Struct needs to be placed at an awkward alignment.
|
||||||
@ -4062,8 +4077,9 @@ void CompilerMSL::mark_scalar_layout_structs(const SPIRType &type)
|
|||||||
uint32_t mbr_cnt = uint32_t(type.member_types.size());
|
uint32_t mbr_cnt = uint32_t(type.member_types.size());
|
||||||
for (uint32_t i = 0; i < mbr_cnt; i++)
|
for (uint32_t i = 0; i < mbr_cnt; i++)
|
||||||
{
|
{
|
||||||
|
// Handle possible recursion when a struct contains a pointer to its own type nested somewhere.
|
||||||
auto &mbr_type = get<SPIRType>(type.member_types[i]);
|
auto &mbr_type = get<SPIRType>(type.member_types[i]);
|
||||||
if (mbr_type.basetype == SPIRType::Struct)
|
if (mbr_type.basetype == SPIRType::Struct && !(mbr_type.pointer && mbr_type.storage == StorageClassPhysicalStorageBuffer))
|
||||||
{
|
{
|
||||||
auto *struct_type = &mbr_type;
|
auto *struct_type = &mbr_type;
|
||||||
while (!struct_type->array.empty())
|
while (!struct_type->array.empty())
|
||||||
@ -4275,8 +4291,10 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in
|
|||||||
// This case will be nightmare-ish to deal with. This could possibly happen if struct alignment does not quite
|
// This case will be nightmare-ish to deal with. This could possibly happen if struct alignment does not quite
|
||||||
// match up with what we want. Scalar block layout comes to mind here where we might have to work around the rule
|
// match up with what we want. Scalar block layout comes to mind here where we might have to work around the rule
|
||||||
// that struct alignment == max alignment of all members and struct size depends on this alignment.
|
// that struct alignment == max alignment of all members and struct size depends on this alignment.
|
||||||
|
// Can't repack structs, but can repack pointers to structs.
|
||||||
auto &mbr_type = get<SPIRType>(ib_type.member_types[index]);
|
auto &mbr_type = get<SPIRType>(ib_type.member_types[index]);
|
||||||
if (mbr_type.basetype == SPIRType::Struct)
|
bool is_buff_ptr = mbr_type.pointer && mbr_type.storage == StorageClassPhysicalStorageBuffer;
|
||||||
|
if (mbr_type.basetype == SPIRType::Struct && !is_buff_ptr)
|
||||||
SPIRV_CROSS_THROW("Cannot perform any repacking for structs when it is used as a member of another struct.");
|
SPIRV_CROSS_THROW("Cannot perform any repacking for structs when it is used as a member of another struct.");
|
||||||
|
|
||||||
// Perform remapping here.
|
// Perform remapping here.
|
||||||
@ -4303,7 +4321,9 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in
|
|||||||
for (uint32_t dim = 0; dim < dimensions; dim++)
|
for (uint32_t dim = 0; dim < dimensions; dim++)
|
||||||
array_stride /= max(to_array_size_literal(mbr_type, dim), 1u);
|
array_stride /= max(to_array_size_literal(mbr_type, dim), 1u);
|
||||||
|
|
||||||
uint32_t elems_per_stride = array_stride / (mbr_type.width / 8);
|
// Pointers are 8 bytes
|
||||||
|
uint32_t mbr_width_in_bytes = is_buff_ptr ? 8 : (mbr_type.width / 8);
|
||||||
|
uint32_t elems_per_stride = array_stride / mbr_width_in_bytes;
|
||||||
|
|
||||||
if (elems_per_stride == 3)
|
if (elems_per_stride == 3)
|
||||||
SPIRV_CROSS_THROW("Cannot use ArrayStride of 3 elements in remapping scenarios.");
|
SPIRV_CROSS_THROW("Cannot use ArrayStride of 3 elements in remapping scenarios.");
|
||||||
@ -4313,6 +4333,17 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in
|
|||||||
auto physical_type = mbr_type;
|
auto physical_type = mbr_type;
|
||||||
physical_type.vecsize = elems_per_stride;
|
physical_type.vecsize = elems_per_stride;
|
||||||
physical_type.parent_type = 0;
|
physical_type.parent_type = 0;
|
||||||
|
|
||||||
|
// If this is a physical buffer pointer, replace type with a ulongn vector.
|
||||||
|
if (is_buff_ptr)
|
||||||
|
{
|
||||||
|
physical_type.width = 64;
|
||||||
|
physical_type.basetype = to_unsigned_basetype(physical_type.width);
|
||||||
|
physical_type.pointer = false;
|
||||||
|
physical_type.pointer_depth = false;
|
||||||
|
physical_type.forward_pointer = false;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t type_id = ir.increase_bound_by(1);
|
uint32_t type_id = ir.increase_bound_by(1);
|
||||||
set<SPIRType>(type_id, physical_type);
|
set<SPIRType>(type_id, physical_type);
|
||||||
set_extended_member_decoration(ib_type.self, index, SPIRVCrossDecorationPhysicalTypeID, type_id);
|
set_extended_member_decoration(ib_type.self, index, SPIRVCrossDecorationPhysicalTypeID, type_id);
|
||||||
@ -6789,6 +6820,25 @@ void CompilerMSL::emit_specialization_constants_and_structs()
|
|||||||
// these types for purpose of iterating over them in ir.ids_for_type and friends.
|
// these types for purpose of iterating over them in ir.ids_for_type and friends.
|
||||||
auto loop_lock = ir.create_loop_soft_lock();
|
auto loop_lock = ir.create_loop_soft_lock();
|
||||||
|
|
||||||
|
// Physical storage buffer pointers can have cyclical references,
|
||||||
|
// so emit forward declarations of them before other structs.
|
||||||
|
// Ignore type_id because we want the underlying struct type from the pointer.
|
||||||
|
ir.for_each_typed_id<SPIRType>([&](uint32_t /* type_id */, const SPIRType &type) {
|
||||||
|
if (type.basetype == SPIRType::Struct &&
|
||||||
|
type.pointer && type.storage == StorageClassPhysicalStorageBuffer &&
|
||||||
|
declared_structs.count(type.self) == 0)
|
||||||
|
{
|
||||||
|
statement("struct ", to_name(type.self), ";");
|
||||||
|
declared_structs.insert(type.self);
|
||||||
|
emitted = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (emitted)
|
||||||
|
statement("");
|
||||||
|
|
||||||
|
emitted = false;
|
||||||
|
declared_structs.clear();
|
||||||
|
|
||||||
for (auto &id_ : ir.ids_for_constant_or_type)
|
for (auto &id_ : ir.ids_for_constant_or_type)
|
||||||
{
|
{
|
||||||
auto &id = ir.ids[id_];
|
auto &id = ir.ids[id_];
|
||||||
@ -7675,6 +7725,23 @@ void CompilerMSL::fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t
|
|||||||
set_extended_decoration(ops[1], SPIRVCrossDecorationInterfaceMemberIndex, interface_index);
|
set_extended_decoration(ops[1], SPIRVCrossDecorationInterfaceMemberIndex, interface_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If the physical type of a physical buffer pointer has been changed
|
||||||
|
// to a ulong or ulongn vector, add a cast back to the pointer type.
|
||||||
|
void CompilerMSL::check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type)
|
||||||
|
{
|
||||||
|
auto *p_physical_type = maybe_get<SPIRType>(physical_type);
|
||||||
|
if (p_physical_type &&
|
||||||
|
p_physical_type->storage == StorageClassPhysicalStorageBuffer &&
|
||||||
|
p_physical_type->basetype == to_unsigned_basetype(64))
|
||||||
|
{
|
||||||
|
if (p_physical_type->vecsize > 1)
|
||||||
|
expr += ".x";
|
||||||
|
|
||||||
|
expr = join("((", type_to_glsl(*type), ")", expr, ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Override for MSL-specific syntax instructions
|
// Override for MSL-specific syntax instructions
|
||||||
void CompilerMSL::emit_instruction(const Instruction &instruction)
|
void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||||
{
|
{
|
||||||
@ -11072,8 +11139,8 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
|
|||||||
case BuiltInSampleId:
|
case BuiltInSampleId:
|
||||||
case BuiltInSampleMask:
|
case BuiltInSampleMask:
|
||||||
case BuiltInLayer:
|
case BuiltInLayer:
|
||||||
case BuiltInBaryCoordNV:
|
case BuiltInBaryCoordKHR:
|
||||||
case BuiltInBaryCoordNoPerspNV:
|
case BuiltInBaryCoordNoPerspKHR:
|
||||||
quals = builtin_qualifier(builtin);
|
quals = builtin_qualifier(builtin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -11089,7 +11156,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
|
|||||||
else
|
else
|
||||||
quals = member_location_attribute_qualifier(type, index);
|
quals = member_location_attribute_qualifier(type, index);
|
||||||
|
|
||||||
if (builtin == BuiltInBaryCoordNV || builtin == BuiltInBaryCoordNoPerspNV)
|
if (builtin == BuiltInBaryCoordKHR || builtin == BuiltInBaryCoordNoPerspKHR)
|
||||||
{
|
{
|
||||||
if (has_member_decoration(type.self, index, DecorationFlat) ||
|
if (has_member_decoration(type.self, index, DecorationFlat) ||
|
||||||
has_member_decoration(type.self, index, DecorationCentroid) ||
|
has_member_decoration(type.self, index, DecorationCentroid) ||
|
||||||
@ -11397,6 +11464,7 @@ string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id, bo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case StorageClassStorageBuffer:
|
case StorageClassStorageBuffer:
|
||||||
|
case StorageClassPhysicalStorageBuffer:
|
||||||
{
|
{
|
||||||
// For arguments from variable pointers, we use the write count deduction, so
|
// For arguments from variable pointers, we use the write count deduction, so
|
||||||
// we should not assume any constness here. Only for global SSBOs.
|
// we should not assume any constness here. Only for global SSBOs.
|
||||||
@ -11555,8 +11623,8 @@ bool CompilerMSL::is_direct_input_builtin(BuiltIn bi_type)
|
|||||||
// Fragment function in
|
// Fragment function in
|
||||||
case BuiltInSamplePosition:
|
case BuiltInSamplePosition:
|
||||||
case BuiltInHelperInvocation:
|
case BuiltInHelperInvocation:
|
||||||
case BuiltInBaryCoordNV:
|
case BuiltInBaryCoordKHR:
|
||||||
case BuiltInBaryCoordNoPerspNV:
|
case BuiltInBaryCoordNoPerspKHR:
|
||||||
return false;
|
return false;
|
||||||
case BuiltInViewIndex:
|
case BuiltInViewIndex:
|
||||||
return get_execution_model() == ExecutionModelFragment && msl_options.multiview &&
|
return get_execution_model() == ExecutionModelFragment && msl_options.multiview &&
|
||||||
@ -13525,7 +13593,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
|||||||
const char *restrict_kw;
|
const char *restrict_kw;
|
||||||
|
|
||||||
auto type_address_space = get_type_address_space(type, id);
|
auto type_address_space = get_type_address_space(type, id);
|
||||||
auto type_decl = type_to_glsl(get<SPIRType>(type.parent_type), id);
|
const auto *p_parent_type = &get<SPIRType>(type.parent_type);
|
||||||
|
|
||||||
// Work around C pointer qualifier rules. If glsl_type is a pointer type as well
|
// Work around C pointer qualifier rules. If glsl_type is a pointer type as well
|
||||||
// we'll need to emit the address space to the right.
|
// we'll need to emit the address space to the right.
|
||||||
@ -13533,9 +13601,16 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
|||||||
// Prefer emitting thread T *foo over T thread* foo since it's more readable,
|
// Prefer emitting thread T *foo over T thread* foo since it's more readable,
|
||||||
// but we'll have to emit thread T * thread * T constant bar; for example.
|
// but we'll have to emit thread T * thread * T constant bar; for example.
|
||||||
if (type_is_pointer_to_pointer(type))
|
if (type_is_pointer_to_pointer(type))
|
||||||
type_name = join(type_decl, " ", type_address_space, " ");
|
type_name = join(type_to_glsl(*p_parent_type, id), " ", type_address_space, " ");
|
||||||
else
|
else
|
||||||
type_name = join(type_address_space, " ", type_decl);
|
{
|
||||||
|
// Since this is not a pointer-to-pointer, ensure we've dug down to the base type.
|
||||||
|
// Some situations chain pointers even though they are not formally pointers-of-pointers.
|
||||||
|
while (type_is_pointer(*p_parent_type))
|
||||||
|
p_parent_type = &get<SPIRType>(p_parent_type->parent_type);
|
||||||
|
|
||||||
|
type_name = join(type_address_space, " ", type_to_glsl(*p_parent_type, id));
|
||||||
|
}
|
||||||
|
|
||||||
switch (type.basetype)
|
switch (type.basetype)
|
||||||
{
|
{
|
||||||
@ -14320,18 +14395,31 @@ string CompilerMSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &in
|
|||||||
// size (eg. short shift right becomes int), which means chaining integer ops
|
// size (eg. short shift right becomes int), which means chaining integer ops
|
||||||
// together may introduce size variations that SPIR-V doesn't know about.
|
// together may introduce size variations that SPIR-V doesn't know about.
|
||||||
if (same_size_cast && !integral_cast)
|
if (same_size_cast && !integral_cast)
|
||||||
{
|
|
||||||
return "as_type<" + type_to_glsl(out_type) + ">";
|
return "as_type<" + type_to_glsl(out_type) + ">";
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return type_to_glsl(out_type);
|
return type_to_glsl(out_type);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerMSL::emit_complex_bitcast(uint32_t, uint32_t, uint32_t)
|
bool CompilerMSL::emit_complex_bitcast(uint32_t result_type, uint32_t id, uint32_t op0)
|
||||||
{
|
{
|
||||||
return false;
|
auto &out_type = get<SPIRType>(result_type);
|
||||||
|
auto &in_type = expression_type(op0);
|
||||||
|
bool uvec2_to_ptr = (in_type.basetype == SPIRType::UInt && in_type.vecsize == 2 &&
|
||||||
|
out_type.pointer && out_type.storage == StorageClassPhysicalStorageBuffer);
|
||||||
|
bool ptr_to_uvec2 = (in_type.pointer && in_type.storage == StorageClassPhysicalStorageBuffer &&
|
||||||
|
out_type.basetype == SPIRType::UInt && out_type.vecsize == 2);
|
||||||
|
string expr;
|
||||||
|
|
||||||
|
// Casting between uvec2 and buffer storage pointer per GL_EXT_buffer_reference_uvec2
|
||||||
|
if (uvec2_to_ptr)
|
||||||
|
expr = join("((", type_to_glsl(out_type), ")as_type<uint64_t>(", to_unpacked_expression(op0), "))");
|
||||||
|
else if (ptr_to_uvec2)
|
||||||
|
expr = join("as_type<", type_to_glsl(out_type), ">((uint64_t)", to_unpacked_expression(op0), ")");
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
emit_op(result_type, id, expr, should_forward(op0));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an MSL string identifying the name of a SPIR-V builtin.
|
// Returns an MSL string identifying the name of a SPIR-V builtin.
|
||||||
@ -14494,8 +14582,8 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
|
|||||||
return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
|
return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BuiltInBaryCoordNV:
|
case BuiltInBaryCoordKHR:
|
||||||
case BuiltInBaryCoordNoPerspNV:
|
case BuiltInBaryCoordNoPerspKHR:
|
||||||
if (storage == StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
|
if (storage == StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
|
||||||
return stage_in_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
|
return stage_in_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
|
||||||
break;
|
break;
|
||||||
@ -14732,16 +14820,14 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
|
|||||||
// Shouldn't be reached.
|
// Shouldn't be reached.
|
||||||
SPIRV_CROSS_THROW("Subgroup ballot masks are handled specially in MSL.");
|
SPIRV_CROSS_THROW("Subgroup ballot masks are handled specially in MSL.");
|
||||||
|
|
||||||
case BuiltInBaryCoordNV:
|
case BuiltInBaryCoordKHR:
|
||||||
// TODO: AMD barycentrics as well? Seem to have different swizzle and 2 components rather than 3.
|
|
||||||
if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3))
|
if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3))
|
||||||
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS.");
|
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS.");
|
||||||
else if (!msl_options.supports_msl_version(2, 2))
|
else if (!msl_options.supports_msl_version(2, 2))
|
||||||
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.2 and above on macOS.");
|
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.2 and above on macOS.");
|
||||||
return "barycentric_coord, center_perspective";
|
return "barycentric_coord, center_perspective";
|
||||||
|
|
||||||
case BuiltInBaryCoordNoPerspNV:
|
case BuiltInBaryCoordNoPerspKHR:
|
||||||
// TODO: AMD barycentrics as well? Seem to have different swizzle and 2 components rather than 3.
|
|
||||||
if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3))
|
if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3))
|
||||||
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS.");
|
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS.");
|
||||||
else if (!msl_options.supports_msl_version(2, 2))
|
else if (!msl_options.supports_msl_version(2, 2))
|
||||||
@ -14831,8 +14917,8 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin, uint32_t id)
|
|||||||
case BuiltInHelperInvocation:
|
case BuiltInHelperInvocation:
|
||||||
return "bool";
|
return "bool";
|
||||||
|
|
||||||
case BuiltInBaryCoordNV:
|
case BuiltInBaryCoordKHR:
|
||||||
case BuiltInBaryCoordNoPerspNV:
|
case BuiltInBaryCoordNoPerspKHR:
|
||||||
// Use the type as declared, can be 1, 2 or 3 components.
|
// Use the type as declared, can be 1, 2 or 3 components.
|
||||||
return type_to_glsl(get_variable_data_type(get<SPIRVariable>(id)));
|
return type_to_glsl(get_variable_data_type(get<SPIRVariable>(id)));
|
||||||
|
|
||||||
@ -15006,6 +15092,25 @@ uint32_t CompilerMSL::get_declared_struct_size_msl(const SPIRType &struct_type,
|
|||||||
// Returns the byte size of a struct member.
|
// Returns the byte size of a struct member.
|
||||||
uint32_t CompilerMSL::get_declared_type_size_msl(const SPIRType &type, bool is_packed, bool row_major) const
|
uint32_t CompilerMSL::get_declared_type_size_msl(const SPIRType &type, bool is_packed, bool row_major) const
|
||||||
{
|
{
|
||||||
|
// Pointers take 8 bytes each
|
||||||
|
if (type.pointer && type.storage == StorageClassPhysicalStorageBuffer)
|
||||||
|
{
|
||||||
|
uint32_t type_size = 8 * (type.vecsize == 3 ? 4 : type.vecsize);
|
||||||
|
|
||||||
|
// Work our way through potentially layered arrays,
|
||||||
|
// stopping when we hit a pointer that is not also an array.
|
||||||
|
int32_t dim_idx = (int32_t)type.array.size() - 1;
|
||||||
|
auto *p_type = &type;
|
||||||
|
while (!type_is_pointer(*p_type) && dim_idx >= 0)
|
||||||
|
{
|
||||||
|
type_size *= to_array_size_literal(*p_type, dim_idx);
|
||||||
|
p_type = &get<SPIRType>(p_type->parent_type);
|
||||||
|
dim_idx--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return type_size;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type.basetype)
|
switch (type.basetype)
|
||||||
{
|
{
|
||||||
case SPIRType::Unknown:
|
case SPIRType::Unknown:
|
||||||
@ -15065,6 +15170,10 @@ uint32_t CompilerMSL::get_declared_input_size_msl(const SPIRType &type, uint32_t
|
|||||||
// Returns the byte alignment of a type.
|
// Returns the byte alignment of a type.
|
||||||
uint32_t CompilerMSL::get_declared_type_alignment_msl(const SPIRType &type, bool is_packed, bool row_major) const
|
uint32_t CompilerMSL::get_declared_type_alignment_msl(const SPIRType &type, bool is_packed, bool row_major) const
|
||||||
{
|
{
|
||||||
|
// Pointers aligns on multiples of 8 bytes
|
||||||
|
if (type.pointer && type.storage == StorageClassPhysicalStorageBuffer)
|
||||||
|
return 8 * (type.vecsize == 3 ? 4 : type.vecsize);
|
||||||
|
|
||||||
switch (type.basetype)
|
switch (type.basetype)
|
||||||
{
|
{
|
||||||
case SPIRType::Unknown:
|
case SPIRType::Unknown:
|
||||||
@ -16404,6 +16513,20 @@ void CompilerMSL::emit_block_hints(const SPIRBlock &)
|
|||||||
string CompilerMSL::additional_fixed_sample_mask_str() const
|
string CompilerMSL::additional_fixed_sample_mask_str() const
|
||||||
{
|
{
|
||||||
char print_buffer[32];
|
char print_buffer[32];
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// snprintf does not exist or is buggy on older MSVC versions, some of
|
||||||
|
// them being used by MinGW. Use sprintf instead and disable
|
||||||
|
// corresponding warning.
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4996)
|
||||||
|
#endif
|
||||||
|
#if _WIN32
|
||||||
sprintf(print_buffer, "0x%x", msl_options.additional_fixed_sample_mask);
|
sprintf(print_buffer, "0x%x", msl_options.additional_fixed_sample_mask);
|
||||||
|
#else
|
||||||
|
snprintf(print_buffer, sizeof(print_buffer), "0x%x", msl_options.additional_fixed_sample_mask);
|
||||||
|
#endif
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
return print_buffer;
|
return print_buffer;
|
||||||
}
|
}
|
||||||
|
2
3rdparty/spirv-cross/spirv_msl.hpp
vendored
2
3rdparty/spirv-cross/spirv_msl.hpp
vendored
@ -986,6 +986,8 @@ protected:
|
|||||||
void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage,
|
void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage,
|
||||||
bool &is_packed) override;
|
bool &is_packed) override;
|
||||||
void fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t length);
|
void fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t length);
|
||||||
|
void check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type) override;
|
||||||
|
|
||||||
bool emit_tessellation_access_chain(const uint32_t *ops, uint32_t length);
|
bool emit_tessellation_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 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);
|
bool is_out_of_bounds_tessellation_level(uint32_t id_lhs);
|
||||||
|
Loading…
Reference in New Issue
Block a user