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
|
||||
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[--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[--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"
|
||||
|
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:
|
||||
** C, C++, C++11, JSON, Lua, Python, C#, D
|
||||
** C, C++, C++11, JSON, Lua, Python, C#, D, Beef
|
||||
**
|
||||
** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
||||
** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
||||
@ -41,6 +41,8 @@
|
||||
** - C# will use enum classes in the Specification class located in the "Spv" namespace,
|
||||
** e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||
** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
|
||||
** - Beef will use enum classes in the Specification class located in the "Spv" namespace,
|
||||
** e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||
**
|
||||
** Some tokens act like mask values, which can be OR'd together,
|
||||
** while others are mutually exclusive. The mask-like ones have
|
||||
@ -70,6 +72,7 @@ typedef enum SpvSourceLanguage_ {
|
||||
SpvSourceLanguageOpenCL_CPP = 4,
|
||||
SpvSourceLanguageHLSL = 5,
|
||||
SpvSourceLanguageCPP_for_OpenCL = 6,
|
||||
SpvSourceLanguageSYCL = 7,
|
||||
SpvSourceLanguageMax = 0x7fffffff,
|
||||
} SpvSourceLanguage;
|
||||
|
||||
@ -184,6 +187,7 @@ typedef enum SpvExecutionMode_ {
|
||||
SpvExecutionModeNoGlobalOffsetINTEL = 5895,
|
||||
SpvExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
||||
SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
|
||||
SpvExecutionModeNamedBarrierCountINTEL = 6417,
|
||||
SpvExecutionModeMax = 0x7fffffff,
|
||||
} SpvExecutionMode;
|
||||
|
||||
@ -546,6 +550,8 @@ typedef enum SpvDecoration_ {
|
||||
SpvDecorationPrefetchINTEL = 5902,
|
||||
SpvDecorationStallEnableINTEL = 5905,
|
||||
SpvDecorationFuseLoopsInFunctionINTEL = 5907,
|
||||
SpvDecorationAliasScopeINTEL = 5914,
|
||||
SpvDecorationNoAliasINTEL = 5915,
|
||||
SpvDecorationBufferLocationINTEL = 5921,
|
||||
SpvDecorationIOPipeStorageINTEL = 5944,
|
||||
SpvDecorationFunctionFloatingPointModeINTEL = 6080,
|
||||
@ -677,6 +683,7 @@ typedef enum SpvBuiltIn_ {
|
||||
SpvBuiltInSMCountNV = 5375,
|
||||
SpvBuiltInWarpIDNV = 5376,
|
||||
SpvBuiltInSMIDNV = 5377,
|
||||
SpvBuiltInCullMaskKHR = 6021,
|
||||
SpvBuiltInMax = 0x7fffffff,
|
||||
} SpvBuiltIn;
|
||||
|
||||
@ -804,6 +811,8 @@ typedef enum SpvMemoryAccessShift_ {
|
||||
SpvMemoryAccessMakePointerVisibleKHRShift = 4,
|
||||
SpvMemoryAccessNonPrivatePointerShift = 5,
|
||||
SpvMemoryAccessNonPrivatePointerKHRShift = 5,
|
||||
SpvMemoryAccessAliasScopeINTELMaskShift = 16,
|
||||
SpvMemoryAccessNoAliasINTELMaskShift = 17,
|
||||
SpvMemoryAccessMax = 0x7fffffff,
|
||||
} SpvMemoryAccessShift;
|
||||
|
||||
@ -818,6 +827,8 @@ typedef enum SpvMemoryAccessMask_ {
|
||||
SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
||||
SpvMemoryAccessNonPrivatePointerMask = 0x00000020,
|
||||
SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
||||
SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000,
|
||||
SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000,
|
||||
} SpvMemoryAccessMask;
|
||||
|
||||
typedef enum SpvScope_ {
|
||||
@ -1059,6 +1070,7 @@ typedef enum SpvCapability_ {
|
||||
SpvCapabilityFPGAMemoryAccessesINTEL = 5898,
|
||||
SpvCapabilityFPGAClusterAttributesINTEL = 5904,
|
||||
SpvCapabilityLoopFuseINTEL = 5906,
|
||||
SpvCapabilityMemoryAccessAliasingINTEL = 5910,
|
||||
SpvCapabilityFPGABufferLocationINTEL = 5920,
|
||||
SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922,
|
||||
SpvCapabilityUSMStorageClassesINTEL = 5935,
|
||||
@ -1073,13 +1085,17 @@ typedef enum SpvCapability_ {
|
||||
SpvCapabilityDotProductInput4x8BitPackedKHR = 6018,
|
||||
SpvCapabilityDotProduct = 6019,
|
||||
SpvCapabilityDotProductKHR = 6019,
|
||||
SpvCapabilityRayCullMaskKHR = 6020,
|
||||
SpvCapabilityBitInstructions = 6025,
|
||||
SpvCapabilityGroupNonUniformRotateKHR = 6026,
|
||||
SpvCapabilityAtomicFloat32AddEXT = 6033,
|
||||
SpvCapabilityAtomicFloat64AddEXT = 6034,
|
||||
SpvCapabilityLongConstantCompositeINTEL = 6089,
|
||||
SpvCapabilityOptNoneINTEL = 6094,
|
||||
SpvCapabilityAtomicFloat16AddEXT = 6095,
|
||||
SpvCapabilityDebugInfoModuleINTEL = 6114,
|
||||
SpvCapabilitySplitBarrierINTEL = 6141,
|
||||
SpvCapabilityGroupUniformArithmeticKHR = 6400,
|
||||
SpvCapabilityMax = 0x7fffffff,
|
||||
} SpvCapability;
|
||||
|
||||
@ -1535,6 +1551,7 @@ typedef enum SpvOp_ {
|
||||
SpvOpSubgroupAllKHR = 4428,
|
||||
SpvOpSubgroupAnyKHR = 4429,
|
||||
SpvOpSubgroupAllEqualKHR = 4430,
|
||||
SpvOpGroupNonUniformRotateKHR = 4431,
|
||||
SpvOpSubgroupReadInvocationKHR = 4432,
|
||||
SpvOpTraceRayKHR = 4445,
|
||||
SpvOpExecuteCallableKHR = 4446,
|
||||
@ -1801,6 +1818,9 @@ typedef enum SpvOp_ {
|
||||
SpvOpArbitraryFloatPowRINTEL = 5881,
|
||||
SpvOpArbitraryFloatPowNINTEL = 5882,
|
||||
SpvOpLoopControlINTEL = 5887,
|
||||
SpvOpAliasDomainDeclINTEL = 5911,
|
||||
SpvOpAliasScopeDeclINTEL = 5912,
|
||||
SpvOpAliasScopeListDeclINTEL = 5913,
|
||||
SpvOpFixedSqrtINTEL = 5923,
|
||||
SpvOpFixedRecipINTEL = 5924,
|
||||
SpvOpFixedRsqrtINTEL = 5925,
|
||||
@ -1839,10 +1859,23 @@ typedef enum SpvOp_ {
|
||||
SpvOpTypeStructContinuedINTEL = 6090,
|
||||
SpvOpConstantCompositeContinuedINTEL = 6091,
|
||||
SpvOpSpecConstantCompositeContinuedINTEL = 6092,
|
||||
SpvOpControlBarrierArriveINTEL = 6142,
|
||||
SpvOpControlBarrierWaitINTEL = 6143,
|
||||
SpvOpGroupIMulKHR = 6401,
|
||||
SpvOpGroupFMulKHR = 6402,
|
||||
SpvOpGroupBitwiseAndKHR = 6403,
|
||||
SpvOpGroupBitwiseOrKHR = 6404,
|
||||
SpvOpGroupBitwiseXorKHR = 6405,
|
||||
SpvOpGroupLogicalAndKHR = 6406,
|
||||
SpvOpGroupLogicalOrKHR = 6407,
|
||||
SpvOpGroupLogicalXorKHR = 6408,
|
||||
SpvOpMax = 0x7fffffff,
|
||||
} SpvOp;
|
||||
|
||||
#ifdef SPV_ENABLE_UTILITY_CODE
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) {
|
||||
*hasResult = *hasResultType = false;
|
||||
switch (opcode) {
|
||||
@ -2197,6 +2230,7 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
|
||||
@ -2452,6 +2486,9 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
@ -2490,6 +2527,16 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
|
||||
case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||
}
|
||||
}
|
||||
#endif /* SPV_ENABLE_UTILITY_CODE */
|
||||
|
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.
|
||||
|
||||
// Enumeration tokens for SPIR-V, in various styles:
|
||||
// C, C++, C++11, JSON, Lua, Python, C#, D
|
||||
// C, C++, C++11, JSON, Lua, Python, C#, D, Beef
|
||||
//
|
||||
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
||||
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
||||
@ -36,6 +36,8 @@
|
||||
// - C# will use enum classes in the Specification class located in the "Spv" namespace,
|
||||
// e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||
// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
|
||||
// - Beef will use enum classes in the Specification class located in the "Spv" namespace,
|
||||
// e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||
//
|
||||
// Some tokens act like mask values, which can be OR'd together,
|
||||
// while others are mutually exclusive. The mask-like ones have
|
||||
@ -66,6 +68,7 @@ enum SourceLanguage {
|
||||
SourceLanguageOpenCL_CPP = 4,
|
||||
SourceLanguageHLSL = 5,
|
||||
SourceLanguageCPP_for_OpenCL = 6,
|
||||
SourceLanguageSYCL = 7,
|
||||
SourceLanguageMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@ -180,6 +183,7 @@ enum ExecutionMode {
|
||||
ExecutionModeNoGlobalOffsetINTEL = 5895,
|
||||
ExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
||||
ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
|
||||
ExecutionModeNamedBarrierCountINTEL = 6417,
|
||||
ExecutionModeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@ -542,6 +546,8 @@ enum Decoration {
|
||||
DecorationPrefetchINTEL = 5902,
|
||||
DecorationStallEnableINTEL = 5905,
|
||||
DecorationFuseLoopsInFunctionINTEL = 5907,
|
||||
DecorationAliasScopeINTEL = 5914,
|
||||
DecorationNoAliasINTEL = 5915,
|
||||
DecorationBufferLocationINTEL = 5921,
|
||||
DecorationIOPipeStorageINTEL = 5944,
|
||||
DecorationFunctionFloatingPointModeINTEL = 6080,
|
||||
@ -673,6 +679,7 @@ enum BuiltIn {
|
||||
BuiltInSMCountNV = 5375,
|
||||
BuiltInWarpIDNV = 5376,
|
||||
BuiltInSMIDNV = 5377,
|
||||
BuiltInCullMaskKHR = 6021,
|
||||
BuiltInMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@ -800,6 +807,8 @@ enum MemoryAccessShift {
|
||||
MemoryAccessMakePointerVisibleKHRShift = 4,
|
||||
MemoryAccessNonPrivatePointerShift = 5,
|
||||
MemoryAccessNonPrivatePointerKHRShift = 5,
|
||||
MemoryAccessAliasScopeINTELMaskShift = 16,
|
||||
MemoryAccessNoAliasINTELMaskShift = 17,
|
||||
MemoryAccessMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@ -814,6 +823,8 @@ enum MemoryAccessMask {
|
||||
MemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
||||
MemoryAccessNonPrivatePointerMask = 0x00000020,
|
||||
MemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
||||
MemoryAccessAliasScopeINTELMaskMask = 0x00010000,
|
||||
MemoryAccessNoAliasINTELMaskMask = 0x00020000,
|
||||
};
|
||||
|
||||
enum Scope {
|
||||
@ -1055,6 +1066,7 @@ enum Capability {
|
||||
CapabilityFPGAMemoryAccessesINTEL = 5898,
|
||||
CapabilityFPGAClusterAttributesINTEL = 5904,
|
||||
CapabilityLoopFuseINTEL = 5906,
|
||||
CapabilityMemoryAccessAliasingINTEL = 5910,
|
||||
CapabilityFPGABufferLocationINTEL = 5920,
|
||||
CapabilityArbitraryPrecisionFixedPointINTEL = 5922,
|
||||
CapabilityUSMStorageClassesINTEL = 5935,
|
||||
@ -1069,13 +1081,17 @@ enum Capability {
|
||||
CapabilityDotProductInput4x8BitPackedKHR = 6018,
|
||||
CapabilityDotProduct = 6019,
|
||||
CapabilityDotProductKHR = 6019,
|
||||
CapabilityRayCullMaskKHR = 6020,
|
||||
CapabilityBitInstructions = 6025,
|
||||
CapabilityGroupNonUniformRotateKHR = 6026,
|
||||
CapabilityAtomicFloat32AddEXT = 6033,
|
||||
CapabilityAtomicFloat64AddEXT = 6034,
|
||||
CapabilityLongConstantCompositeINTEL = 6089,
|
||||
CapabilityOptNoneINTEL = 6094,
|
||||
CapabilityAtomicFloat16AddEXT = 6095,
|
||||
CapabilityDebugInfoModuleINTEL = 6114,
|
||||
CapabilitySplitBarrierINTEL = 6141,
|
||||
CapabilityGroupUniformArithmeticKHR = 6400,
|
||||
CapabilityMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@ -1531,6 +1547,7 @@ enum Op {
|
||||
OpSubgroupAllKHR = 4428,
|
||||
OpSubgroupAnyKHR = 4429,
|
||||
OpSubgroupAllEqualKHR = 4430,
|
||||
OpGroupNonUniformRotateKHR = 4431,
|
||||
OpSubgroupReadInvocationKHR = 4432,
|
||||
OpTraceRayKHR = 4445,
|
||||
OpExecuteCallableKHR = 4446,
|
||||
@ -1797,6 +1814,9 @@ enum Op {
|
||||
OpArbitraryFloatPowRINTEL = 5881,
|
||||
OpArbitraryFloatPowNINTEL = 5882,
|
||||
OpLoopControlINTEL = 5887,
|
||||
OpAliasDomainDeclINTEL = 5911,
|
||||
OpAliasScopeDeclINTEL = 5912,
|
||||
OpAliasScopeListDeclINTEL = 5913,
|
||||
OpFixedSqrtINTEL = 5923,
|
||||
OpFixedRecipINTEL = 5924,
|
||||
OpFixedRsqrtINTEL = 5925,
|
||||
@ -1835,10 +1855,23 @@ enum Op {
|
||||
OpTypeStructContinuedINTEL = 6090,
|
||||
OpConstantCompositeContinuedINTEL = 6091,
|
||||
OpSpecConstantCompositeContinuedINTEL = 6092,
|
||||
OpControlBarrierArriveINTEL = 6142,
|
||||
OpControlBarrierWaitINTEL = 6143,
|
||||
OpGroupIMulKHR = 6401,
|
||||
OpGroupFMulKHR = 6402,
|
||||
OpGroupBitwiseAndKHR = 6403,
|
||||
OpGroupBitwiseOrKHR = 6404,
|
||||
OpGroupBitwiseXorKHR = 6405,
|
||||
OpGroupLogicalAndKHR = 6406,
|
||||
OpGroupLogicalOrKHR = 6407,
|
||||
OpGroupLogicalXorKHR = 6408,
|
||||
OpMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
#ifdef SPV_ENABLE_UTILITY_CODE
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
*hasResult = *hasResultType = false;
|
||||
switch (opcode) {
|
||||
@ -2193,6 +2226,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
|
||||
@ -2448,6 +2482,9 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break;
|
||||
case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
@ -2486,6 +2523,16 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||
case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break;
|
||||
case OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
|
||||
}
|
||||
}
|
||||
#endif /* SPV_ENABLE_UTILITY_CODE */
|
||||
|
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 false_path_ignore = false;
|
||||
if (ignore_block_id && dom.terminator == SPIRBlock::Select)
|
||||
|
||||
bool merges_to_nothing = dom.merge == SPIRBlock::MergeNone ||
|
||||
(dom.merge == SPIRBlock::MergeSelection && dom.next_block &&
|
||||
compiler.get<SPIRBlock>(dom.next_block).terminator == SPIRBlock::Unreachable) ||
|
||||
(dom.merge == SPIRBlock::MergeLoop && dom.merge_block &&
|
||||
compiler.get<SPIRBlock>(dom.merge_block).terminator == SPIRBlock::Unreachable);
|
||||
|
||||
if (dom.self == from || merges_to_nothing)
|
||||
{
|
||||
auto &true_block = compiler.get<SPIRBlock>(dom.true_block);
|
||||
auto &false_block = compiler.get<SPIRBlock>(dom.false_block);
|
||||
auto &ignore_block = compiler.get<SPIRBlock>(ignore_block_id);
|
||||
true_path_ignore = compiler.execution_is_branchless(true_block, ignore_block);
|
||||
false_path_ignore = compiler.execution_is_branchless(false_block, ignore_block);
|
||||
// We can only ignore inner branchy paths if there is no merge,
|
||||
// i.e. no code is generated afterwards. E.g. this allows us to elide continue:
|
||||
// for (;;) { if (cond) { continue; } else { break; } }.
|
||||
// Codegen here in SPIR-V will be something like either no merge if one path directly breaks, or
|
||||
// we merge to Unreachable.
|
||||
if (ignore_block_id && dom.terminator == SPIRBlock::Select)
|
||||
{
|
||||
auto &true_block = compiler.get<SPIRBlock>(dom.true_block);
|
||||
auto &false_block = compiler.get<SPIRBlock>(dom.false_block);
|
||||
auto &ignore_block = compiler.get<SPIRBlock>(ignore_block_id);
|
||||
true_path_ignore = compiler.execution_is_branchless(true_block, ignore_block);
|
||||
false_path_ignore = compiler.execution_is_branchless(false_block, ignore_block);
|
||||
}
|
||||
}
|
||||
|
||||
// Cases where we allow traversal. This serves as a proxy for post-dominance in a loop body.
|
||||
// TODO: Might want to do full post-dominance analysis, but it's a lot of churn for something like this ...
|
||||
// - We're the merge block of a selection construct. Jump to header.
|
||||
// - We're the merge block of a loop. Jump to header.
|
||||
// - Direct branch. Trivial.
|
||||
// - Allow cases inside a branch if the header cannot merge execution before loop exit.
|
||||
if ((dom.merge == SPIRBlock::MergeSelection && dom.next_block == to) ||
|
||||
(dom.merge == SPIRBlock::MergeLoop && dom.merge_block == to) ||
|
||||
(dom.terminator == SPIRBlock::Direct && dom.next_block == to) ||
|
||||
|
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.
|
||||
uint32_t result_type, result_id;
|
||||
if (compiler.instruction_to_result_type(result_type, result_id, op, args, length))
|
||||
{
|
||||
// For some opcodes, we will need to override the result id.
|
||||
// If we need to hoist the temporary, the temporary type is the input, not the result.
|
||||
// FIXME: This will likely break with OpCopyObject + hoisting, but we'll have to
|
||||
// solve it if we ever get there ...
|
||||
if (op == OpConvertUToAccelerationStructureKHR)
|
||||
{
|
||||
auto itr = result_id_to_type.find(args[2]);
|
||||
if (itr != result_id_to_type.end())
|
||||
result_type = itr->second;
|
||||
}
|
||||
|
||||
result_id_to_type[result_id] = result_type;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
|
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)
|
||||
{
|
||||
if (options.es)
|
||||
SPIRV_CROSS_THROW("64-bit integers not supported in ES profile.");
|
||||
if (!options.es)
|
||||
require_extension_internal("GL_ARB_gpu_shader_int64");
|
||||
if (options.es && options.version < 310) // GL_NV_gpu_shader5 fallback requires 310.
|
||||
SPIRV_CROSS_THROW("64-bit integers not supported in ES profile before version 310.");
|
||||
require_extension_internal("GL_ARB_gpu_shader_int64");
|
||||
}
|
||||
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.");
|
||||
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()
|
||||
@ -821,7 +825,20 @@ void CompilerGLSL::emit_header()
|
||||
|
||||
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.
|
||||
// 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("#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")
|
||||
{
|
||||
if (options.vulkan_semantics)
|
||||
statement("#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require");
|
||||
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("#elif defined(GL_NV_gpu_shader5)");
|
||||
statement("#extension GL_NV_gpu_shader5 : require");
|
||||
@ -1206,14 +1240,23 @@ string CompilerGLSL::to_interpolation_qualifiers(const Bitset &flags)
|
||||
res += "__explicitInterpAMD ";
|
||||
}
|
||||
|
||||
if (flags.get(DecorationPerVertexNV))
|
||||
if (flags.get(DecorationPerVertexKHR))
|
||||
{
|
||||
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)
|
||||
SPIRV_CROSS_THROW("pervertexNV requires GLSL 450.");
|
||||
require_extension_internal("GL_NV_fragment_shader_barycentric");
|
||||
res += "pervertexNV ";
|
||||
SPIRV_CROSS_THROW("pervertexEXT requires GLSL 450.");
|
||||
|
||||
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;
|
||||
@ -5171,8 +5214,8 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c, bool inside_bloc
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// sprintf warning.
|
||||
// We cannot rely on snprintf existing because, ..., MSVC.
|
||||
// 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
|
||||
@ -5232,7 +5275,11 @@ string CompilerGLSL::convert_float_to_string(const SPIRConstant &c, uint32_t col
|
||||
in_type.width = 32;
|
||||
|
||||
char print_buffer[32];
|
||||
#ifdef _WIN32
|
||||
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";
|
||||
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);
|
||||
|
||||
if (options.es)
|
||||
SPIRV_CROSS_THROW("64-bit integers/float not supported in ES profile.");
|
||||
if (options.es && options.version < 310) // GL_NV_gpu_shader5 fallback requires 310.
|
||||
SPIRV_CROSS_THROW("64-bit integers not supported in ES profile before version 310.");
|
||||
require_extension_internal("GL_ARB_gpu_shader_int64");
|
||||
|
||||
char print_buffer[64];
|
||||
#ifdef _WIN32
|
||||
sprintf(print_buffer, "0x%llx%s", static_cast<unsigned long long>(u64_value),
|
||||
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";
|
||||
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,
|
||||
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);
|
||||
emit_op(result_type, result_id,
|
||||
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)
|
||||
{
|
||||
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;
|
||||
case spv::Dim2D:
|
||||
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 += ")";
|
||||
|
||||
// texture(samplerXShadow) returns float. shadowX() returns vec4. Swizzle here.
|
||||
if (is_legacy() && is_depth_image(imgtype, img))
|
||||
// texture(samplerXShadow) returns float. shadowX() returns vec4, but only in desktop GLSL. Swizzle here.
|
||||
if (is_legacy() && !options.es && is_depth_image(imgtype, img))
|
||||
expr += ".r";
|
||||
|
||||
// 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.
|
||||
auto type = expression_type(args.coord);
|
||||
type.vecsize = args.coord_components + 1;
|
||||
if (imgtype.image.dim == Dim1D && options.es)
|
||||
type.vecsize++;
|
||||
farg_str += ", ";
|
||||
farg_str += type_to_glsl_constructor(type);
|
||||
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 += to_expression(args.dref);
|
||||
farg_str += ")";
|
||||
@ -7311,6 +7396,33 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool
|
||||
}
|
||||
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 += coord_expr;
|
||||
}
|
||||
@ -8698,24 +8810,42 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
|
||||
case BuiltInIncomingRayFlagsKHR:
|
||||
return ray_tracing_is_khr ? "gl_IncomingRayFlagsEXT" : "gl_IncomingRayFlagsNV";
|
||||
|
||||
case BuiltInBaryCoordNV:
|
||||
case BuiltInBaryCoordKHR:
|
||||
{
|
||||
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)
|
||||
SPIRV_CROSS_THROW("gl_BaryCoordNV requires GLSL 450.");
|
||||
require_extension_internal("GL_NV_fragment_shader_barycentric");
|
||||
return "gl_BaryCoordNV";
|
||||
SPIRV_CROSS_THROW("gl_BaryCoordEXT requires GLSL 450.");
|
||||
|
||||
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:
|
||||
{
|
||||
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)
|
||||
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspNV requires GLSL 450.");
|
||||
require_extension_internal("GL_NV_fragment_shader_barycentric");
|
||||
return "gl_BaryCoordNoPerspNV";
|
||||
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspEXT requires GLSL 450.");
|
||||
|
||||
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:
|
||||
@ -8860,6 +8990,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
if (!is_literal)
|
||||
mod_flags &= ~ACCESS_CHAIN_INDEX_IS_LITERAL_BIT;
|
||||
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++)
|
||||
@ -9192,6 +9323,10 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
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 &)
|
||||
{
|
||||
}
|
||||
@ -12132,6 +12267,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
}
|
||||
|
||||
case OpAtomicIAdd:
|
||||
case OpAtomicFAddEXT:
|
||||
{
|
||||
const char *op = check_atomic_image(ops[2]) ? "imageAtomicAdd" : "atomicAdd";
|
||||
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;
|
||||
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.
|
||||
if (sparse)
|
||||
{
|
||||
@ -12596,6 +12736,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
target_coord_type.basetype = SPIRType::Int;
|
||||
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)
|
||||
{
|
||||
uint32_t operands = ops[3];
|
||||
@ -13249,9 +13393,30 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
#undef GLSL_RAY_QUERY_GET_OP2
|
||||
|
||||
case OpConvertUToAccelerationStructureKHR:
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
case OpConvertUToPtr:
|
||||
{
|
||||
@ -13956,7 +14121,8 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
switch (type.image.dim)
|
||||
{
|
||||
case Dim1D:
|
||||
res += "1D";
|
||||
// ES doesn't support 1D. Fake it with 2D.
|
||||
res += options.es ? "2D" : "1D";
|
||||
break;
|
||||
case Dim2D:
|
||||
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
|
||||
// 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.
|
||||
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 (is_legacy_es())
|
||||
if (block_like_switch || is_legacy_es())
|
||||
{
|
||||
uint32_t counter = statement_count;
|
||||
statement("for (int spvDummy", counter, " = 0; spvDummy", counter,
|
||||
" < 1; spvDummy", counter, "++)");
|
||||
// ESSL 1.0 is not guaranteed to support do/while.
|
||||
if (is_legacy_es())
|
||||
{
|
||||
uint32_t counter = statement_count;
|
||||
statement("for (int spvDummy", counter, " = 0; spvDummy", counter, " < 1; spvDummy", counter,
|
||||
"++)");
|
||||
}
|
||||
else
|
||||
statement("do");
|
||||
}
|
||||
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++)
|
||||
{
|
||||
@ -15616,7 +15788,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
||||
if (literals.empty())
|
||||
{
|
||||
// Default case.
|
||||
if (!degenerate_switch)
|
||||
if (!block_like_switch)
|
||||
{
|
||||
if (is_legacy_es())
|
||||
statement("else");
|
||||
@ -15654,10 +15826,10 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
||||
else
|
||||
current_emitting_switch_fallthrough = false;
|
||||
|
||||
if (!degenerate_switch)
|
||||
if (!block_like_switch)
|
||||
begin_scope();
|
||||
branch(block.self, target_block);
|
||||
if (!degenerate_switch)
|
||||
if (!block_like_switch)
|
||||
end_scope();
|
||||
|
||||
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.
|
||||
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();
|
||||
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)
|
||||
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();
|
||||
}
|
||||
|
||||
if (degenerate_switch && !is_legacy_es())
|
||||
end_scope_decl("while(false)");
|
||||
if (!collapsed_switch)
|
||||
{
|
||||
if (block_like_switch && !is_legacy_es())
|
||||
end_scope_decl("while(false)");
|
||||
else
|
||||
end_scope();
|
||||
}
|
||||
else
|
||||
end_scope();
|
||||
flush_phi(block.self, block.next_block);
|
||||
|
||||
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);
|
||||
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,
|
||||
spv::StorageClass storage, bool &is_packed);
|
||||
|
||||
@ -877,6 +878,7 @@ protected:
|
||||
bool requires_transpose_3x3 = false;
|
||||
bool requires_transpose_4x4 = false;
|
||||
bool ray_tracing_is_khr = false;
|
||||
bool barycentric_is_nv = false;
|
||||
void ray_tracing_khr_fixup_locations();
|
||||
|
||||
bool args_will_forward(uint32_t id, const uint32_t *args, uint32_t num_args, bool pure);
|
||||
|
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:
|
||||
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";
|
||||
semantic = "SV_RenderTargetIndex";
|
||||
semantic = "SV_RenderTargetArrayIndex";
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -797,9 +797,9 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
|
||||
|
||||
case BuiltInLayer:
|
||||
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";
|
||||
semantic = "SV_RenderTargetIndex";
|
||||
semantic = "SV_RenderTargetArrayIndex";
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3598,6 +3598,18 @@ string CompilerHLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &i
|
||||
}
|
||||
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
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
// 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
|
||||
@ -1980,7 +1987,8 @@ void CompilerMSL::mark_as_packable(SPIRType &type)
|
||||
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);
|
||||
|
||||
@ -3175,6 +3183,9 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
|
||||
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
|
||||
// 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.
|
||||
@ -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 ||
|
||||
bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex ||
|
||||
bi_type == BuiltInBaryCoordNV || bi_type == BuiltInBaryCoordNoPerspNV ||
|
||||
bi_type == BuiltInBaryCoordKHR || bi_type == BuiltInBaryCoordNoPerspKHR ||
|
||||
bi_type == BuiltInFragDepth ||
|
||||
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.
|
||||
if (is_active && (bi_type == BuiltInBaryCoordNV || bi_type == BuiltInBaryCoordNoPerspNV))
|
||||
if (is_active && (bi_type == BuiltInBaryCoordKHR || bi_type == BuiltInBaryCoordNoPerspKHR))
|
||||
{
|
||||
if (has_seen_barycentric)
|
||||
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)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// 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());
|
||||
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]);
|
||||
if (mbr_type.basetype == SPIRType::Struct)
|
||||
if (mbr_type.basetype == SPIRType::Struct && !(mbr_type.pointer && mbr_type.storage == StorageClassPhysicalStorageBuffer))
|
||||
{
|
||||
auto *struct_type = &mbr_type;
|
||||
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
|
||||
// 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.
|
||||
// Can't repack structs, but can repack pointers to structs.
|
||||
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.");
|
||||
|
||||
// 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++)
|
||||
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)
|
||||
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;
|
||||
physical_type.vecsize = elems_per_stride;
|
||||
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);
|
||||
set<SPIRType>(type_id, physical_type);
|
||||
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.
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
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 BuiltInSampleMask:
|
||||
case BuiltInLayer:
|
||||
case BuiltInBaryCoordNV:
|
||||
case BuiltInBaryCoordNoPerspNV:
|
||||
case BuiltInBaryCoordKHR:
|
||||
case BuiltInBaryCoordNoPerspKHR:
|
||||
quals = builtin_qualifier(builtin);
|
||||
break;
|
||||
|
||||
@ -11089,7 +11156,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
|
||||
else
|
||||
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) ||
|
||||
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;
|
||||
|
||||
case StorageClassStorageBuffer:
|
||||
case StorageClassPhysicalStorageBuffer:
|
||||
{
|
||||
// For arguments from variable pointers, we use the write count deduction, so
|
||||
// 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
|
||||
case BuiltInSamplePosition:
|
||||
case BuiltInHelperInvocation:
|
||||
case BuiltInBaryCoordNV:
|
||||
case BuiltInBaryCoordNoPerspNV:
|
||||
case BuiltInBaryCoordKHR:
|
||||
case BuiltInBaryCoordNoPerspKHR:
|
||||
return false;
|
||||
case BuiltInViewIndex:
|
||||
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;
|
||||
|
||||
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
|
||||
// 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,
|
||||
// but we'll have to emit thread T * thread * T constant bar; for example.
|
||||
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
|
||||
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)
|
||||
{
|
||||
@ -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
|
||||
// together may introduce size variations that SPIR-V doesn't know about.
|
||||
if (same_size_cast && !integral_cast)
|
||||
{
|
||||
return "as_type<" + type_to_glsl(out_type) + ">";
|
||||
}
|
||||
else
|
||||
{
|
||||
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.
|
||||
@ -14494,8 +14582,8 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
|
||||
return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
|
||||
break;
|
||||
|
||||
case BuiltInBaryCoordNV:
|
||||
case BuiltInBaryCoordNoPerspNV:
|
||||
case BuiltInBaryCoordKHR:
|
||||
case BuiltInBaryCoordNoPerspKHR:
|
||||
if (storage == StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
|
||||
return stage_in_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
|
||||
break;
|
||||
@ -14732,16 +14820,14 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
|
||||
// Shouldn't be reached.
|
||||
SPIRV_CROSS_THROW("Subgroup ballot masks are handled specially in MSL.");
|
||||
|
||||
case BuiltInBaryCoordNV:
|
||||
// TODO: AMD barycentrics as well? Seem to have different swizzle and 2 components rather than 3.
|
||||
case BuiltInBaryCoordKHR:
|
||||
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.");
|
||||
else if (!msl_options.supports_msl_version(2, 2))
|
||||
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.2 and above on macOS.");
|
||||
return "barycentric_coord, center_perspective";
|
||||
|
||||
case BuiltInBaryCoordNoPerspNV:
|
||||
// TODO: AMD barycentrics as well? Seem to have different swizzle and 2 components rather than 3.
|
||||
case BuiltInBaryCoordNoPerspKHR:
|
||||
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.");
|
||||
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:
|
||||
return "bool";
|
||||
|
||||
case BuiltInBaryCoordNV:
|
||||
case BuiltInBaryCoordNoPerspNV:
|
||||
case BuiltInBaryCoordKHR:
|
||||
case BuiltInBaryCoordNoPerspKHR:
|
||||
// Use the type as declared, can be 1, 2 or 3 components.
|
||||
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.
|
||||
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)
|
||||
{
|
||||
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.
|
||||
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)
|
||||
{
|
||||
case SPIRType::Unknown:
|
||||
@ -16404,6 +16513,20 @@ void CompilerMSL::emit_block_hints(const SPIRBlock &)
|
||||
string CompilerMSL::additional_fixed_sample_mask_str() const
|
||||
{
|
||||
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);
|
||||
#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;
|
||||
}
|
||||
|
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,
|
||||
bool &is_packed) override;
|
||||
void fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t length);
|
||||
void check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type) override;
|
||||
|
||||
bool emit_tessellation_access_chain(const uint32_t *ops, uint32_t length);
|
||||
bool emit_tessellation_io_load(uint32_t result_type, uint32_t id, uint32_t ptr);
|
||||
bool is_out_of_bounds_tessellation_level(uint32_t id_lhs);
|
||||
|
Loading…
Reference in New Issue
Block a user