diff --git a/CMakeLists.txt b/CMakeLists.txt index cc218bb..6557c79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -267,6 +267,8 @@ set(THIRDPARTY_SOURCES ../thirdparty/ShaderCompiler/glslang/MachineIndependent/Scan.h ../thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.h ../thirdparty/ShaderCompiler/glslang/MachineIndependent/ScanContext.h + ../thirdparty/ShaderCompiler/glslang/MachineIndependent/pch.h + ../thirdparty/ShaderCompiler/glslang/MachineIndependent/SpirvIntrinsics.cpp ../thirdparty/ShaderCompiler/glslang/OSDependent/osinclude.h ../thirdparty/ShaderCompiler/glslang/GenericCodeGen/Link.cpp ../thirdparty/ShaderCompiler/glslang/GenericCodeGen/CodeGen.cpp @@ -280,9 +282,9 @@ set(THIRDPARTY_SOURCES ../thirdparty/ShaderCompiler/glslang/Include/InfoSink.h ../thirdparty/ShaderCompiler/glslang/Include/ResourceLimits.h ../thirdparty/ShaderCompiler/glslang/Include/Types.h - ../thirdparty/ShaderCompiler/glslang/Include/revision.h ../thirdparty/ShaderCompiler/glslang/Include/BaseTypes.h ../thirdparty/ShaderCompiler/glslang/Include/intermediate.h + ../thirdparty/ShaderCompiler/glslang/Include/SpirvIntrinsics.h ../thirdparty/ShaderCompiler/spirv/Logger.h ../thirdparty/ShaderCompiler/spirv/GlslangToSpv.cpp ../thirdparty/ShaderCompiler/spirv/SPVRemapper.h diff --git a/thirdparty/ShaderCompiler/glslang/Include/BaseTypes.h b/thirdparty/ShaderCompiler/glslang/Include/BaseTypes.h index 1827c49..c8203c2 100644 --- a/thirdparty/ShaderCompiler/glslang/Include/BaseTypes.h +++ b/thirdparty/ShaderCompiler/glslang/Include/BaseTypes.h @@ -2,6 +2,7 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -61,12 +62,13 @@ enum TBasicType { EbtSampler, EbtStruct, EbtBlock, - -#ifdef NV_EXTENSIONS - EbtAccStructNV, -#endif - + EbtAccStruct, EbtReference, + EbtRayQuery, +#ifndef GLSLANG_WEB + // SPIR-V type defined by spirv_type + EbtSpirvType, +#endif // HLSL types that live only temporarily. EbtString, @@ -93,15 +95,16 @@ enum TStorageQualifier { EvqUniform, // read only, shared with app EvqBuffer, // read/write, shared with app EvqShared, // compute shader's read/write 'shared' qualifier - -#ifdef NV_EXTENSIONS - EvqPayloadNV, - EvqPayloadInNV, - EvqHitAttrNV, - EvqCallableDataNV, - EvqCallableDataInNV, +#ifndef GLSLANG_WEB + EvqSpirvStorageClass, // spirv_storage_class #endif + EvqPayload, + EvqPayloadIn, + EvqHitAttr, + EvqCallableData, + EvqCallableDataIn, + // parameters EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter @@ -221,7 +224,6 @@ enum TBuiltInVariable { EbvSampleMask, EbvHelperInvocation, -#ifdef AMD_EXTENSIONS EbvBaryCoordNoPersp, EbvBaryCoordNoPerspCentroid, EbvBaryCoordNoPerspSample, @@ -229,15 +231,19 @@ enum TBuiltInVariable { EbvBaryCoordSmoothCentroid, EbvBaryCoordSmoothSample, EbvBaryCoordPullModel, -#endif EbvViewIndex, EbvDeviceIndex, + EbvShadingRateKHR, + EbvPrimitiveShadingRateKHR, + EbvFragSizeEXT, EbvFragInvocationCountEXT, -#ifdef NV_EXTENSIONS + EbvSecondaryFragDataEXT, + EbvSecondaryFragColorEXT, + EbvViewportMaskNV, EbvSecondaryPositionNV, EbvSecondaryViewportMaskNV, @@ -246,23 +252,29 @@ enum TBuiltInVariable { EbvFragFullyCoveredNV, EbvFragmentSizeNV, EbvInvocationsPerPixelNV, - // raytracing - EbvLaunchIdNV, - EbvLaunchSizeNV, - EbvInstanceCustomIndexNV, - EbvWorldRayOriginNV, - EbvWorldRayDirectionNV, - EbvObjectRayOriginNV, - EbvObjectRayDirectionNV, - EbvRayTminNV, - EbvRayTmaxNV, - EbvHitTNV, - EbvHitKindNV, - EbvObjectToWorldNV, - EbvWorldToObjectNV, - EbvIncomingRayFlagsNV, + // ray tracing + EbvLaunchId, + EbvLaunchSize, + EbvInstanceCustomIndex, + EbvGeometryIndex, + EbvWorldRayOrigin, + EbvWorldRayDirection, + EbvObjectRayOrigin, + EbvObjectRayDirection, + EbvRayTmin, + EbvRayTmax, + EbvHitT, + EbvHitKind, + EbvObjectToWorld, + EbvObjectToWorld3x4, + EbvWorldToObject, + EbvWorldToObject3x4, + EbvIncomingRayFlags, + EbvCurrentRayTimeNV, + // barycentrics EbvBaryCoordNV, EbvBaryCoordNoPerspNV, + // mesh shaders EbvTaskCountNV, EbvPrimitiveCountNV, EbvPrimitiveIndicesNV, @@ -271,7 +283,12 @@ enum TBuiltInVariable { EbvLayerPerViewNV, EbvMeshViewCountNV, EbvMeshViewIndicesNV, -#endif + + // sm builtins + EbvWarpsPerSM, + EbvSMCount, + EbvWarpID, + EbvSMID, // HLSL built-ins that live only temporarily, until they get remapped // to one of the above. @@ -291,6 +308,19 @@ enum TBuiltInVariable { EbvLast }; +// In this enum, order matters; users can assume higher precision is a bigger value +// and EpqNone is 0. +enum TPrecisionQualifier { + EpqNone = 0, + EpqLow, + EpqMedium, + EpqHigh +}; + +#ifdef GLSLANG_WEB +__inline const char* GetStorageQualifierString(TStorageQualifier q) { return ""; } +__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) { return ""; } +#else // These will show up in error messages __inline const char* GetStorageQualifierString(TStorageQualifier q) { @@ -299,6 +329,9 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q) case EvqGlobal: return "global"; break; case EvqConst: return "const"; break; case EvqConstReadOnly: return "const (read only)"; break; +#ifndef GLSLANG_WEB + case EvqSpirvStorageClass: return "spirv_storage_class"; break; +#endif case EvqVaryingIn: return "in"; break; case EvqVaryingOut: return "out"; break; case EvqUniform: return "uniform"; break; @@ -317,13 +350,11 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q) case EvqPointCoord: return "gl_PointCoord"; break; case EvqFragColor: return "fragColor"; break; case EvqFragDepth: return "gl_FragDepth"; break; -#ifdef NV_EXTENSIONS - case EvqPayloadNV: return "rayPayloadNV"; break; - case EvqPayloadInNV: return "rayPayloadInNV"; break; - case EvqHitAttrNV: return "hitAttributeNV"; break; - case EvqCallableDataNV: return "callableDataNV"; break; - case EvqCallableDataInNV: return "callableDataInNV"; break; -#endif + case EvqPayload: return "rayPayloadNV"; break; + case EvqPayloadIn: return "rayPayloadInNV"; break; + case EvqHitAttr: return "hitAttributeNV"; break; + case EvqCallableData: return "callableDataNV"; break; + case EvqCallableDataIn: return "callableDataInNV"; break; default: return "unknown qualifier"; } } @@ -338,6 +369,8 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvLocalInvocationId: return "LocalInvocationID"; case EbvGlobalInvocationId: return "GlobalInvocationID"; case EbvLocalInvocationIndex: return "LocalInvocationIndex"; + case EbvNumSubgroups: return "NumSubgroups"; + case EbvSubgroupID: return "SubgroupID"; case EbvSubGroupSize: return "SubGroupSize"; case EbvSubGroupInvocation: return "SubGroupInvocation"; case EbvSubGroupEqMask: return "SubGroupEqMask"; @@ -345,6 +378,13 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvSubGroupGtMask: return "SubGroupGtMask"; case EbvSubGroupLeMask: return "SubGroupLeMask"; case EbvSubGroupLtMask: return "SubGroupLtMask"; + case EbvSubgroupSize2: return "SubgroupSize"; + case EbvSubgroupInvocation2: return "SubgroupInvocationID"; + case EbvSubgroupEqMask2: return "SubgroupEqMask"; + case EbvSubgroupGeMask2: return "SubgroupGeMask"; + case EbvSubgroupGtMask2: return "SubgroupGtMask"; + case EbvSubgroupLeMask2: return "SubgroupLeMask"; + case EbvSubgroupLtMask2: return "SubgroupLtMask"; case EbvVertexId: return "VertexId"; case EbvInstanceId: return "InstanceId"; case EbvVertexIndex: return "VertexIndex"; @@ -396,7 +436,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvSampleMask: return "SampleMaskIn"; case EbvHelperInvocation: return "HelperInvocation"; -#ifdef AMD_EXTENSIONS case EbvBaryCoordNoPersp: return "BaryCoordNoPersp"; case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid"; case EbvBaryCoordNoPerspSample: return "BaryCoordNoPerspSample"; @@ -404,7 +443,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvBaryCoordSmoothCentroid: return "BaryCoordSmoothCentroid"; case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample"; case EbvBaryCoordPullModel: return "BaryCoordPullModel"; -#endif case EbvViewIndex: return "ViewIndex"; case EbvDeviceIndex: return "DeviceIndex"; @@ -412,7 +450,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvFragSizeEXT: return "FragSizeEXT"; case EbvFragInvocationCountEXT: return "FragInvocationCountEXT"; -#ifdef NV_EXTENSIONS + case EbvSecondaryFragDataEXT: return "SecondaryFragDataEXT"; + case EbvSecondaryFragColorEXT: return "SecondaryFragColorEXT"; + case EbvViewportMaskNV: return "ViewportMaskNV"; case EbvSecondaryPositionNV: return "SecondaryPositionNV"; case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; @@ -421,23 +461,26 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvFragFullyCoveredNV: return "FragFullyCoveredNV"; case EbvFragmentSizeNV: return "FragmentSizeNV"; case EbvInvocationsPerPixelNV: return "InvocationsPerPixelNV"; - case EbvLaunchIdNV: return "LaunchIdNV"; - case EbvLaunchSizeNV: return "LaunchSizeNV"; - case EbvInstanceCustomIndexNV: return "InstanceCustomIndexNV"; - case EbvWorldRayOriginNV: return "WorldRayOriginNV"; - case EbvWorldRayDirectionNV: return "WorldRayDirectionNV"; - case EbvObjectRayOriginNV: return "ObjectRayOriginNV"; - case EbvObjectRayDirectionNV: return "ObjectRayDirectionNV"; - case EbvRayTminNV: return "ObjectRayTminNV"; - case EbvRayTmaxNV: return "ObjectRayTmaxNV"; - case EbvHitTNV: return "HitTNV"; - case EbvHitKindNV: return "HitKindNV"; - case EbvIncomingRayFlagsNV: return "IncomingRayFlagsNV"; - case EbvObjectToWorldNV: return "ObjectToWorldNV"; - case EbvWorldToObjectNV: return "WorldToObjectNV"; + case EbvLaunchId: return "LaunchIdNV"; + case EbvLaunchSize: return "LaunchSizeNV"; + case EbvInstanceCustomIndex: return "InstanceCustomIndexNV"; + case EbvGeometryIndex: return "GeometryIndexEXT"; + case EbvWorldRayOrigin: return "WorldRayOriginNV"; + case EbvWorldRayDirection: return "WorldRayDirectionNV"; + case EbvObjectRayOrigin: return "ObjectRayOriginNV"; + case EbvObjectRayDirection: return "ObjectRayDirectionNV"; + case EbvRayTmin: return "ObjectRayTminNV"; + case EbvRayTmax: return "ObjectRayTmaxNV"; + case EbvHitT: return "HitTNV"; + case EbvHitKind: return "HitKindNV"; + case EbvIncomingRayFlags: return "IncomingRayFlagsNV"; + case EbvObjectToWorld: return "ObjectToWorldNV"; + case EbvWorldToObject: return "WorldToObjectNV"; + case EbvCurrentRayTimeNV: return "CurrentRayTimeNV"; case EbvBaryCoordNV: return "BaryCoordNV"; case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; + case EbvTaskCountNV: return "TaskCountNV"; case EbvPrimitiveCountNV: return "PrimitiveCountNV"; case EbvPrimitiveIndicesNV: return "PrimitiveIndicesNV"; @@ -446,20 +489,19 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvLayerPerViewNV: return "LayerPerViewNV"; case EbvMeshViewCountNV: return "MeshViewCountNV"; case EbvMeshViewIndicesNV: return "MeshViewIndicesNV"; -#endif + + case EbvWarpsPerSM: return "WarpsPerSMNV"; + case EbvSMCount: return "SMCountNV"; + case EbvWarpID: return "WarpIDNV"; + case EbvSMID: return "SMIDNV"; + + case EbvShadingRateKHR: return "ShadingRateKHR"; + case EbvPrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR"; + default: return "unknown built-in variable"; } } -// In this enum, order matters; users can assume higher precision is a bigger value -// and EpqNone is 0. -enum TPrecisionQualifier { - EpqNone = 0, - EpqLow, - EpqMedium, - EpqHigh -}; - __inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) { switch (p) { @@ -470,6 +512,7 @@ __inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) default: return "unknown precision qualifier"; } } +#endif __inline bool isTypeSignedInt(TBasicType type) { @@ -514,7 +557,8 @@ __inline bool isTypeFloat(TBasicType type) } } -__inline int getTypeRank(TBasicType type) { +__inline int getTypeRank(TBasicType type) +{ int res = -1; switch(type) { case EbtInt8: diff --git a/thirdparty/ShaderCompiler/glslang/Include/Common.h b/thirdparty/ShaderCompiler/glslang/Include/Common.h index 98e5a1a..1e47239 100644 --- a/thirdparty/ShaderCompiler/glslang/Include/Common.h +++ b/thirdparty/ShaderCompiler/glslang/Include/Common.h @@ -37,8 +37,19 @@ #ifndef _COMMON_INCLUDED_ #define _COMMON_INCLUDED_ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#if defined(__ANDROID__) || _MSC_VER < 1700 +#if defined(__ANDROID__) || (defined(_MSC_VER) && _MSC_VER < 1700) #include namespace std { template @@ -93,17 +104,6 @@ std::string to_string(const T& val) { #pragma warning(disable : 4201) // nameless union #endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "PoolAlloc.h" // @@ -194,6 +194,10 @@ template , class PRED = std::equal_t class TUnorderedMap : public std::unordered_map > > { }; +template > +class TSet : public std::set > { +}; + // // Persistent string memory. Should only be used for strings that survive // across compiles/links. @@ -286,6 +290,18 @@ template bool IsMultipleOfPow2(T number, int powerOf2) return ! (number & (powerOf2 - 1)); } +// Returns log2 of an integer power of 2. +// T should be integral. +template int IntLog2(T n) +{ + assert(IsPow2(n)); + int result = 0; + while ((T(1) << result) != n) { + result++; + } + return result; +} + } // end namespace glslang #endif // _COMMON_INCLUDED_ diff --git a/thirdparty/ShaderCompiler/glslang/Include/ConstantUnion.h b/thirdparty/ShaderCompiler/glslang/Include/ConstantUnion.h index 3e93340..c4ffb85 100644 --- a/thirdparty/ShaderCompiler/glslang/Include/ConstantUnion.h +++ b/thirdparty/ShaderCompiler/glslang/Include/ConstantUnion.h @@ -213,6 +213,28 @@ public: return false; switch (type) { + case EbtInt: + if (constant.iConst == iConst) + return true; + + break; + case EbtUint: + if (constant.uConst == uConst) + return true; + + break; + case EbtBool: + if (constant.bConst == bConst) + return true; + + break; + case EbtDouble: + if (constant.dConst == dConst) + return true; + + break; + +#ifndef GLSLANG_WEB case EbtInt16: if (constant.i16Const == i16Const) return true; @@ -232,16 +254,6 @@ public: if (constant.u8Const == u8Const) return true; - break; - case EbtInt: - if (constant.iConst == iConst) - return true; - - break; - case EbtUint: - if (constant.uConst == uConst) - return true; - break; case EbtInt64: if (constant.i64Const == i64Const) @@ -253,16 +265,7 @@ public: return true; break; - case EbtDouble: - if (constant.dConst == dConst) - return true; - - break; - case EbtBool: - if (constant.bConst == bConst) - return true; - - break; +#endif default: assert(false && "Default missing"); } @@ -329,6 +332,22 @@ public: { assert(type == constant.type); switch (type) { + case EbtInt: + if (iConst > constant.iConst) + return true; + + return false; + case EbtUint: + if (uConst > constant.uConst) + return true; + + return false; + case EbtDouble: + if (dConst > constant.dConst) + return true; + + return false; +#ifndef GLSLANG_WEB case EbtInt8: if (i8Const > constant.i8Const) return true; @@ -348,16 +367,6 @@ public: if (u16Const > constant.u16Const) return true; - return false; - case EbtInt: - if (iConst > constant.iConst) - return true; - - return false; - case EbtUint: - if (uConst > constant.uConst) - return true; - return false; case EbtInt64: if (i64Const > constant.i64Const) @@ -369,11 +378,7 @@ public: return true; return false; - case EbtDouble: - if (dConst > constant.dConst) - return true; - - return false; +#endif default: assert(false && "Default missing"); return false; @@ -384,6 +389,7 @@ public: { assert(type == constant.type); switch (type) { +#ifndef GLSLANG_WEB case EbtInt8: if (i8Const < constant.i8Const) return true; @@ -394,7 +400,7 @@ public: return true; return false; - case EbtInt16: + case EbtInt16: if (i16Const < constant.i16Const) return true; @@ -402,17 +408,6 @@ public: case EbtUint16: if (u16Const < constant.u16Const) return true; - - return false; - case EbtInt: - if (iConst < constant.iConst) - return true; - - return false; - case EbtUint: - if (uConst < constant.uConst) - return true; - return false; case EbtInt64: if (i64Const < constant.i64Const) @@ -424,10 +419,21 @@ public: return true; return false; +#endif case EbtDouble: if (dConst < constant.dConst) return true; + return false; + case EbtInt: + if (iConst < constant.iConst) + return true; + + return false; + case EbtUint: + if (uConst < constant.uConst) + return true; + return false; default: assert(false && "Default missing"); @@ -440,15 +446,17 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst + constant.uConst); break; + case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setI8Const(i8Const + constant.i8Const); break; case EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); break; - case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break; case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break; case EbtUint16: returnValue.setU16Const(u16Const + constant.u16Const); break; - case EbtUint: returnValue.setUConst(uConst + constant.uConst); break; case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break; - case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break; +#endif default: assert(false && "Default missing"); } @@ -460,15 +468,17 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst - constant.uConst); break; + case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setI8Const(i8Const - constant.i8Const); break; case EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); break; - case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break; case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break; case EbtUint16: returnValue.setU16Const(u16Const - constant.u16Const); break; - case EbtUint: returnValue.setUConst(uConst - constant.uConst); break; case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break; - case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break; +#endif default: assert(false && "Default missing"); } @@ -480,15 +490,17 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst * constant.uConst); break; + case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setI8Const(i8Const * constant.i8Const); break; case EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); break; - case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break; case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break; case EbtUint16: returnValue.setU16Const(u16Const * constant.u16Const); break; - case EbtUint: returnValue.setUConst(uConst * constant.uConst); break; case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break; - case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; +#endif default: assert(false && "Default missing"); } @@ -500,14 +512,16 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst % constant.uConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break; case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break; - case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break; case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break; case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break; - case EbtUint: returnValue.setUConst(uConst % constant.uConst); break; case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break; +#endif default: assert(false && "Default missing"); } @@ -518,6 +532,7 @@ public: { TConstUnion returnValue; switch (type) { +#ifndef GLSLANG_WEB case EbtInt8: switch (constant.type) { case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break; @@ -570,32 +585,38 @@ public: default: assert(false && "Default missing"); } break; +#endif case EbtInt: switch (constant.type) { + case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; + case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setIConst(iConst >> constant.i8Const); break; case EbtUint8: returnValue.setIConst(iConst >> constant.u8Const); break; case EbtInt16: returnValue.setIConst(iConst >> constant.i16Const); break; case EbtUint16: returnValue.setIConst(iConst >> constant.u16Const); break; - case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; - case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break; case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break; case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break; +#endif default: assert(false && "Default missing"); } break; case EbtUint: switch (constant.type) { + case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setUConst(uConst >> constant.i8Const); break; case EbtUint8: returnValue.setUConst(uConst >> constant.u8Const); break; case EbtInt16: returnValue.setUConst(uConst >> constant.i16Const); break; case EbtUint16: returnValue.setUConst(uConst >> constant.u16Const); break; - case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break; - case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break; case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break; case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break; +#endif default: assert(false && "Default missing"); } break; +#ifndef GLSLANG_WEB case EbtInt64: switch (constant.type) { case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break; @@ -622,6 +643,7 @@ public: default: assert(false && "Default missing"); } break; +#endif default: assert(false && "Default missing"); } @@ -632,6 +654,7 @@ public: { TConstUnion returnValue; switch (type) { +#ifndef GLSLANG_WEB case EbtInt8: switch (constant.type) { case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break; @@ -684,32 +707,6 @@ public: default: assert(false && "Default missing"); } break; - case EbtInt: - switch (constant.type) { - case EbtInt8: returnValue.setIConst(iConst << constant.i8Const); break; - case EbtUint8: returnValue.setIConst(iConst << constant.u8Const); break; - case EbtInt16: returnValue.setIConst(iConst << constant.i16Const); break; - case EbtUint16: returnValue.setIConst(iConst << constant.u16Const); break; - case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; - case EbtUint: returnValue.setIConst(iConst << constant.uConst); break; - case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break; - case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break; - default: assert(false && "Default missing"); - } - break; - case EbtUint: - switch (constant.type) { - case EbtInt8: returnValue.setUConst(uConst << constant.i8Const); break; - case EbtUint8: returnValue.setUConst(uConst << constant.u8Const); break; - case EbtInt16: returnValue.setUConst(uConst << constant.i16Const); break; - case EbtUint16: returnValue.setUConst(uConst << constant.u16Const); break; - case EbtInt: returnValue.setUConst(uConst << constant.iConst); break; - case EbtUint: returnValue.setUConst(uConst << constant.uConst); break; - case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break; - case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break; - default: assert(false && "Default missing"); - } - break; case EbtInt64: switch (constant.type) { case EbtInt8: returnValue.setI64Const(i64Const << constant.i8Const); break; @@ -736,6 +733,37 @@ public: default: assert(false && "Default missing"); } break; +#endif + case EbtInt: + switch (constant.type) { + case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; + case EbtUint: returnValue.setIConst(iConst << constant.uConst); break; +#ifndef GLSLANG_WEB + case EbtInt8: returnValue.setIConst(iConst << constant.i8Const); break; + case EbtUint8: returnValue.setIConst(iConst << constant.u8Const); break; + case EbtInt16: returnValue.setIConst(iConst << constant.i16Const); break; + case EbtUint16: returnValue.setIConst(iConst << constant.u16Const); break; + case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break; + case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break; +#endif + default: assert(false && "Default missing"); + } + break; + case EbtUint: + switch (constant.type) { + case EbtInt: returnValue.setUConst(uConst << constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst << constant.uConst); break; +#ifndef GLSLANG_WEB + case EbtInt8: returnValue.setUConst(uConst << constant.i8Const); break; + case EbtUint8: returnValue.setUConst(uConst << constant.u8Const); break; + case EbtInt16: returnValue.setUConst(uConst << constant.i16Const); break; + case EbtUint16: returnValue.setUConst(uConst << constant.u16Const); break; + case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break; + case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break; +#endif + default: assert(false && "Default missing"); + } + break; default: assert(false && "Default missing"); } @@ -747,14 +775,16 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst & constant.uConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setI8Const(i8Const & constant.i8Const); break; case EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break; case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break; case EbtUint16: returnValue.setU16Const(u16Const & constant.u16Const); break; - case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; - case EbtUint: returnValue.setUConst(uConst & constant.uConst); break; case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break; case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break; +#endif default: assert(false && "Default missing"); } @@ -766,14 +796,16 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst | constant.uConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setI8Const(i8Const | constant.i8Const); break; case EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break; case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break; case EbtUint16: returnValue.setU16Const(u16Const | constant.u16Const); break; - case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; - case EbtUint: returnValue.setUConst(uConst | constant.uConst); break; case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break; case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break; +#endif default: assert(false && "Default missing"); } @@ -785,14 +817,16 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setI8Const(i8Const ^ constant.i8Const); break; case EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break; case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break; case EbtUint16: returnValue.setU16Const(u16Const ^ constant.u16Const); break; - case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; - case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break; case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break; case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break; +#endif default: assert(false && "Default missing"); } @@ -803,14 +837,16 @@ public: { TConstUnion returnValue; switch (type) { + case EbtInt: returnValue.setIConst(~iConst); break; + case EbtUint: returnValue.setUConst(~uConst); break; +#ifndef GLSLANG_WEB case EbtInt8: returnValue.setI8Const(~i8Const); break; case EbtUint8: returnValue.setU8Const(~u8Const); break; case EbtInt16: returnValue.setI16Const(~i16Const); break; case EbtUint16: returnValue.setU16Const(~u16Const); break; - case EbtInt: returnValue.setIConst(~iConst); break; - case EbtUint: returnValue.setUConst(~uConst); break; case EbtInt64: returnValue.setI64Const(~i64Const); break; case EbtUint64: returnValue.setU64Const(~u64Const); break; +#endif default: assert(false && "Default missing"); } @@ -885,7 +921,7 @@ public: else unionArray = new TConstUnionVector(size); } - TConstUnionArray(const TConstUnionArray& a) : unionArray(a.unionArray) { } + TConstUnionArray(const TConstUnionArray& a) = default; TConstUnionArray(const TConstUnionArray& a, int start, int size) { unionArray = new TConstUnionVector(size); diff --git a/thirdparty/ShaderCompiler/glslang/Include/PoolAlloc.h b/thirdparty/ShaderCompiler/glslang/Include/PoolAlloc.h index 0e237a6..b8eccb8 100644 --- a/thirdparty/ShaderCompiler/glslang/Include/PoolAlloc.h +++ b/thirdparty/ShaderCompiler/glslang/Include/PoolAlloc.h @@ -304,7 +304,6 @@ public: size_type max_size() const { return static_cast(-1) / sizeof(T); } size_type max_size(int size) const { return static_cast(-1) / size; } - void setAllocator(TPoolAllocator* a) { allocator = *a; } TPoolAllocator& getAllocator() const { return allocator; } protected: diff --git a/thirdparty/ShaderCompiler/glslang/Include/ResourceLimits.h b/thirdparty/ShaderCompiler/glslang/Include/ResourceLimits.h index 106b21d..b670cf1 100644 --- a/thirdparty/ShaderCompiler/glslang/Include/ResourceLimits.h +++ b/thirdparty/ShaderCompiler/glslang/Include/ResourceLimits.h @@ -142,6 +142,7 @@ struct TBuiltInResource { int maxTaskWorkGroupSizeY_NV; int maxTaskWorkGroupSizeZ_NV; int maxMeshViewCountNV; + int maxDualSourceDrawBuffersEXT; TLimits limits; }; diff --git a/thirdparty/ShaderCompiler/glslang/Include/SpirvIntrinsics.h b/thirdparty/ShaderCompiler/glslang/Include/SpirvIntrinsics.h new file mode 100644 index 0000000..e7a999d --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/Include/SpirvIntrinsics.h @@ -0,0 +1,136 @@ +// +// Copyright(C) 2021 Advanced Micro Devices, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#pragma once + +#ifndef GLSLANG_WEB + +// +// GL_EXT_spirv_intrinsics +// +#include "Common.h" + +namespace glslang { + +class TIntermTyped; +class TIntermConstantUnion; +class TType; + +// SPIR-V requirements +struct TSpirvRequirement { + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + // capability = [..] + TSet extensions; + // extension = [..] + TSet capabilities; +}; + +// SPIR-V execution modes +struct TSpirvExecutionMode { + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + // spirv_execution_mode + TMap> modes; + // spirv_execution_mode_id + TMap > modeIds; +}; + +// SPIR-V decorations +struct TSpirvDecorate { + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + // spirv_decorate + TMap > decorates; + // spirv_decorate_id + TMap > decorateIds; + // spirv_decorate_string + TMap > decorateStrings; +}; + +// SPIR-V instruction +struct TSpirvInstruction { + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + TSpirvInstruction() { set = ""; id = -1; } + + bool operator==(const TSpirvInstruction& rhs) const { return set == rhs.set && id == rhs.id; } + bool operator!=(const TSpirvInstruction& rhs) const { return !operator==(rhs); } + + // spirv_instruction + TString set; + int id; +}; + +// SPIR-V type parameter +struct TSpirvTypeParameter { + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + TSpirvTypeParameter(const TIntermConstantUnion* arg) { isConstant = true; constant = arg; } + TSpirvTypeParameter(const TType* arg) { isConstant = false; type = arg; } + + bool operator==(const TSpirvTypeParameter& rhs) const + { + return isConstant == rhs.isConstant && ((isConstant && constant == rhs.constant) || (!isConstant && type == rhs.type)); + } + bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); } + + bool isConstant; + union { + const TIntermConstantUnion* constant; + const TType* type; + }; +}; + +typedef TVector TSpirvTypeParameters; + +// SPIR-V type +struct TSpirvType { + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + bool operator==(const TSpirvType& rhs) const + { + return spirvInst == rhs.spirvInst && typeParams == rhs.typeParams; + } + bool operator!=(const TSpirvType& rhs) const { return !operator==(rhs); } + + // spirv_type + TSpirvInstruction spirvInst; + TSpirvTypeParameters typeParams; +}; + +} // end namespace glslang + +#endif // GLSLANG_WEB diff --git a/thirdparty/ShaderCompiler/glslang/Include/Types.h b/thirdparty/ShaderCompiler/glslang/Include/Types.h index 4663a35..a6bf191 100644 --- a/thirdparty/ShaderCompiler/glslang/Include/Types.h +++ b/thirdparty/ShaderCompiler/glslang/Include/Types.h @@ -3,6 +3,7 @@ // Copyright (C) 2012-2016 LunarG, Inc. // Copyright (C) 2015-2016 Google, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -43,11 +44,14 @@ #include "../Include/BaseTypes.h" #include "../Public/ShaderLang.h" #include "arrays.h" +#include "SpirvIntrinsics.h" #include namespace glslang { +class TIntermAggregate; + const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded const char* const AnonymousPrefix = "anon@"; // for something like a block whose members can be directly accessed @@ -80,31 +84,60 @@ struct TSampler { // misnomer now; includes images, textures without sampler, bool image : 1; // image, combined should be false bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler bool sampler : 1; // true means a pure sampler, other fields should be clear() - bool external : 1; // GL_OES_EGL_image_external - bool yuv : 1; // GL_EXT_YUV_target - unsigned int vectorSize : 3; // vector return type size. +#ifdef GLSLANG_WEB + bool is1D() const { return false; } + bool isBuffer() const { return false; } + bool isRect() const { return false; } + bool isSubpass() const { return false; } + bool isCombined() const { return true; } + bool isImage() const { return false; } + bool isImageClass() const { return false; } + bool isMultiSample() const { return false; } + bool isExternal() const { return false; } + void setExternal(bool e) { } + bool isYuv() const { return false; } +#else + unsigned int vectorSize : 3; // vector return type size. // Some languages support structures as sample results. Storing the whole structure in the // TSampler is too large, so there is an index to a separate table. static const unsigned structReturnIndexBits = 4; // number of index bits to use. static const unsigned structReturnSlots = (1< 1) localSize[i] = src.localSize[i]; } + for (int i = 0; i < 3; ++i) { + localSizeNotDefault[i] = src.localSizeNotDefault[i] || localSizeNotDefault[i]; + } for (int i = 0; i < 3; ++i) { if (src.localSizeSpecId[i] != TQualifier::layoutNotSet) localSizeSpecId[i] = src.localSizeSpecId[i]; } +#ifndef GLSLANG_WEB if (src.earlyFragmentTests) earlyFragmentTests = true; if (src.postDepthCoverage) @@ -1205,7 +1418,6 @@ struct TShaderQualifiers { blendEquation = src.blendEquation; if (src.numViews != TQualifier::layoutNotSet) numViews = src.numViews; -#ifdef NV_EXTENSIONS if (src.layoutOverrideCoverage) layoutOverrideCoverage = src.layoutOverrideCoverage; if (src.layoutDerivativeGroupQuads) @@ -1214,6 +1426,10 @@ struct TShaderQualifiers { layoutDerivativeGroupLinear = src.layoutDerivativeGroupLinear; if (src.primitives != TQualifier::layoutNotSet) primitives = src.primitives; + if (src.interlockOrdering != EioNone) + interlockOrdering = src.interlockOrdering; + if (src.layoutPrimitiveCulling) + layoutPrimitiveCulling = src.layoutPrimitiveCulling; #endif } }; @@ -1235,9 +1451,21 @@ public: int vectorSize : 4; int matrixCols : 4; int matrixRows : 4; + bool coopmat : 1; TArraySizes* arraySizes; const TType* userDef; TSourceLoc loc; + TArraySizes* typeParameters; +#ifndef GLSLANG_WEB + // SPIR-V type defined by spirv_type directive + TSpirvType* spirvType; +#endif + +#ifdef GLSLANG_WEB + bool isCoopmat() const { return false; } +#else + bool isCoopmat() const { return coopmat; } +#endif void initType(const TSourceLoc& l) { @@ -1248,6 +1476,11 @@ public: arraySizes = nullptr; userDef = nullptr; loc = l; + typeParameters = nullptr; + coopmat = false; +#ifndef GLSLANG_WEB + spirvType = nullptr; +#endif } void initQualifiers(bool global = false) @@ -1284,6 +1517,11 @@ public: return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr; } +#ifndef GLSLANG_WEB + // GL_EXT_spirv_intrinsics + void setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams = nullptr); +#endif + // "Image" is a superset of "Subpass" bool isImage() const { return basicType == EbtSampler && sampler.isImage(); } bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); } @@ -1299,8 +1537,11 @@ public: // for "empty" type (no args) or simple scalar/vector/matrix explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0, bool isVector = false) : - basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), - arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) + basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr) +#ifndef GLSLANG_WEB + , spirvType(nullptr) +#endif { sampler.clear(); qualifier.clear(); @@ -1310,8 +1551,11 @@ public: // for explicit precision qualifier TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0, bool isVector = false) : - basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), - arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) + basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr) +#ifndef GLSLANG_WEB + , spirvType(nullptr) +#endif { sampler.clear(); qualifier.clear(); @@ -1323,8 +1567,11 @@ public: // for turning a TPublicType into a TType, using a shallow copy explicit TType(const TPublicType& p) : basicType(p.basicType), - vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), - arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr) + vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmat(p.coopmat), + arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters) +#ifndef GLSLANG_WEB + , spirvType(p.spirvType) +#endif { if (basicType == EbtSampler) sampler = p.sampler; @@ -1340,12 +1587,28 @@ public: } typeName = NewPoolTString(p.userDef->getTypeName().c_str()); } + if (p.isCoopmat() && p.typeParameters && p.typeParameters->getNumDims() > 0) { + int numBits = p.typeParameters->getDimSize(0); + if (p.basicType == EbtFloat && numBits == 16) { + basicType = EbtFloat16; + qualifier.precision = EpqNone; + } else if (p.basicType == EbtUint && numBits == 8) { + basicType = EbtUint8; + qualifier.precision = EpqNone; + } else if (p.basicType == EbtInt && numBits == 8) { + basicType = EbtInt8; + qualifier.precision = EpqNone; + } + } } // for construction of sampler types TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) : - basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), + basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr), - sampler(sampler) + sampler(sampler), typeParameters(nullptr) +#ifndef GLSLANG_WEB + , spirvType(nullptr) +#endif { qualifier.clear(); qualifier.storage = q; @@ -1386,13 +1649,19 @@ public: // dereference from vector to scalar vectorSize = 1; vector1 = false; + } else if (isCoopMat()) { + coopmat = false; + typeParameters = nullptr; } } } // for making structures, ... TType(TTypeList* userDef, const TString& n) : - basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), - arraySizes(nullptr), structure(userDef), fieldName(nullptr) + basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), + arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr) +#ifndef GLSLANG_WEB + , spirvType(nullptr) +#endif { sampler.clear(); qualifier.clear(); @@ -1400,8 +1669,11 @@ public: } // For interface blocks TType(TTypeList* userDef, const TString& n, const TQualifier& q) : - basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), - qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr) + basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), + qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr) +#ifndef GLSLANG_WEB + , spirvType(nullptr) +#endif { sampler.clear(); typeName = NewPoolTString(n.c_str()); @@ -1410,6 +1682,9 @@ public: explicit TType(TBasicType t, const TType &p, const TString& n) : basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) +#ifndef GLSLANG_WEB + , spirvType(nullptr) +#endif { assert(t == EbtReference); typeName = NewPoolTString(n.c_str()); @@ -1439,6 +1714,11 @@ public: } else { referentType = copyOf.referentType; } + typeParameters = copyOf.typeParameters; +#ifndef GLSLANG_WEB + spirvType = copyOf.spirvType; +#endif + coopmat = copyOf.isCoopMat(); } // Make complete copy of the whole type graph rooted at 'copyOf'. @@ -1483,6 +1763,23 @@ public: assert(fieldName); return *fieldName; } + TShaderInterface getShaderInterface() const + { + if (basicType != EbtBlock) + return EsiNone; + + switch (qualifier.storage) { + default: + return EsiNone; + case EvqVaryingIn: + return EsiInput; + case EvqVaryingOut: + return EsiOutput; + case EvqUniform: + case EvqBuffer: + return EsiUniform; + } + } virtual TBasicType getBasicType() const { return basicType; } virtual const TSampler& getSampler() const { return sampler; } @@ -1497,14 +1794,21 @@ public: virtual int getOuterArraySize() const { return arraySizes->getOuterSize(); } virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); } virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); } - virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; } +#ifdef GLSLANG_WEB + bool isArrayOfArrays() const { return false; } +#else + bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; } +#endif virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); } virtual const TArraySizes* getArraySizes() const { return arraySizes; } virtual TArraySizes* getArraySizes() { return arraySizes; } virtual TType* getReferentType() const { return referentType; } + virtual const TArraySizes* getTypeParameters() const { return typeParameters; } + virtual TArraySizes* getTypeParameters() { return typeParameters; } virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); } virtual bool isScalarOrVec1() const { return isScalar() || vector1; } + virtual bool isScalarOrVector() const { return !isMatrix() && !isStruct() && !isArray(); } virtual bool isVector() const { return vectorSize > 1 || vector1; } virtual bool isMatrix() const { return matrixCols ? true : false; } virtual bool isArray() const { return arraySizes != nullptr; } @@ -1533,9 +1837,9 @@ public: } return false; } - virtual bool isOpaque() const { return basicType == EbtSampler || basicType == EbtAtomicUint -#ifdef NV_EXTENSIONS - || basicType == EbtAccStructNV + virtual bool isOpaque() const { return basicType == EbtSampler +#ifndef GLSLANG_WEB + || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery #endif ; } virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; } @@ -1544,6 +1848,18 @@ public: virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); } + // Check the block-name convention of creating a block without populating it's members: + virtual bool isUnusableName() const { return isStruct() && structure == nullptr; } + virtual bool isParameterized() const { return typeParameters != nullptr; } +#ifdef GLSLANG_WEB + bool isAtomic() const { return false; } + bool isCoopMat() const { return false; } + bool isReference() const { return false; } +#else + bool isAtomic() const { return basicType == EbtAtomicUint; } + bool isCoopMat() const { return coopmat; } + bool isReference() const { return getBasicType() == EbtReference; } +#endif // return true if this type contains any subtype which satisfies the given predicate. template @@ -1609,6 +1925,7 @@ public: case EbtInt64: case EbtUint64: case EbtBool: + case EbtReference: return true; default: return false; @@ -1623,15 +1940,44 @@ public: return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } ); } - virtual bool contains16BitInt() const +#ifdef GLSLANG_WEB + bool containsDouble() const { return false; } + bool contains16BitFloat() const { return false; } + bool contains64BitInt() const { return false; } + bool contains16BitInt() const { return false; } + bool contains8BitInt() const { return false; } + bool containsCoopMat() const { return false; } + bool containsReference() const { return false; } +#else + bool containsDouble() const + { + return containsBasicType(EbtDouble); + } + bool contains16BitFloat() const + { + return containsBasicType(EbtFloat16); + } + bool contains64BitInt() const + { + return containsBasicType(EbtInt64) || containsBasicType(EbtUint64); + } + bool contains16BitInt() const { return containsBasicType(EbtInt16) || containsBasicType(EbtUint16); } - - virtual bool contains8BitInt() const + bool contains8BitInt() const { return containsBasicType(EbtInt8) || containsBasicType(EbtUint8); } + bool containsCoopMat() const + { + return contains([](const TType* t) { return t->coopmat; } ); + } + bool containsReference() const + { + return containsBasicType(EbtReference); + } +#endif // Array editing methods. Array descriptors can be shared across // type instances. This allows all uses of the same array @@ -1691,11 +2037,9 @@ public: { if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed())) changeOuterArraySize(getImplicitArraySize()); -#ifdef NV_EXTENSIONS // For multi-dim per-view arrays, set unsized inner dimension size to 1 if (qualifier.isPerView() && arraySizes && arraySizes->isInnerUnsized()) arraySizes->clearInnerUnsized(); -#endif if (isStruct() && structure->size() > 0) { int lastMember = (int)structure->size() - 1; for (int i = 0; i < lastMember; ++i) @@ -1705,6 +2049,44 @@ public: } } + + void updateTypeParameters(const TType& type) + { + // For when we may already be sharing existing array descriptors, + // keeping the pointers the same, just updating the contents. + assert(typeParameters != nullptr); + assert(type.typeParameters != nullptr); + *typeParameters = *type.typeParameters; + } + void copyTypeParameters(const TArraySizes& s) + { + // For setting a fresh new set of type parameters, not yet worrying about sharing. + typeParameters = new TArraySizes; + *typeParameters = s; + } + void transferTypeParameters(TArraySizes* s) + { + // For setting an already allocated set of sizes that this type can use + // (no copy made). + typeParameters = s; + } + void clearTypeParameters() + { + typeParameters = nullptr; + } + + // Add inner array sizes, to any existing sizes, via copy; the + // sizes passed in can still be reused for other purposes. + void copyTypeParametersInnerSizes(const TArraySizes* s) + { + if (s != nullptr) { + if (typeParameters == nullptr) + copyTypeParameters(*s); + else + typeParameters->addInnerSizes(*s); + } + } + const char* getBasicString() const { return TType::getBasicString(basicType); @@ -1713,31 +2095,41 @@ public: static const char* getBasicString(TBasicType t) { switch (t) { - case EbtVoid: return "void"; case EbtFloat: return "float"; + case EbtInt: return "int"; + case EbtUint: return "uint"; + case EbtSampler: return "sampler/image"; +#ifndef GLSLANG_WEB + case EbtVoid: return "void"; case EbtDouble: return "double"; case EbtFloat16: return "float16_t"; case EbtInt8: return "int8_t"; case EbtUint8: return "uint8_t"; case EbtInt16: return "int16_t"; case EbtUint16: return "uint16_t"; - case EbtInt: return "int"; - case EbtUint: return "uint"; case EbtInt64: return "int64_t"; case EbtUint64: return "uint64_t"; case EbtBool: return "bool"; case EbtAtomicUint: return "atomic_uint"; - case EbtSampler: return "sampler/image"; case EbtStruct: return "structure"; case EbtBlock: return "block"; -#ifdef NV_EXTENSIONS - case EbtAccStructNV: return "accelerationStructureNV"; -#endif + case EbtAccStruct: return "accelerationStructureNV"; + case EbtRayQuery: return "rayQueryEXT"; case EbtReference: return "reference"; + case EbtString: return "string"; + case EbtSpirvType: return "spirv_type"; +#endif default: return "unknown type"; } } +#ifdef GLSLANG_WEB + TString getCompleteString() const { return ""; } + const char* getStorageQualifierString() const { return ""; } + const char* getBuiltInVariableString() const { return ""; } + const char* getPrecisionQualifierString() const { return ""; } + TString getBasicTypeString() const { return ""; } +#else TString getCompleteString() const { TString typeString; @@ -1746,6 +2138,9 @@ public: const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); }; const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); }; + if (qualifier.hasSprivDecorate()) + appendStr(qualifier.getSpirvDecorateQualifierString().c_str()); + if (qualifier.hasLayout()) { // To reduce noise, skip this if the only layout is an xfb_buffer // with no triggering xfb_offset. @@ -1826,7 +2221,6 @@ public: appendUint(1u << qualifier.layoutBufferReferenceAlign); } -#ifdef NV_EXTENSIONS if (qualifier.layoutPassthrough) appendStr(" passthrough"); if (qualifier.layoutViewportRelative) @@ -1835,9 +2229,8 @@ public: appendStr(" layoutSecondaryViewportRelativeOffset="); appendInt(qualifier.layoutSecondaryViewportRelativeOffset); } - if (qualifier.layoutShaderRecordNV) + if (qualifier.layoutShaderRecord) appendStr(" shaderRecordNV"); -#endif appendStr(")"); } @@ -1855,11 +2248,8 @@ public: appendStr(" flat"); if (qualifier.nopersp) appendStr(" noperspective"); -#ifdef AMD_EXTENSIONS if (qualifier.explicitInterp) appendStr(" __explicitInterpAMD"); -#endif -#ifdef NV_EXTENSIONS if (qualifier.pervertexNV) appendStr(" pervertexNV"); if (qualifier.perPrimitiveNV) @@ -1868,7 +2258,6 @@ public: appendStr(" perviewNV"); if (qualifier.perTaskNV) appendStr(" taskNV"); -#endif if (qualifier.patch) appendStr(" patch"); if (qualifier.sample) @@ -1883,6 +2272,8 @@ public: appendStr(" workgroupcoherent"); if (qualifier.subgroupcoherent) appendStr(" subgroupcoherent"); + if (qualifier.shadercallcoherent) + appendStr(" shadercallcoherent"); if (qualifier.nonprivate) appendStr(" nonprivate"); if (qualifier.volatil) @@ -1897,6 +2288,12 @@ public: appendStr(" specialization-constant"); if (qualifier.nonUniform) appendStr(" nonuniform"); + if (qualifier.isNullInit()) + appendStr(" null-init"); + if (qualifier.isSpirvByReference()) + appendStr(" spirv_by_reference"); + if (qualifier.isSpirvLiteral()) + appendStr(" spirv_literal"); appendStr(" "); appendStr(getStorageQualifierString()); if (isArray()) { @@ -1919,6 +2316,15 @@ public: } } } + if (isParameterized()) { + appendStr("<"); + for(int i = 0; i < (int)typeParameters->getNumDims(); ++i) { + appendInt(typeParameters->getDimSize(i)); + if (i != (int)typeParameters->getNumDims() - 1) + appendStr(", "); + } + appendStr(">"); + } if (qualifier.precision != EpqNone) { appendStr(" "); appendStr(getPrecisionQualifierString()); @@ -1944,15 +2350,17 @@ public: } // Add struct/block members - if (isStruct()) { + if (isStruct() && structure) { appendStr("{"); + bool hasHiddenMember = true; for (size_t i = 0; i < structure->size(); ++i) { if (! (*structure)[i].type->hiddenMember()) { + if (!hasHiddenMember) + appendStr(", "); typeString.append((*structure)[i].type->getCompleteString()); typeString.append(" "); typeString.append((*structure)[i].type->getFieldName()); - if (i < structure->size() - 1) - appendStr(", "); + hasHiddenMember = false; } } appendStr("}"); @@ -1972,10 +2380,13 @@ public: const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); } const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); } const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); } +#endif + const TTypeList* getStruct() const { assert(isStruct()); return structure; } void setStruct(TTypeList* s) { assert(isStruct()); structure = s; } TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads - + void setBasicType(const TBasicType& t) { basicType = t; } + int computeNumComponents() const { int components = 0; @@ -2002,6 +2413,17 @@ public: name += ';' ; } + // These variables are inconsistently declared inside and outside of gl_PerVertex in glslang right now. + // They are declared inside of 'in gl_PerVertex', but sitting as standalone when they are 'out'puts. + bool isInconsistentGLPerVertexMember(const TString& name) const + { + if (name == "gl_SecondaryPositionNV" || + name == "gl_PositionPerViewNV") + return true; + return false; + } + + // Do two structure types match? They could be declared independently, // in different places, but still might satisfy the definition of matching. // From the spec: @@ -2017,33 +2439,59 @@ public: (isStruct() && right.isStruct() && structure == right.structure)) return true; - // Both being nullptr was caught above, now they both have to be structures of the same number of elements - if (!isStruct() || !right.isStruct() || - structure->size() != right.structure->size()) - return false; - // Structure names have to match if (*typeName != *right.typeName) return false; - // Compare the names and types of all the members, which have to match - for (unsigned int i = 0; i < structure->size(); ++i) { - if ((*structure)[i].type->getFieldName() != (*right.structure)[i].type->getFieldName()) - return false; + // There are inconsistencies with how gl_PerVertex is setup. For now ignore those as errors if they + // are known inconsistencies. + bool isGLPerVertex = *typeName == "gl_PerVertex"; - if (*(*structure)[i].type != *(*right.structure)[i].type) - return false; + // Both being nullptr was caught above, now they both have to be structures of the same number of elements + if (!isStruct() || !right.isStruct() || + (structure->size() != right.structure->size() && !isGLPerVertex)) + return false; + + // Compare the names and types of all the members, which have to match + for (size_t li = 0, ri = 0; li < structure->size() || ri < right.structure->size(); ++li, ++ri) { + if (li < structure->size() && ri < right.structure->size()) { + if ((*structure)[li].type->getFieldName() == (*right.structure)[ri].type->getFieldName()) { + if (*(*structure)[li].type != *(*right.structure)[ri].type) + return false; + } else { + // If one of the members is something that's inconsistently declared, skip over it + // for now. + if (isGLPerVertex) { + if (isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName())) { + ri--; + continue; + } else if (isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName())) { + li--; + continue; + } + } else { + return false; + } + } + // If we get here, then there should only be inconsistently declared members left + } else if (li < structure->size()) { + if (!isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName())) + return false; + } else { + if (!isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName())) + return false; + } } return true; } - bool sameReferenceType(const TType& right) const + bool sameReferenceType(const TType& right) const { - if ((basicType == EbtReference) != (right.basicType == EbtReference)) + if (isReference() != right.isReference()) return false; - if ((basicType != EbtReference) && (right.basicType != EbtReference)) + if (!isReference() && !right.isReference()) return true; assert(referentType != nullptr); @@ -2055,7 +2503,7 @@ public: return *referentType == *right.referentType; } - // See if two types match, in all aspects except arrayness + // See if two types match, in all aspects except arrayness bool sameElementType(const TType& right) const { return basicType == right.basicType && sameElementShape(right); @@ -2075,6 +2523,22 @@ public: return arraySizes->sameInnerArrayness(*right.arraySizes); } + // See if two type's parameters match + bool sameTypeParameters(const TType& right) const + { + return ((typeParameters == nullptr && right.typeParameters == nullptr) || + (typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters)); + } + +#ifndef GLSLANG_WEB + // See if two type's SPIR-V type contents match + bool sameSpirvType(const TType& right) const + { + return ((spirvType == nullptr && right.spirvType == nullptr) || + (spirvType != nullptr && right.spirvType != nullptr && *spirvType == *right.spirvType)); + } +#endif + // See if two type's elements match in all ways except basic type bool sameElementShape(const TType& right) const { @@ -2083,14 +2547,41 @@ public: matrixCols == right.matrixCols && matrixRows == right.matrixRows && vector1 == right.vector1 && + isCoopMat() == right.isCoopMat() && sameStructType(right) && sameReferenceType(right); } + // See if a cooperative matrix type parameter with unspecified parameters is + // an OK function parameter + bool coopMatParameterOK(const TType& right) const + { + return isCoopMat() && right.isCoopMat() && (getBasicType() == right.getBasicType()) && + typeParameters == nullptr && right.typeParameters != nullptr; + } + + bool sameCoopMatBaseType(const TType &right) const { + bool rv = coopmat && right.coopmat; + if (getBasicType() == EbtFloat || getBasicType() == EbtFloat16) + rv = right.getBasicType() == EbtFloat || right.getBasicType() == EbtFloat16; + else if (getBasicType() == EbtUint || getBasicType() == EbtUint8) + rv = right.getBasicType() == EbtUint || right.getBasicType() == EbtUint8; + else if (getBasicType() == EbtInt || getBasicType() == EbtInt8) + rv = right.getBasicType() == EbtInt || right.getBasicType() == EbtInt8; + else + rv = false; + return rv; + } + + // See if two types match in all ways (just the actual type, not qualification) bool operator==(const TType& right) const { - return sameElementType(right) && sameArrayness(right); +#ifndef GLSLANG_WEB + return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right) && sameSpirvType(right); +#else + return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right); +#endif } bool operator!=(const TType& right) const @@ -2098,6 +2589,21 @@ public: return ! operator==(right); } + unsigned int getBufferReferenceAlignment() const + { +#ifndef GLSLANG_WEB + if (getBasicType() == glslang::EbtReference) { + return getReferentType()->getQualifier().hasBufferReferenceAlign() ? + (1u << getReferentType()->getQualifier().layoutBufferReferenceAlign) : 16u; + } +#endif + return 0; + } + +#ifndef GLSLANG_WEB + const TSpirvType& getSpirvType() const { assert(spirvType); return *spirvType; } +#endif + protected: // Require consumer to pick between deep copy and shallow copy. TType(const TType& type); @@ -2110,11 +2616,29 @@ protected: { shallowCopy(copyOf); +#ifndef GLSLANG_WEB + // GL_EXT_spirv_intrinsics + if (copyOf.qualifier.spirvDecorate) { + qualifier.spirvDecorate = new TSpirvDecorate; + *qualifier.spirvDecorate = *copyOf.qualifier.spirvDecorate; + } + + if (copyOf.spirvType) { + spirvType = new TSpirvType; + *spirvType = *copyOf.spirvType; + } +#endif + if (copyOf.arraySizes) { arraySizes = new TArraySizes; *arraySizes = *copyOf.arraySizes; } + if (copyOf.typeParameters) { + typeParameters = new TArraySizes; + *typeParameters = *copyOf.typeParameters; + } + if (copyOf.isStruct() && copyOf.structure) { auto prevCopy = copiedMap.find(copyOf.structure); if (prevCopy != copiedMap.end()) @@ -2150,6 +2674,7 @@ protected: // functionality is added. // HLSL does have a 1-component vectors, so this will be true to disambiguate // from a scalar. + bool coopmat : 1; TQualifier qualifier; TArraySizes* arraySizes; // nullptr unless an array; can be shared across types @@ -2162,6 +2687,10 @@ protected: TString *fieldName; // for structure field names TString *typeName; // for structure type name TSampler sampler; + TArraySizes* typeParameters;// nullptr unless a parameterized type; can be shared across types +#ifndef GLSLANG_WEB + TSpirvType* spirvType; // SPIR-V type defined by spirv_type directive +#endif }; } // end namespace glslang diff --git a/thirdparty/ShaderCompiler/glslang/Include/arrays.h b/thirdparty/ShaderCompiler/glslang/Include/arrays.h index af8f560..7f047d9 100644 --- a/thirdparty/ShaderCompiler/glslang/Include/arrays.h +++ b/thirdparty/ShaderCompiler/glslang/Include/arrays.h @@ -254,7 +254,9 @@ struct TArraySizes { void addInnerSize() { addInnerSize((unsigned)UnsizedArraySize); } void addInnerSize(int s) { addInnerSize((unsigned)s, nullptr); } void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); } - void addInnerSize(TArraySize pair) { sizes.push_back(pair.size, pair.node); } + void addInnerSize(TArraySize pair) { + sizes.push_back(pair.size, pair.node); + } void addInnerSizes(const TArraySizes& s) { sizes.push_back(s.sizes); } void changeOuterSize(int s) { sizes.changeFront((unsigned)s); } int getImplicitSize() const { return implicitArraySize; } @@ -318,8 +320,8 @@ struct TArraySizes { void setVariablyIndexed() { variablyIndexed = true; } bool isVariablyIndexed() const { return variablyIndexed; } - bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; } - bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; } + bool operator==(const TArraySizes& rhs) const { return sizes == rhs.sizes; } + bool operator!=(const TArraySizes& rhs) const { return sizes != rhs.sizes; } protected: TSmallArrayVector sizes; diff --git a/thirdparty/ShaderCompiler/glslang/Include/build_info.h b/thirdparty/ShaderCompiler/glslang/Include/build_info.h new file mode 100644 index 0000000..661c4a3 --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/Include/build_info.h @@ -0,0 +1,62 @@ +// Copyright (C) 2020 The Khronos Group Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of The Khronos Group Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef GLSLANG_BUILD_INFO +#define GLSLANG_BUILD_INFO + +#define GLSLANG_VERSION_MAJOR 11 +#define GLSLANG_VERSION_MINOR 6 +#define GLSLANG_VERSION_PATCH 0 +#define GLSLANG_VERSION_FLAVOR "" + +#define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \ + (((major) > GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ + (((minor) > GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ + ((patch) > GLSLANG_VERSION_PATCH))))) + +#define GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch) \ + (((major) > GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ + (((minor) > GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ + ((patch) >= GLSLANG_VERSION_PATCH))))) + +#define GLSLANG_VERSION_LESS_THAN(major, minor, patch) \ + (((major) < GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ + (((minor) < GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ + ((patch) < GLSLANG_VERSION_PATCH))))) + +#define GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch) \ + (((major) < GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ + (((minor) < GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ + ((patch) <= GLSLANG_VERSION_PATCH))))) + +#endif // GLSLANG_BUILD_INFO diff --git a/thirdparty/ShaderCompiler/glslang/Include/intermediate.h b/thirdparty/ShaderCompiler/glslang/Include/intermediate.h index 4b6bcb7..1e6ab4a 100644 --- a/thirdparty/ShaderCompiler/glslang/Include/intermediate.h +++ b/thirdparty/ShaderCompiler/glslang/Include/intermediate.h @@ -2,6 +2,7 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -70,6 +71,9 @@ enum TOperator { EOpFunctionCall, EOpFunction, // For function definition EOpParameters, // an aggregate listing the parameters to a function +#ifndef GLSLANG_WEB + EOpSpirvInst, +#endif // // Unary operators @@ -85,6 +89,8 @@ enum TOperator { EOpPreIncrement, EOpPreDecrement, + EOpCopyObject, + // (u)int* -> bool EOpConvInt8ToBool, EOpConvUint8ToBool, @@ -273,6 +279,16 @@ enum TOperator { EOpConvUint64ToPtr, EOpConvPtrToUint64, + // uvec2 <-> pointer + EOpConvUvec2ToPtr, + EOpConvPtrToUvec2, + + // uint64_t -> accelerationStructureEXT + EOpConvUint64ToAccStruct, + + // uvec2 -> accelerationStructureEXT + EOpConvUvec2ToAccStruct, + // // binary operations // @@ -420,11 +436,9 @@ enum TOperator { EOpReflect, EOpRefract, -#ifdef AMD_EXTENSIONS EOpMin3, EOpMax3, EOpMid3, -#endif EOpDPdx, // Fragment only EOpDPdy, // Fragment only @@ -439,10 +453,7 @@ enum TOperator { EOpInterpolateAtCentroid, // Fragment only EOpInterpolateAtSample, // Fragment only EOpInterpolateAtOffset, // Fragment only - -#ifdef AMD_EXTENSIONS EOpInterpolateAtVertex, -#endif EOpMatrixTimesMatrix, EOpOuterProduct, @@ -532,7 +543,6 @@ enum TOperator { EOpSubgroupQuadSwapVertical, EOpSubgroupQuadSwapDiagonal, -#ifdef NV_EXTENSIONS EOpSubgroupPartition, EOpSubgroupPartitionedAdd, EOpSubgroupPartitionedMul, @@ -555,11 +565,9 @@ enum TOperator { EOpSubgroupPartitionedExclusiveAnd, EOpSubgroupPartitionedExclusiveOr, EOpSubgroupPartitionedExclusiveXor, -#endif EOpSubgroupGuardStop, -#ifdef AMD_EXTENSIONS EOpMinInvocations, EOpMaxInvocations, EOpAddInvocations, @@ -586,9 +594,9 @@ enum TOperator { EOpCubeFaceIndex, EOpCubeFaceCoord, EOpTime, -#endif EOpAtomicAdd, + EOpAtomicSubtract, EOpAtomicMin, EOpAtomicMax, EOpAtomicAnd, @@ -615,11 +623,26 @@ enum TOperator { EOpAny, EOpAll, + EOpCooperativeMatrixLoad, + EOpCooperativeMatrixStore, + EOpCooperativeMatrixMulAdd, + + EOpBeginInvocationInterlock, // Fragment only + EOpEndInvocationInterlock, // Fragment only + + EOpIsHelperInvocation, + + EOpDebugPrintf, + // // Branch // - EOpKill, // Fragment only + EOpKill, // Fragment only + EOpTerminateInvocation, // Fragment only + EOpDemote, // Fragment only + EOpTerminateRayKHR, // Any-hit only + EOpIgnoreIntersectionKHR, // Any-hit only EOpReturn, EOpBreak, EOpContinue, @@ -642,9 +665,21 @@ enum TOperator { EOpConstructBool, EOpConstructFloat, EOpConstructDouble, + // Keep vector and matrix constructors in a consistent relative order for + // TParseContext::constructBuiltIn, which converts between 8/16/32 bit + // vector constructors EOpConstructVec2, EOpConstructVec3, EOpConstructVec4, + EOpConstructMat2x2, + EOpConstructMat2x3, + EOpConstructMat2x4, + EOpConstructMat3x2, + EOpConstructMat3x3, + EOpConstructMat3x4, + EOpConstructMat4x2, + EOpConstructMat4x3, + EOpConstructMat4x4, EOpConstructDVec2, EOpConstructDVec3, EOpConstructDVec4, @@ -675,15 +710,6 @@ enum TOperator { EOpConstructU64Vec2, EOpConstructU64Vec3, EOpConstructU64Vec4, - EOpConstructMat2x2, - EOpConstructMat2x3, - EOpConstructMat2x4, - EOpConstructMat3x2, - EOpConstructMat3x3, - EOpConstructMat3x4, - EOpConstructMat4x2, - EOpConstructMat4x3, - EOpConstructMat4x4, EOpConstructDMat2x2, EOpConstructDMat2x3, EOpConstructDMat2x4, @@ -737,6 +763,8 @@ enum TOperator { EOpConstructTextureSampler, EOpConstructNonuniform, // expected to be transformed away, not present in final AST EOpConstructReference, + EOpConstructCooperativeMatrix, + EOpConstructAccStruct, EOpConstructGuardEnd, // @@ -779,10 +807,8 @@ enum TOperator { EOpImageQuerySamples, EOpImageLoad, EOpImageStore, -#ifdef AMD_EXTENSIONS EOpImageLoadLod, EOpImageStoreLod, -#endif EOpImageAtomicAdd, EOpImageAtomicMin, EOpImageAtomicMax, @@ -797,9 +823,7 @@ enum TOperator { EOpSubpassLoad, EOpSubpassLoadMS, EOpSparseImageLoad, -#ifdef AMD_EXTENSIONS EOpSparseImageLoadLod, -#endif EOpImageGuardEnd, @@ -837,13 +861,11 @@ enum TOperator { EOpTextureOffsetClamp, EOpTextureGradClamp, EOpTextureGradOffsetClamp, -#ifdef AMD_EXTENSIONS EOpTextureGatherLod, EOpTextureGatherLodOffset, EOpTextureGatherLodOffsets, EOpFragmentMaskFetch, EOpFragmentFetch, -#endif EOpSparseTextureGuardBegin, @@ -863,15 +885,12 @@ enum TOperator { EOpSparseTextureOffsetClamp, EOpSparseTextureGradClamp, EOpSparseTextureGradOffsetClamp, -#ifdef AMD_EXTENSIONS EOpSparseTextureGatherLod, EOpSparseTextureGatherLodOffset, EOpSparseTextureGatherLodOffsets, -#endif EOpSparseTextureGuardEnd, -#ifdef NV_EXTENSIONS EOpImageFootprintGuardBegin, EOpImageSampleFootprintNV, EOpImageSampleFootprintClampNV, @@ -879,7 +898,6 @@ enum TOperator { EOpImageSampleFootprintGradNV, EOpImageSampleFootprintGradClampNV, EOpImageFootprintGuardEnd, -#endif EOpSamplingGuardEnd, EOpTextureGuardEnd, @@ -898,14 +916,53 @@ enum TOperator { EOpFindLSB, EOpFindMSB, -#ifdef NV_EXTENSIONS + EOpCountLeadingZeros, + EOpCountTrailingZeros, + EOpAbsDifference, + EOpAddSaturate, + EOpSubSaturate, + EOpAverage, + EOpAverageRounded, + EOpMul32x16, + EOpTraceNV, - EOpReportIntersectionNV, + EOpTraceRayMotionNV, + EOpTraceKHR, + EOpReportIntersection, EOpIgnoreIntersectionNV, EOpTerminateRayNV, EOpExecuteCallableNV, + EOpExecuteCallableKHR, EOpWritePackedPrimitiveIndices4x8NV, -#endif + + // + // GL_EXT_ray_query operations + // + + EOpRayQueryInitialize, + EOpRayQueryTerminate, + EOpRayQueryGenerateIntersection, + EOpRayQueryConfirmIntersection, + EOpRayQueryProceed, + EOpRayQueryGetIntersectionType, + EOpRayQueryGetRayTMin, + EOpRayQueryGetRayFlags, + EOpRayQueryGetIntersectionT, + EOpRayQueryGetIntersectionInstanceCustomIndex, + EOpRayQueryGetIntersectionInstanceId, + EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset, + EOpRayQueryGetIntersectionGeometryIndex, + EOpRayQueryGetIntersectionPrimitiveIndex, + EOpRayQueryGetIntersectionBarycentrics, + EOpRayQueryGetIntersectionFrontFace, + EOpRayQueryGetIntersectionCandidateAABBOpaque, + EOpRayQueryGetIntersectionObjectRayDirection, + EOpRayQueryGetIntersectionObjectRayOrigin, + EOpRayQueryGetWorldRayDirection, + EOpRayQueryGetWorldRayOrigin, + EOpRayQueryGetIntersectionObjectToWorld, + EOpRayQueryGetIntersectionWorldToObject, + // // HLSL operations // @@ -989,6 +1046,10 @@ enum TOperator { EOpWaveGetLaneIndex, // Will decompose to gl_SubgroupInvocationID. EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()). EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()). + + // Shader Clock Ops + EOpReadClockSubgroupKHR, + EOpReadClockDeviceKHR, }; class TIntermTraverser; @@ -1079,6 +1140,8 @@ public: virtual TBasicType getBasicType() const { return type.getBasicType(); } virtual TQualifier& getQualifier() { return type.getQualifier(); } virtual const TQualifier& getQualifier() const { return type.getQualifier(); } + virtual TArraySizes* getArraySizes() { return type.getArraySizes(); } + virtual const TArraySizes* getArraySizes() const { return type.getArraySizes(); } virtual void propagatePrecision(TPrecisionQualifier); virtual int getVectorSize() const { return type.getVectorSize(); } virtual int getMatrixCols() const { return type.getMatrixCols(); } @@ -1090,6 +1153,8 @@ public: virtual bool isStruct() const { return type.isStruct(); } virtual bool isFloatingDomain() const { return type.isFloatingDomain(); } virtual bool isIntegerDomain() const { return type.isIntegerDomain(); } + bool isAtomic() const { return type.isAtomic(); } + bool isReference() const { return type.isReference(); } TString getCompleteString() const { return type.getCompleteString(); } protected: @@ -1109,7 +1174,12 @@ public: first(testFirst), unroll(false), dontUnroll(false), - dependency(0) + dependency(0), + minIterations(0), + maxIterations(iterationsInfinite), + iterationMultiple(1), + peelCount(0), + partialCount(0) { } virtual TIntermLoop* getAsLoopNode() { return this; } @@ -1121,14 +1191,36 @@ public: bool testFirst() const { return first; } void setUnroll() { unroll = true; } - void setDontUnroll() { dontUnroll = true; } + void setDontUnroll() { + dontUnroll = true; + peelCount = 0; + partialCount = 0; + } bool getUnroll() const { return unroll; } bool getDontUnroll() const { return dontUnroll; } static const unsigned int dependencyInfinite = 0xFFFFFFFF; + static const unsigned int iterationsInfinite = 0xFFFFFFFF; void setLoopDependency(int d) { dependency = d; } int getLoopDependency() const { return dependency; } + void setMinIterations(unsigned int v) { minIterations = v; } + unsigned int getMinIterations() const { return minIterations; } + void setMaxIterations(unsigned int v) { maxIterations = v; } + unsigned int getMaxIterations() const { return maxIterations; } + void setIterationMultiple(unsigned int v) { iterationMultiple = v; } + unsigned int getIterationMultiple() const { return iterationMultiple; } + void setPeelCount(unsigned int v) { + peelCount = v; + dontUnroll = false; + } + unsigned int getPeelCount() const { return peelCount; } + void setPartialCount(unsigned int v) { + partialCount = v; + dontUnroll = false; + } + unsigned int getPartialCount() const { return partialCount; } + protected: TIntermNode* body; // code to loop over TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops @@ -1137,6 +1229,11 @@ protected: bool unroll; // true if unroll requested bool dontUnroll; // true if request to not unroll unsigned int dependency; // loop dependency hint; 0 means not set or unknown + unsigned int minIterations; // as per the SPIR-V specification + unsigned int maxIterations; // as per the SPIR-V specification + unsigned int iterationMultiple; // as per the SPIR-V specification + unsigned int peelCount; // as per the SPIR-V specification + unsigned int partialCount; // as per the SPIR-V specification }; // @@ -1152,6 +1249,8 @@ public: virtual void traverse(TIntermTraverser*); TOperator getFlowOp() const { return flowOp; } TIntermTyped* getExpression() const { return expression; } + void setExpression(TIntermTyped* pExpression) { expression = pExpression; } + void updatePrecision(TPrecisionQualifier parentPrecision); protected: TOperator flowOp; TIntermTyped* expression; @@ -1183,15 +1282,15 @@ public: // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from // per process threadPoolAllocator, then it causes increased memory usage per compile // it is essential to use "symbol = sym" to assign to symbol - TIntermSymbol(int i, const TString& n, const TType& t) + TIntermSymbol(long long i, const TString& n, const TType& t) : TIntermTyped(t), id(i), -#ifdef ENABLE_HLSL +#ifndef GLSLANG_WEB flattenSubset(-1), #endif constSubtree(nullptr) { name = n; } - virtual int getId() const { return id; } - virtual void changeId(int i) { id = i; } + virtual long long getId() const { return id; } + virtual void changeId(long long i) { id = i; } virtual const TString& getName() const { return name; } virtual void traverse(TIntermTraverser*); virtual TIntermSymbol* getAsSymbolNode() { return this; } @@ -1200,18 +1299,20 @@ public: const TConstUnionArray& getConstArray() const { return constArray; } void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; } TIntermTyped* getConstSubtree() const { return constSubtree; } -#ifdef ENABLE_HLSL +#ifndef GLSLANG_WEB void setFlattenSubset(int subset) { flattenSubset = subset; } + virtual const TString& getAccessName() const; + int getFlattenSubset() const { return flattenSubset; } // -1 means full object #endif // This is meant for cases where a node has already been constructed, and // later on, it becomes necessary to switch to a different symbol. - virtual void switchId(int newId) { id = newId; } + virtual void switchId(long long newId) { id = newId; } protected: - int id; // the unique id of the symbol this node represents -#ifdef ENABLE_HLSL + long long id; // the unique id of the symbol this node represents +#ifndef GLSLANG_WEB int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced #endif TString name; // the name of the symbol this node represents @@ -1251,9 +1352,7 @@ struct TCrackedTextureOp { bool grad; bool subpass; bool lodClamp; -#ifdef AMD_EXTENSIONS bool fragMask; -#endif }; // @@ -1269,12 +1368,19 @@ public: bool isConstructor() const; bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; } bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; } +#ifdef GLSLANG_WEB + bool isImage() const { return false; } + bool isSparseTexture() const { return false; } + bool isImageFootprint() const { return false; } + bool isSparseImage() const { return false; } + bool isSubgroup() const { return false; } +#else bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; } bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; } -#ifdef NV_EXTENSIONS bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; } -#endif bool isSparseImage() const { return op == EOpSparseImageLoad; } + bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; } +#endif void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; } TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ? @@ -1304,9 +1410,7 @@ public: cracked.grad = false; cracked.subpass = false; cracked.lodClamp = false; -#ifdef AMD_EXTENSIONS cracked.fragMask = false; -#endif switch (op) { case EOpImageQuerySize: @@ -1321,10 +1425,6 @@ public: case EOpTexture: case EOpSparseTexture: break; - case EOpTextureClamp: - case EOpSparseTextureClamp: - cracked.lodClamp = true; - break; case EOpTextureProj: cracked.proj = true; break; @@ -1336,22 +1436,17 @@ public: case EOpSparseTextureOffset: cracked.offset = true; break; - case EOpTextureOffsetClamp: - case EOpSparseTextureOffsetClamp: - cracked.offset = true; - cracked.lodClamp = true; - break; case EOpTextureFetch: case EOpSparseTextureFetch: cracked.fetch = true; - if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D) cracked.lod = true; break; case EOpTextureFetchOffset: case EOpSparseTextureFetchOffset: cracked.fetch = true; cracked.offset = true; - if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D) cracked.lod = true; break; case EOpTextureProjOffset: @@ -1376,11 +1471,6 @@ public: case EOpSparseTextureGrad: cracked.grad = true; break; - case EOpTextureGradClamp: - case EOpSparseTextureGradClamp: - cracked.grad = true; - cracked.lodClamp = true; - break; case EOpTextureGradOffset: case EOpSparseTextureGradOffset: cracked.grad = true; @@ -1395,6 +1485,21 @@ public: cracked.offset = true; cracked.proj = true; break; +#ifndef GLSLANG_WEB + case EOpTextureClamp: + case EOpSparseTextureClamp: + cracked.lodClamp = true; + break; + case EOpTextureOffsetClamp: + case EOpSparseTextureOffsetClamp: + cracked.offset = true; + cracked.lodClamp = true; + break; + case EOpTextureGradClamp: + case EOpSparseTextureGradClamp: + cracked.grad = true; + cracked.lodClamp = true; + break; case EOpTextureGradOffsetClamp: case EOpSparseTextureGradOffsetClamp: cracked.grad = true; @@ -1415,7 +1520,6 @@ public: cracked.gather = true; cracked.offsets = true; break; -#ifdef AMD_EXTENSIONS case EOpTextureGatherLod: case EOpSparseTextureGatherLod: cracked.gather = true; @@ -1446,8 +1550,6 @@ public: cracked.subpass = sampler.dim == EsdSubpass; cracked.fragMask = true; break; -#endif -#ifdef NV_EXTENSIONS case EOpImageSampleFootprintNV: break; case EOpImageSampleFootprintClampNV: @@ -1463,11 +1565,11 @@ public: cracked.lodClamp = true; cracked.grad = true; break; -#endif case EOpSubpassLoad: case EOpSubpassLoadMS: cracked.subpass = true; break; +#endif default: break; } @@ -1518,8 +1620,15 @@ public: virtual TIntermUnary* getAsUnaryNode() { return this; } virtual const TIntermUnary* getAsUnaryNode() const { return this; } virtual void updatePrecision(); +#ifndef GLSLANG_WEB + void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; } + const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; } +#endif protected: TIntermTyped* operand; +#ifndef GLSLANG_WEB + TSpirvInstruction spirvInst; +#endif }; typedef TVector TIntermSequence; @@ -1550,6 +1659,10 @@ public: bool getDebug() const { return debug; } void setPragmaTable(const TPragmaTable& pTable); const TPragmaTable& getPragmaTable() const { return *pragmaTable; } +#ifndef GLSLANG_WEB + void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; } + const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; } +#endif protected: TIntermAggregate(const TIntermAggregate&); // disallow copy constructor TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator @@ -1560,6 +1673,9 @@ protected: bool optimize; bool debug; TPragmaTable* pragmaTable; +#ifndef GLSLANG_WEB + TSpirvInstruction spirvInst; +#endif }; // @@ -1577,8 +1693,11 @@ public: flatten(false), dontFlatten(false) {} virtual void traverse(TIntermTraverser*); virtual TIntermTyped* getCondition() const { return condition; } + virtual void setCondition(TIntermTyped* c) { condition = c; } virtual TIntermNode* getTrueBlock() const { return trueBlock; } + virtual void setTrueBlock(TIntermTyped* tb) { trueBlock = tb; } virtual TIntermNode* getFalseBlock() const { return falseBlock; } + virtual void setFalseBlock(TIntermTyped* fb) { falseBlock = fb; } virtual TIntermSelection* getAsSelectionNode() { return this; } virtual const TIntermSelection* getAsSelectionNode() const { return this; } diff --git a/thirdparty/ShaderCompiler/glslang/Include/revision.h b/thirdparty/ShaderCompiler/glslang/Include/revision.h deleted file mode 100644 index 702c89e..0000000 --- a/thirdparty/ShaderCompiler/glslang/Include/revision.h +++ /dev/null @@ -1,3 +0,0 @@ -// This header is generated by the make-revision script. - -#define GLSLANG_PATCH_LEVEL 3057 diff --git a/thirdparty/ShaderCompiler/glslang/Include/revision.template b/thirdparty/ShaderCompiler/glslang/Include/revision.template deleted file mode 100644 index 4a16bee..0000000 --- a/thirdparty/ShaderCompiler/glslang/Include/revision.template +++ /dev/null @@ -1,13 +0,0 @@ -// The file revision.h should be updated to the latest version, somehow, on -// check-in, if glslang has changed. -// -// revision.template is the source for revision.h when using SubWCRev as the -// method of updating revision.h. You don't have to do it this way, the -// requirement is only that revision.h gets updated. -// -// revision.h is under source control so that not all consumers of glslang -// source have to figure out how to create revision.h just to get a build -// going. However, if it is not updated, it can be a version behind. - -#define GLSLANG_REVISION "$WCREV$" -#define GLSLANG_DATE "$WCDATE$" diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Constant.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Constant.cpp index 58cb264..17b496c 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Constant.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Constant.cpp @@ -2,7 +2,7 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. -// Copyright (C) 2018 Google, Inc. +// Copyright (C) 2018-2020 Google, Inc. // // All rights reserved. // @@ -42,6 +42,10 @@ #include #include +#ifdef _MSC_VER +#pragma warning(disable: 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned +#endif + namespace { using namespace glslang; @@ -189,6 +193,24 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right else newConstArray[i].setDConst((double)NAN); break; + + case EbtInt: + if (rightUnionArray[i] == 0) + newConstArray[i].setIConst(0x7FFFFFFF); + else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)-0x80000000ll) + newConstArray[i].setIConst((int)-0x80000000ll); + else + newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst()); + break; + + case EbtUint: + if (rightUnionArray[i] == 0u) + newConstArray[i].setUConst(0xFFFFFFFFu); + else + newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst()); + break; + +#ifndef GLSLANG_WEB case EbtInt8: if (rightUnionArray[i] == (signed char)0) newConstArray[i].setI8Const((signed char)0x7F); @@ -221,27 +243,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const()); break; - case EbtInt: - if (rightUnionArray[i] == 0) - newConstArray[i].setIConst(0x7FFFFFFF); - else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)-0x80000000ll) - newConstArray[i].setIConst((int)-0x80000000ll); - else - newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst()); - break; - - case EbtUint: - if (rightUnionArray[i] == 0u) - newConstArray[i].setUConst(0xFFFFFFFFu); - else - newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst()); - break; - case EbtInt64: if (rightUnionArray[i] == 0ll) newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll); - else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == -(long long)0x8000000000000000ll) - newConstArray[i].setI64Const(-(long long)0x8000000000000000ll); + else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == (long long)-0x8000000000000000ll) + newConstArray[i].setI64Const((long long)-0x8000000000000000ll); else newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const()); break; @@ -254,6 +260,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right break; default: return 0; +#endif } } break; @@ -292,13 +299,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right newConstArray[i].setIConst(0); break; } else goto modulo_default; - +#ifndef GLSLANG_WEB case EbtInt64: if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) { newConstArray[i].setI64Const(0); break; } else goto modulo_default; -#ifdef AMD_EXTENSIONS case EbtInt16: if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == SHRT_MIN) { newConstArray[i].setIConst(0); @@ -415,8 +421,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpEmitStreamVertex: case EOpEndStreamPrimitive: - // These don't actually fold - return 0; + // These don't fold + return nullptr; case EOpPackSnorm2x16: case EOpPackUnorm2x16: @@ -491,8 +497,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) break; } - // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out - case EOpPackSnorm2x16: case EOpPackUnorm2x16: case EOpPackHalf2x16: @@ -510,7 +514,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpDeterminant: case EOpMatrixInverse: case EOpTranspose: - return 0; + return nullptr; default: assert(componentWise); @@ -529,16 +533,23 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EbtDouble: case EbtFloat16: case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break; + // Note: avoid UBSAN error regarding negating 0x80000000 + case EbtInt: newConstArray[i].setIConst( + unionArray[i].getIConst() == 0x80000000 + ? -0x7FFFFFFF - 1 + : -unionArray[i].getIConst()); + break; + case EbtUint: newConstArray[i].setUConst(static_cast(-static_cast(unionArray[i].getUConst()))); break; +#ifndef GLSLANG_WEB case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break; case EbtUint8: newConstArray[i].setU8Const(static_cast(-static_cast(unionArray[i].getU8Const()))); break; case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break; case EbtUint16:newConstArray[i].setU16Const(static_cast(-static_cast(unionArray[i].getU16Const()))); break; - case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break; - case EbtUint: newConstArray[i].setUConst(static_cast(-static_cast(unionArray[i].getUConst()))); break; case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break; case EbtUint64: newConstArray[i].setU64Const(static_cast(-static_cast(unionArray[i].getU64Const()))); break; +#endif default: - return 0; + return nullptr; } break; case EOpLogicalNot: @@ -546,7 +557,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) switch (getType().getBasicType()) { case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break; default: - return 0; + return nullptr; } break; case EOpBitwiseNot: @@ -597,17 +608,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) newConstArray[i].setDConst(log(unionArray[i].getDConst())); break; case EOpExp2: - { - const double inv_log2_e = 0.69314718055994530941723212145818; - newConstArray[i].setDConst(exp(unionArray[i].getDConst() * inv_log2_e)); - break; - } + newConstArray[i].setDConst(exp2(unionArray[i].getDConst())); + break; case EOpLog2: - { - const double log2_e = 1.4426950408889634073599246810019; - newConstArray[i].setDConst(log2_e * log(unionArray[i].getDConst())); - break; - } + newConstArray[i].setDConst(log2(unionArray[i].getDConst())); + break; case EOpSqrt: newConstArray[i].setDConst(sqrt(unionArray[i].getDConst())); break; @@ -671,6 +676,48 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) break; } + case EOpConvIntToBool: + newConstArray[i].setBConst(unionArray[i].getIConst() != 0); break; + case EOpConvUintToBool: + newConstArray[i].setBConst(unionArray[i].getUConst() != 0); break; + case EOpConvBoolToInt: + newConstArray[i].setIConst(unionArray[i].getBConst()); break; + case EOpConvBoolToUint: + newConstArray[i].setUConst(unionArray[i].getBConst()); break; + case EOpConvIntToUint: + newConstArray[i].setUConst(unionArray[i].getIConst()); break; + case EOpConvUintToInt: + newConstArray[i].setIConst(unionArray[i].getUConst()); break; + + case EOpConvFloatToBool: + case EOpConvDoubleToBool: + newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break; + + case EOpConvBoolToFloat: + case EOpConvBoolToDouble: + newConstArray[i].setDConst(unionArray[i].getBConst()); break; + + case EOpConvIntToFloat: + case EOpConvIntToDouble: + newConstArray[i].setDConst(unionArray[i].getIConst()); break; + + case EOpConvUintToFloat: + case EOpConvUintToDouble: + newConstArray[i].setDConst(unionArray[i].getUConst()); break; + + case EOpConvDoubleToFloat: + case EOpConvFloatToDouble: + newConstArray[i].setDConst(unionArray[i].getDConst()); break; + + case EOpConvFloatToUint: + case EOpConvDoubleToUint: + newConstArray[i].setUConst(static_cast(unionArray[i].getDConst())); break; + + case EOpConvFloatToInt: + case EOpConvDoubleToInt: + newConstArray[i].setIConst(static_cast(unionArray[i].getDConst())); break; + +#ifndef GLSLANG_WEB case EOpConvInt8ToBool: newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break; case EOpConvUint8ToBool: @@ -679,20 +726,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) newConstArray[i].setBConst(unionArray[i].getI16Const() != 0); break; case EOpConvUint16ToBool: newConstArray[i].setBConst(unionArray[i].getU16Const() != 0); break; - case EOpConvIntToBool: - newConstArray[i].setBConst(unionArray[i].getIConst() != 0); break; - case EOpConvUintToBool: - newConstArray[i].setBConst(unionArray[i].getUConst() != 0); break; case EOpConvInt64ToBool: newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break; case EOpConvUint64ToBool: newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break; case EOpConvFloat16ToBool: newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break; - case EOpConvFloatToBool: - newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break; - case EOpConvDoubleToBool: - newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break; case EOpConvBoolToInt8: newConstArray[i].setI8Const(unionArray[i].getBConst()); break; @@ -702,20 +741,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) newConstArray[i].setI16Const(unionArray[i].getBConst()); break; case EOpConvBoolToUint16: newConstArray[i].setU16Const(unionArray[i].getBConst()); break; - case EOpConvBoolToInt: - newConstArray[i].setIConst(unionArray[i].getBConst()); break; - case EOpConvBoolToUint: - newConstArray[i].setUConst(unionArray[i].getBConst()); break; case EOpConvBoolToInt64: newConstArray[i].setI64Const(unionArray[i].getBConst()); break; case EOpConvBoolToUint64: newConstArray[i].setU64Const(unionArray[i].getBConst()); break; case EOpConvBoolToFloat16: newConstArray[i].setDConst(unionArray[i].getBConst()); break; - case EOpConvBoolToFloat: - newConstArray[i].setDConst(unionArray[i].getBConst()); break; - case EOpConvBoolToDouble: - newConstArray[i].setDConst(unionArray[i].getBConst()); break; case EOpConvInt8ToInt16: newConstArray[i].setI16Const(unionArray[i].getI8Const()); break; @@ -810,8 +841,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) newConstArray[i].setU8Const((unsigned char)unionArray[i].getIConst()); break; case EOpConvIntToUint16: newConstArray[i].setU16Const((unsigned char)unionArray[i].getIConst()); break; - case EOpConvIntToUint: - newConstArray[i].setUConst(unionArray[i].getIConst()); break; case EOpConvIntToUint64: newConstArray[i].setU64Const(unionArray[i].getIConst()); break; @@ -819,8 +848,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) newConstArray[i].setI8Const((signed char)unionArray[i].getUConst()); break; case EOpConvUintToInt16: newConstArray[i].setI16Const((signed short)unionArray[i].getUConst()); break; - case EOpConvUintToInt: - newConstArray[i].setIConst(unionArray[i].getUConst()); break; case EOpConvUintToInt64: newConstArray[i].setI64Const(unionArray[i].getUConst()); break; case EOpConvUintToUint8: @@ -831,16 +858,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) newConstArray[i].setU64Const(unionArray[i].getUConst()); break; case EOpConvIntToFloat16: newConstArray[i].setDConst(unionArray[i].getIConst()); break; - case EOpConvIntToFloat: - newConstArray[i].setDConst(unionArray[i].getIConst()); break; - case EOpConvIntToDouble: - newConstArray[i].setDConst(unionArray[i].getIConst()); break; case EOpConvUintToFloat16: newConstArray[i].setDConst(unionArray[i].getUConst()); break; - case EOpConvUintToFloat: - newConstArray[i].setDConst(unionArray[i].getUConst()); break; - case EOpConvUintToDouble: - newConstArray[i].setDConst(unionArray[i].getUConst()); break; case EOpConvInt64ToInt8: newConstArray[i].setI8Const(static_cast(unionArray[i].getI64Const())); break; case EOpConvInt64ToInt16: @@ -905,44 +924,35 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) newConstArray[i].setI8Const(static_cast(unionArray[i].getDConst())); break; case EOpConvFloatToInt16: newConstArray[i].setI16Const(static_cast(unionArray[i].getDConst())); break; - case EOpConvFloatToInt: - newConstArray[i].setIConst(static_cast(unionArray[i].getDConst())); break; case EOpConvFloatToInt64: newConstArray[i].setI64Const(static_cast(unionArray[i].getDConst())); break; case EOpConvFloatToUint8: newConstArray[i].setU8Const(static_cast(unionArray[i].getDConst())); break; case EOpConvFloatToUint16: newConstArray[i].setU16Const(static_cast(unionArray[i].getDConst())); break; - case EOpConvFloatToUint: - newConstArray[i].setUConst(static_cast(unionArray[i].getDConst())); break; case EOpConvFloatToUint64: newConstArray[i].setU64Const(static_cast(unionArray[i].getDConst())); break; case EOpConvFloatToFloat16: newConstArray[i].setDConst(unionArray[i].getDConst()); break; - case EOpConvFloatToDouble: - newConstArray[i].setDConst(unionArray[i].getDConst()); break; case EOpConvDoubleToInt8: newConstArray[i].setI8Const(static_cast(unionArray[i].getDConst())); break; case EOpConvDoubleToInt16: newConstArray[i].setI16Const(static_cast(unionArray[i].getDConst())); break; - case EOpConvDoubleToInt: - newConstArray[i].setIConst(static_cast(unionArray[i].getDConst())); break; case EOpConvDoubleToInt64: newConstArray[i].setI64Const(static_cast(unionArray[i].getDConst())); break; case EOpConvDoubleToUint8: newConstArray[i].setU8Const(static_cast(unionArray[i].getDConst())); break; case EOpConvDoubleToUint16: newConstArray[i].setU16Const(static_cast(unionArray[i].getDConst())); break; - case EOpConvDoubleToUint: - newConstArray[i].setUConst(static_cast(unionArray[i].getDConst())); break; case EOpConvDoubleToUint64: newConstArray[i].setU64Const(static_cast(unionArray[i].getDConst())); break; case EOpConvDoubleToFloat16: newConstArray[i].setDConst(unionArray[i].getDConst()); break; - case EOpConvDoubleToFloat: - newConstArray[i].setDConst(unionArray[i].getDConst()); break; - - + case EOpConvPtrToUint64: + case EOpConvUint64ToPtr: + case EOpConstructReference: + newConstArray[i].setU64Const(unionArray[i].getU64Const()); break; +#endif // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out @@ -966,7 +976,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpInt16BitsToFloat16: case EOpUint16BitsToFloat16: default: - return 0; + return nullptr; } } @@ -1005,6 +1015,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EOpMin: case EOpMax: case EOpMix: + case EOpMod: case EOpClamp: case EOpLessThan: case EOpGreaterThan: @@ -1067,6 +1078,14 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EOpPow: newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); break; + case EOpMod: + { + double arg0 = childConstUnions[0][arg0comp].getDConst(); + double arg1 = childConstUnions[1][arg1comp].getDConst(); + double result = arg0 - arg1 * floor(arg0 / arg1); + newConstArray[comp].setDConst(result); + break; + } case EOpMin: switch(children[0]->getAsTyped()->getBasicType()) { case EbtFloat16: @@ -1074,6 +1093,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtDouble: newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); break; + case EbtInt: + newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); + break; + case EbtUint: + newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); + break; +#ifndef GLSLANG_WEB case EbtInt8: newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const())); break; @@ -1086,18 +1112,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtUint16: newConstArray[comp].setU16Const(std::min(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const())); break; - case EbtInt: - newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); - break; - case EbtUint: - newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); - break; case EbtInt64: newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const())); break; case EbtUint64: newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); break; +#endif default: assert(false && "Default missing"); } break; @@ -1108,6 +1129,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtDouble: newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); break; + case EbtInt: + newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); + break; + case EbtUint: + newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); + break; +#ifndef GLSLANG_WEB case EbtInt8: newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const())); break; @@ -1120,18 +1148,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtUint16: newConstArray[comp].setU16Const(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const())); break; - case EbtInt: - newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); - break; - case EbtUint: - newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); - break; case EbtInt64: newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const())); break; case EbtUint64: newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); break; +#endif default: assert(false && "Default missing"); } break; @@ -1143,6 +1166,11 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()), childConstUnions[2][arg2comp].getDConst())); break; + case EbtUint: + newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()), + childConstUnions[2][arg2comp].getUConst())); + break; +#ifndef GLSLANG_WEB case EbtInt8: newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()), childConstUnions[2][arg2comp].getI8Const())); @@ -1163,10 +1191,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()), childConstUnions[2][arg2comp].getIConst())); break; - case EbtUint: - newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()), - childConstUnions[2][arg2comp].getUConst())); - break; case EbtInt64: newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()), childConstUnions[2][arg2comp].getI64Const())); @@ -1175,6 +1199,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()), childConstUnions[2][arg2comp].getU64Const())); break; +#endif default: assert(false && "Default missing"); } break; @@ -1197,12 +1222,17 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[comp].setBConst(childConstUnions[0][arg0comp] != childConstUnions[1][arg1comp]); break; case EOpMix: - if (children[2]->getAsTyped()->getBasicType() == EbtBool) - newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst() ? childConstUnions[1][arg1comp].getDConst() : - childConstUnions[0][arg0comp].getDConst()); - else - newConstArray[comp].setDConst(childConstUnions[0][arg0comp].getDConst() * (1.0 - childConstUnions[2][arg2comp].getDConst()) + - childConstUnions[1][arg1comp].getDConst() * childConstUnions[2][arg2comp].getDConst()); + if (!children[0]->getAsTyped()->isFloatingDomain()) + return aggrNode; + if (children[2]->getAsTyped()->getBasicType() == EbtBool) { + newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst() + ? childConstUnions[1][arg1comp].getDConst() + : childConstUnions[0][arg0comp].getDConst()); + } else { + newConstArray[comp].setDConst( + childConstUnions[0][arg0comp].getDConst() * (1.0 - childConstUnions[2][arg2comp].getDConst()) + + childConstUnions[1][arg1comp].getDConst() * childConstUnions[2][arg2comp].getDConst()); + } break; case EOpStep: newConstArray[comp].setDConst(childConstUnions[1][arg1comp].getDConst() < childConstUnions[0][arg0comp].getDConst() ? 0.0 : 1.0); @@ -1354,7 +1384,9 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons // arrays, vectors, matrices, all use simple multiplicative math // while structures need to add up heterogeneous members int start; - if (node->isArray() || ! node->isStruct()) + if (node->getType().isCoopMat()) + start = 0; + else if (node->isArray() || ! node->isStruct()) start = size * index; else { // it is a structure diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Initialize.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Initialize.cpp index e399ead..823406c 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Initialize.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Initialize.cpp @@ -1,8 +1,9 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -64,9 +65,426 @@ const bool ForwardCompatibility = false; // Using PureOperatorBuiltins=false is deprecated. bool PureOperatorBuiltins = true; +namespace { + +// +// A set of definitions for tabling of the built-in functions. +// + +// Order matters here, as does correlation with the subsequent +// "const int ..." declarations and the ArgType enumerants. +const char* TypeString[] = { + "bool", "bvec2", "bvec3", "bvec4", + "float", "vec2", "vec3", "vec4", + "int", "ivec2", "ivec3", "ivec4", + "uint", "uvec2", "uvec3", "uvec4", +}; +const int TypeStringCount = sizeof(TypeString) / sizeof(char*); // number of entries in 'TypeString' +const int TypeStringRowShift = 2; // shift amount to go downe one row in 'TypeString' +const int TypeStringColumnMask = (1 << TypeStringRowShift) - 1; // reduce type to its column number in 'TypeString' +const int TypeStringScalarMask = ~TypeStringColumnMask; // take type to its scalar column in 'TypeString' + +enum ArgType { + // numbers hardcoded to correspond to 'TypeString'; order and value matter + TypeB = 1 << 0, // Boolean + TypeF = 1 << 1, // float 32 + TypeI = 1 << 2, // int 32 + TypeU = 1 << 3, // uint 32 + TypeF16 = 1 << 4, // float 16 + TypeF64 = 1 << 5, // float 64 + TypeI8 = 1 << 6, // int 8 + TypeI16 = 1 << 7, // int 16 + TypeI64 = 1 << 8, // int 64 + TypeU8 = 1 << 9, // uint 8 + TypeU16 = 1 << 10, // uint 16 + TypeU64 = 1 << 11, // uint 64 +}; +// Mixtures of the above, to help the function tables +const ArgType TypeFI = static_cast(TypeF | TypeI); +const ArgType TypeFIB = static_cast(TypeF | TypeI | TypeB); +const ArgType TypeIU = static_cast(TypeI | TypeU); + +// The relationships between arguments and return type, whether anything is +// output, or other unusual situations. +enum ArgClass { + ClassRegular = 0, // nothing special, just all vector widths with matching return type; traditional arithmetic + ClassLS = 1 << 0, // the last argument is also held fixed as a (type-matched) scalar while the others cycle + ClassXLS = 1 << 1, // the last argument is exclusively a (type-matched) scalar while the others cycle + ClassLS2 = 1 << 2, // the last two arguments are held fixed as a (type-matched) scalar while the others cycle + ClassFS = 1 << 3, // the first argument is held fixed as a (type-matched) scalar while the others cycle + ClassFS2 = 1 << 4, // the first two arguments are held fixed as a (type-matched) scalar while the others cycle + ClassLO = 1 << 5, // the last argument is an output + ClassB = 1 << 6, // return type cycles through only bool/bvec, matching vector width of args + ClassLB = 1 << 7, // last argument cycles through only bool/bvec, matching vector width of args + ClassV1 = 1 << 8, // scalar only + ClassFIO = 1 << 9, // first argument is inout + ClassRS = 1 << 10, // the return is held scalar as the arguments cycle + ClassNS = 1 << 11, // no scalar prototype + ClassCV = 1 << 12, // first argument is 'coherent volatile' + ClassFO = 1 << 13, // first argument is output + ClassV3 = 1 << 14, // vec3 only +}; +// Mixtures of the above, to help the function tables +const ArgClass ClassV1FIOCV = (ArgClass)(ClassV1 | ClassFIO | ClassCV); +const ArgClass ClassBNS = (ArgClass)(ClassB | ClassNS); +const ArgClass ClassRSNS = (ArgClass)(ClassRS | ClassNS); + +// A descriptor, for a single profile, of when something is available. +// If the current profile does not match 'profile' mask below, the other fields +// do not apply (nor validate). +// profiles == EBadProfile is the end of an array of these +struct Versioning { + EProfile profiles; // the profile(s) (mask) that the following fields are valid for + int minExtendedVersion; // earliest version when extensions are enabled; ignored if numExtensions is 0 + int minCoreVersion; // earliest version function is in core; 0 means never + int numExtensions; // how many extensions are in the 'extensions' list + const char** extensions; // list of extension names enabling the function +}; + +EProfile EDesktopProfile = static_cast(ENoProfile | ECoreProfile | ECompatibilityProfile); + +// Declare pointers to put into the table for versioning. +#ifdef GLSLANG_WEB + const Versioning* Es300Desktop130 = nullptr; + const Versioning* Es310Desktop420 = nullptr; +#elif defined(GLSLANG_ANGLE) + const Versioning* Es300Desktop130 = nullptr; + const Versioning* Es310Desktop420 = nullptr; + const Versioning* Es310Desktop450 = nullptr; +#else + const Versioning Es300Desktop130Version[] = { { EEsProfile, 0, 300, 0, nullptr }, + { EDesktopProfile, 0, 130, 0, nullptr }, + { EBadProfile } }; + const Versioning* Es300Desktop130 = &Es300Desktop130Version[0]; + + const Versioning Es310Desktop420Version[] = { { EEsProfile, 0, 310, 0, nullptr }, + { EDesktopProfile, 0, 420, 0, nullptr }, + { EBadProfile } }; + const Versioning* Es310Desktop420 = &Es310Desktop420Version[0]; + + const Versioning Es310Desktop450Version[] = { { EEsProfile, 0, 310, 0, nullptr }, + { EDesktopProfile, 0, 450, 0, nullptr }, + { EBadProfile } }; + const Versioning* Es310Desktop450 = &Es310Desktop450Version[0]; +#endif + +// The main descriptor of what a set of function prototypes can look like, and +// a pointer to extra versioning information, when needed. +struct BuiltInFunction { + TOperator op; // operator to map the name to + const char* name; // function name + int numArguments; // number of arguments (overloads with varying arguments need different entries) + ArgType types; // ArgType mask + ArgClass classes; // the ways this particular function entry manifests + const Versioning* versioning; // nullptr means always a valid version +}; + +// The tables can have the same built-in function name more than one time, +// but the exact same prototype must be indicated at most once. +// The prototypes that get declared are the union of all those indicated. +// This is important when different releases add new prototypes for the same name. +// It also also congnitively simpler tiling of the prototype space. +// In practice, most names can be fully represented with one entry. +// +// Table is terminated by an OpNull TOperator. + +const BuiltInFunction BaseFunctions[] = { +// TOperator, name, arg-count, ArgType, ArgClass, versioning +// --------- ---- --------- ------- -------- ---------- + { EOpRadians, "radians", 1, TypeF, ClassRegular, nullptr }, + { EOpDegrees, "degrees", 1, TypeF, ClassRegular, nullptr }, + { EOpSin, "sin", 1, TypeF, ClassRegular, nullptr }, + { EOpCos, "cos", 1, TypeF, ClassRegular, nullptr }, + { EOpTan, "tan", 1, TypeF, ClassRegular, nullptr }, + { EOpAsin, "asin", 1, TypeF, ClassRegular, nullptr }, + { EOpAcos, "acos", 1, TypeF, ClassRegular, nullptr }, + { EOpAtan, "atan", 2, TypeF, ClassRegular, nullptr }, + { EOpAtan, "atan", 1, TypeF, ClassRegular, nullptr }, + { EOpPow, "pow", 2, TypeF, ClassRegular, nullptr }, + { EOpExp, "exp", 1, TypeF, ClassRegular, nullptr }, + { EOpLog, "log", 1, TypeF, ClassRegular, nullptr }, + { EOpExp2, "exp2", 1, TypeF, ClassRegular, nullptr }, + { EOpLog2, "log2", 1, TypeF, ClassRegular, nullptr }, + { EOpSqrt, "sqrt", 1, TypeF, ClassRegular, nullptr }, + { EOpInverseSqrt, "inversesqrt", 1, TypeF, ClassRegular, nullptr }, + { EOpAbs, "abs", 1, TypeF, ClassRegular, nullptr }, + { EOpSign, "sign", 1, TypeF, ClassRegular, nullptr }, + { EOpFloor, "floor", 1, TypeF, ClassRegular, nullptr }, + { EOpCeil, "ceil", 1, TypeF, ClassRegular, nullptr }, + { EOpFract, "fract", 1, TypeF, ClassRegular, nullptr }, + { EOpMod, "mod", 2, TypeF, ClassLS, nullptr }, + { EOpMin, "min", 2, TypeF, ClassLS, nullptr }, + { EOpMax, "max", 2, TypeF, ClassLS, nullptr }, + { EOpClamp, "clamp", 3, TypeF, ClassLS2, nullptr }, + { EOpMix, "mix", 3, TypeF, ClassLS, nullptr }, + { EOpStep, "step", 2, TypeF, ClassFS, nullptr }, + { EOpSmoothStep, "smoothstep", 3, TypeF, ClassFS2, nullptr }, + { EOpNormalize, "normalize", 1, TypeF, ClassRegular, nullptr }, + { EOpFaceForward, "faceforward", 3, TypeF, ClassRegular, nullptr }, + { EOpReflect, "reflect", 2, TypeF, ClassRegular, nullptr }, + { EOpRefract, "refract", 3, TypeF, ClassXLS, nullptr }, + { EOpLength, "length", 1, TypeF, ClassRS, nullptr }, + { EOpDistance, "distance", 2, TypeF, ClassRS, nullptr }, + { EOpDot, "dot", 2, TypeF, ClassRS, nullptr }, + { EOpCross, "cross", 2, TypeF, ClassV3, nullptr }, + { EOpLessThan, "lessThan", 2, TypeFI, ClassBNS, nullptr }, + { EOpLessThanEqual, "lessThanEqual", 2, TypeFI, ClassBNS, nullptr }, + { EOpGreaterThan, "greaterThan", 2, TypeFI, ClassBNS, nullptr }, + { EOpGreaterThanEqual, "greaterThanEqual", 2, TypeFI, ClassBNS, nullptr }, + { EOpVectorEqual, "equal", 2, TypeFIB, ClassBNS, nullptr }, + { EOpVectorNotEqual, "notEqual", 2, TypeFIB, ClassBNS, nullptr }, + { EOpAny, "any", 1, TypeB, ClassRSNS, nullptr }, + { EOpAll, "all", 1, TypeB, ClassRSNS, nullptr }, + { EOpVectorLogicalNot, "not", 1, TypeB, ClassNS, nullptr }, + { EOpSinh, "sinh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpCosh, "cosh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpTanh, "tanh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpAsinh, "asinh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpAcosh, "acosh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpAtanh, "atanh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpAbs, "abs", 1, TypeI, ClassRegular, Es300Desktop130 }, + { EOpSign, "sign", 1, TypeI, ClassRegular, Es300Desktop130 }, + { EOpTrunc, "trunc", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpRound, "round", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpRoundEven, "roundEven", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpModf, "modf", 2, TypeF, ClassLO, Es300Desktop130 }, + { EOpMin, "min", 2, TypeIU, ClassLS, Es300Desktop130 }, + { EOpMax, "max", 2, TypeIU, ClassLS, Es300Desktop130 }, + { EOpClamp, "clamp", 3, TypeIU, ClassLS2, Es300Desktop130 }, + { EOpMix, "mix", 3, TypeF, ClassLB, Es300Desktop130 }, + { EOpIsInf, "isinf", 1, TypeF, ClassB, Es300Desktop130 }, + { EOpIsNan, "isnan", 1, TypeF, ClassB, Es300Desktop130 }, + { EOpLessThan, "lessThan", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpLessThanEqual, "lessThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpGreaterThan, "greaterThan", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpVectorEqual, "equal", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop420 }, +#ifndef GLSLANG_WEB + { EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 }, + { EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 }, +#endif + + { EOpNull } +}; + +const BuiltInFunction DerivativeFunctions[] = { + { EOpDPdx, "dFdx", 1, TypeF, ClassRegular, nullptr }, + { EOpDPdy, "dFdy", 1, TypeF, ClassRegular, nullptr }, + { EOpFwidth, "fwidth", 1, TypeF, ClassRegular, nullptr }, + { EOpNull } +}; + +// For functions declared some other way, but still use the table to relate to operator. +struct CustomFunction { + TOperator op; // operator to map the name to + const char* name; // function name + const Versioning* versioning; // nullptr means always a valid version +}; + +const CustomFunction CustomFunctions[] = { + { EOpBarrier, "barrier", nullptr }, + { EOpMemoryBarrierShared, "memoryBarrierShared", nullptr }, + { EOpGroupMemoryBarrier, "groupMemoryBarrier", nullptr }, + { EOpMemoryBarrier, "memoryBarrier", nullptr }, + { EOpMemoryBarrierBuffer, "memoryBarrierBuffer", nullptr }, + + { EOpPackSnorm2x16, "packSnorm2x16", nullptr }, + { EOpUnpackSnorm2x16, "unpackSnorm2x16", nullptr }, + { EOpPackUnorm2x16, "packUnorm2x16", nullptr }, + { EOpUnpackUnorm2x16, "unpackUnorm2x16", nullptr }, + { EOpPackHalf2x16, "packHalf2x16", nullptr }, + { EOpUnpackHalf2x16, "unpackHalf2x16", nullptr }, + + { EOpMul, "matrixCompMult", nullptr }, + { EOpOuterProduct, "outerProduct", nullptr }, + { EOpTranspose, "transpose", nullptr }, + { EOpDeterminant, "determinant", nullptr }, + { EOpMatrixInverse, "inverse", nullptr }, + { EOpFloatBitsToInt, "floatBitsToInt", nullptr }, + { EOpFloatBitsToUint, "floatBitsToUint", nullptr }, + { EOpIntBitsToFloat, "intBitsToFloat", nullptr }, + { EOpUintBitsToFloat, "uintBitsToFloat", nullptr }, + + { EOpTextureQuerySize, "textureSize", nullptr }, + { EOpTextureQueryLod, "textureQueryLod", nullptr }, + { EOpTextureQueryLevels, "textureQueryLevels", nullptr }, + { EOpTextureQuerySamples, "textureSamples", nullptr }, + { EOpTexture, "texture", nullptr }, + { EOpTextureProj, "textureProj", nullptr }, + { EOpTextureLod, "textureLod", nullptr }, + { EOpTextureOffset, "textureOffset", nullptr }, + { EOpTextureFetch, "texelFetch", nullptr }, + { EOpTextureFetchOffset, "texelFetchOffset", nullptr }, + { EOpTextureProjOffset, "textureProjOffset", nullptr }, + { EOpTextureLodOffset, "textureLodOffset", nullptr }, + { EOpTextureProjLod, "textureProjLod", nullptr }, + { EOpTextureProjLodOffset, "textureProjLodOffset", nullptr }, + { EOpTextureGrad, "textureGrad", nullptr }, + { EOpTextureGradOffset, "textureGradOffset", nullptr }, + { EOpTextureProjGrad, "textureProjGrad", nullptr }, + { EOpTextureProjGradOffset, "textureProjGradOffset", nullptr }, + + { EOpNull } +}; + +// For the given table of functions, add all the indicated prototypes for each +// one, to be returned in the passed in decls. +void AddTabledBuiltin(TString& decls, const BuiltInFunction& function) +{ + const auto isScalarType = [](int type) { return (type & TypeStringColumnMask) == 0; }; + + // loop across these two: + // 0: the varying arg set, and + // 1: the fixed scalar args + const ArgClass ClassFixed = (ArgClass)(ClassLS | ClassXLS | ClassLS2 | ClassFS | ClassFS2); + for (int fixed = 0; fixed < ((function.classes & ClassFixed) > 0 ? 2 : 1); ++fixed) { + + if (fixed == 0 && (function.classes & ClassXLS)) + continue; + + // walk the type strings in TypeString[] + for (int type = 0; type < TypeStringCount; ++type) { + // skip types not selected: go from type to row number to type bit + if ((function.types & (1 << (type >> TypeStringRowShift))) == 0) + continue; + + // if we aren't on a scalar, and should be, skip + if ((function.classes & ClassV1) && !isScalarType(type)) + continue; + + // if we aren't on a 3-vector, and should be, skip + if ((function.classes & ClassV3) && (type & TypeStringColumnMask) != 2) + continue; + + // skip replication of all arg scalars between the varying arg set and the fixed args + if (fixed == 1 && type == (type & TypeStringScalarMask) && (function.classes & ClassXLS) == 0) + continue; + + // skip scalars when we are told to + if ((function.classes & ClassNS) && isScalarType(type)) + continue; + + // return type + if (function.classes & ClassB) + decls.append(TypeString[type & TypeStringColumnMask]); + else if (function.classes & ClassRS) + decls.append(TypeString[type & TypeStringScalarMask]); + else + decls.append(TypeString[type]); + decls.append(" "); + decls.append(function.name); + decls.append("("); + + // arguments + for (int arg = 0; arg < function.numArguments; ++arg) { + if (arg == function.numArguments - 1 && (function.classes & ClassLO)) + decls.append("out "); + if (arg == 0) { +#ifndef GLSLANG_WEB + if (function.classes & ClassCV) + decls.append("coherent volatile "); +#endif + if (function.classes & ClassFIO) + decls.append("inout "); + if (function.classes & ClassFO) + decls.append("out "); + } + if ((function.classes & ClassLB) && arg == function.numArguments - 1) + decls.append(TypeString[type & TypeStringColumnMask]); + else if (fixed && ((arg == function.numArguments - 1 && (function.classes & (ClassLS | ClassXLS | + ClassLS2))) || + (arg == function.numArguments - 2 && (function.classes & ClassLS2)) || + (arg == 0 && (function.classes & (ClassFS | ClassFS2))) || + (arg == 1 && (function.classes & ClassFS2)))) + decls.append(TypeString[type & TypeStringScalarMask]); + else + decls.append(TypeString[type]); + if (arg < function.numArguments - 1) + decls.append(","); + } + decls.append(");\n"); + } + } +} + +// See if the tabled versioning information allows the current version. +bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile, const SpvVersion& /* spVersion */) +{ +#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) + // all entries in table are valid + return true; +#endif + + // nullptr means always valid + if (function.versioning == nullptr) + return true; + + // check for what is said about our current profile + for (const Versioning* v = function.versioning; v->profiles != EBadProfile; ++v) { + if ((v->profiles & profile) != 0) { + if (v->minCoreVersion <= version || (v->numExtensions > 0 && v->minExtendedVersion <= version)) + return true; + } + } + + return false; +} + +// Relate a single table of built-ins to their AST operator. +// This can get called redundantly (especially for the common built-ins, when +// called once per stage). This is a performance issue only, not a correctness +// concern. It is done for quality arising from simplicity, as there are subtleties +// to get correct if instead trying to do it surgically. +template +void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable) +{ + while (functions->op != EOpNull) { + symbolTable.relateToOperator(functions->name, functions->op); + ++functions; + } +} + +} // end anonymous namespace + +// Add declarations for all tables of built-in functions. +void TBuiltIns::addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion) +{ + const auto forEachFunction = [&](TString& decls, const BuiltInFunction* function) { + while (function->op != EOpNull) { + if (ValidVersion(*function, version, profile, spvVersion)) + AddTabledBuiltin(decls, *function); + ++function; + } + }; + + forEachFunction(commonBuiltins, BaseFunctions); + forEachFunction(stageBuiltins[EShLangFragment], DerivativeFunctions); + + if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450)) + forEachFunction(stageBuiltins[EShLangCompute], DerivativeFunctions); +} + +// Relate all tables of built-ins to the AST operators. +void TBuiltIns::relateTabledBuiltins(int /* version */, EProfile /* profile */, const SpvVersion& /* spvVersion */, EShLanguage /* stage */, TSymbolTable& symbolTable) +{ + RelateTabledBuiltins(BaseFunctions, symbolTable); + RelateTabledBuiltins(DerivativeFunctions, symbolTable); + RelateTabledBuiltins(CustomFunctions, symbolTable); +} + inline bool IncludeLegacy(int version, EProfile profile, const SpvVersion& spvVersion) { - return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && ARBCompatibility) || profile == ECompatibilityProfile); + return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && version == 140 && ARBCompatibility) || + profile == ECompatibilityProfile); } // Construct TBuiltInParseables base class. This can be used for language-common constructs. @@ -84,27 +502,34 @@ TBuiltIns::TBuiltIns() // Set up textual representations for making all the permutations // of texturing/imaging functions. prefixes[EbtFloat] = ""; -#ifdef AMD_EXTENSIONS + prefixes[EbtInt] = "i"; + prefixes[EbtUint] = "u"; +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) prefixes[EbtFloat16] = "f16"; -#endif prefixes[EbtInt8] = "i8"; prefixes[EbtUint8] = "u8"; prefixes[EbtInt16] = "i16"; prefixes[EbtUint16] = "u16"; - prefixes[EbtInt] = "i"; - prefixes[EbtUint] = "u"; + prefixes[EbtInt64] = "i64"; + prefixes[EbtUint64] = "u64"; +#endif + postfixes[2] = "2"; postfixes[3] = "3"; postfixes[4] = "4"; // Map from symbolic class of texturing dimension to numeric dimensions. - dimMap[Esd1D] = 1; dimMap[Esd2D] = 2; - dimMap[EsdRect] = 2; dimMap[Esd3D] = 3; dimMap[EsdCube] = 3; +#ifndef GLSLANG_WEB +#ifndef GLSLANG_ANGLE + dimMap[Esd1D] = 1; +#endif + dimMap[EsdRect] = 2; dimMap[EsdBuffer] = 1; - dimMap[EsdSubpass] = 2; // potientially unused for now + dimMap[EsdSubpass] = 2; // potentially unused for now +#endif } TBuiltIns::~TBuiltIns() @@ -122,32 +547,25 @@ TBuiltIns::~TBuiltIns() // void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvVersion) { +#ifdef GLSLANG_WEB + version = 310; + profile = EEsProfile; +#elif defined(GLSLANG_ANGLE) + version = 450; + profile = ECoreProfile; +#endif + addTabledBuiltins(version, profile, spvVersion); + //============================================================================ // // Prototypes for built-in functions used repeatly by different shaders // //============================================================================ +#ifndef GLSLANG_WEB // // Derivatives Functions. // - TString derivatives ( - "float dFdx(float p);" - "vec2 dFdx(vec2 p);" - "vec3 dFdx(vec3 p);" - "vec4 dFdx(vec4 p);" - - "float dFdy(float p);" - "vec2 dFdy(vec2 p);" - "vec3 dFdy(vec3 p);" - "vec4 dFdy(vec4 p);" - - "float fwidth(float p);" - "vec2 fwidth(vec2 p);" - "vec3 fwidth(vec3 p);" - "vec4 fwidth(vec4 p);" - ); - TString derivativeControls ( "float dFdxFine(float p);" "vec2 dFdxFine(vec2 p);" @@ -180,6 +598,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 fwidthCoarse(vec4 p);" ); +#ifndef GLSLANG_ANGLE TString derivativesAndControl16bits ( "float16_t dFdx(float16_t);" "f16vec2 dFdx(f16vec2);" @@ -280,322 +699,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV // //============================================================================ - // - // Angle and Trigonometric Functions. - // - commonBuiltins.append( - "float radians(float degrees);" - "vec2 radians(vec2 degrees);" - "vec3 radians(vec3 degrees);" - "vec4 radians(vec4 degrees);" - - "float degrees(float radians);" - "vec2 degrees(vec2 radians);" - "vec3 degrees(vec3 radians);" - "vec4 degrees(vec4 radians);" - - "float sin(float angle);" - "vec2 sin(vec2 angle);" - "vec3 sin(vec3 angle);" - "vec4 sin(vec4 angle);" - - "float cos(float angle);" - "vec2 cos(vec2 angle);" - "vec3 cos(vec3 angle);" - "vec4 cos(vec4 angle);" - - "float tan(float angle);" - "vec2 tan(vec2 angle);" - "vec3 tan(vec3 angle);" - "vec4 tan(vec4 angle);" - - "float asin(float x);" - "vec2 asin(vec2 x);" - "vec3 asin(vec3 x);" - "vec4 asin(vec4 x);" - - "float acos(float x);" - "vec2 acos(vec2 x);" - "vec3 acos(vec3 x);" - "vec4 acos(vec4 x);" - - "float atan(float y, float x);" - "vec2 atan(vec2 y, vec2 x);" - "vec3 atan(vec3 y, vec3 x);" - "vec4 atan(vec4 y, vec4 x);" - - "float atan(float y_over_x);" - "vec2 atan(vec2 y_over_x);" - "vec3 atan(vec3 y_over_x);" - "vec4 atan(vec4 y_over_x);" - - "\n"); - - if (version >= 130) { - commonBuiltins.append( - "float sinh(float angle);" - "vec2 sinh(vec2 angle);" - "vec3 sinh(vec3 angle);" - "vec4 sinh(vec4 angle);" - - "float cosh(float angle);" - "vec2 cosh(vec2 angle);" - "vec3 cosh(vec3 angle);" - "vec4 cosh(vec4 angle);" - - "float tanh(float angle);" - "vec2 tanh(vec2 angle);" - "vec3 tanh(vec3 angle);" - "vec4 tanh(vec4 angle);" - - "float asinh(float x);" - "vec2 asinh(vec2 x);" - "vec3 asinh(vec3 x);" - "vec4 asinh(vec4 x);" - - "float acosh(float x);" - "vec2 acosh(vec2 x);" - "vec3 acosh(vec3 x);" - "vec4 acosh(vec4 x);" - - "float atanh(float y_over_x);" - "vec2 atanh(vec2 y_over_x);" - "vec3 atanh(vec3 y_over_x);" - "vec4 atanh(vec4 y_over_x);" - - "\n"); - } - - // - // Exponential Functions. - // - commonBuiltins.append( - "float pow(float x, float y);" - "vec2 pow(vec2 x, vec2 y);" - "vec3 pow(vec3 x, vec3 y);" - "vec4 pow(vec4 x, vec4 y);" - - "float exp(float x);" - "vec2 exp(vec2 x);" - "vec3 exp(vec3 x);" - "vec4 exp(vec4 x);" - - "float log(float x);" - "vec2 log(vec2 x);" - "vec3 log(vec3 x);" - "vec4 log(vec4 x);" - - "float exp2(float x);" - "vec2 exp2(vec2 x);" - "vec3 exp2(vec3 x);" - "vec4 exp2(vec4 x);" - - "float log2(float x);" - "vec2 log2(vec2 x);" - "vec3 log2(vec3 x);" - "vec4 log2(vec4 x);" - - "float sqrt(float x);" - "vec2 sqrt(vec2 x);" - "vec3 sqrt(vec3 x);" - "vec4 sqrt(vec4 x);" - - "float inversesqrt(float x);" - "vec2 inversesqrt(vec2 x);" - "vec3 inversesqrt(vec3 x);" - "vec4 inversesqrt(vec4 x);" - - "\n"); - - // - // Common Functions. - // - commonBuiltins.append( - "float abs(float x);" - "vec2 abs(vec2 x);" - "vec3 abs(vec3 x);" - "vec4 abs(vec4 x);" - - "float sign(float x);" - "vec2 sign(vec2 x);" - "vec3 sign(vec3 x);" - "vec4 sign(vec4 x);" - - "float floor(float x);" - "vec2 floor(vec2 x);" - "vec3 floor(vec3 x);" - "vec4 floor(vec4 x);" - - "float ceil(float x);" - "vec2 ceil(vec2 x);" - "vec3 ceil(vec3 x);" - "vec4 ceil(vec4 x);" - - "float fract(float x);" - "vec2 fract(vec2 x);" - "vec3 fract(vec3 x);" - "vec4 fract(vec4 x);" - - "float mod(float x, float y);" - "vec2 mod(vec2 x, float y);" - "vec3 mod(vec3 x, float y);" - "vec4 mod(vec4 x, float y);" - "vec2 mod(vec2 x, vec2 y);" - "vec3 mod(vec3 x, vec3 y);" - "vec4 mod(vec4 x, vec4 y);" - - "float min(float x, float y);" - "vec2 min(vec2 x, float y);" - "vec3 min(vec3 x, float y);" - "vec4 min(vec4 x, float y);" - "vec2 min(vec2 x, vec2 y);" - "vec3 min(vec3 x, vec3 y);" - "vec4 min(vec4 x, vec4 y);" - - "float max(float x, float y);" - "vec2 max(vec2 x, float y);" - "vec3 max(vec3 x, float y);" - "vec4 max(vec4 x, float y);" - "vec2 max(vec2 x, vec2 y);" - "vec3 max(vec3 x, vec3 y);" - "vec4 max(vec4 x, vec4 y);" - - "float clamp(float x, float minVal, float maxVal);" - "vec2 clamp(vec2 x, float minVal, float maxVal);" - "vec3 clamp(vec3 x, float minVal, float maxVal);" - "vec4 clamp(vec4 x, float minVal, float maxVal);" - "vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);" - "vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);" - "vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);" - - "float mix(float x, float y, float a);" - "vec2 mix(vec2 x, vec2 y, float a);" - "vec3 mix(vec3 x, vec3 y, float a);" - "vec4 mix(vec4 x, vec4 y, float a);" - "vec2 mix(vec2 x, vec2 y, vec2 a);" - "vec3 mix(vec3 x, vec3 y, vec3 a);" - "vec4 mix(vec4 x, vec4 y, vec4 a);" - - "float step(float edge, float x);" - "vec2 step(vec2 edge, vec2 x);" - "vec3 step(vec3 edge, vec3 x);" - "vec4 step(vec4 edge, vec4 x);" - "vec2 step(float edge, vec2 x);" - "vec3 step(float edge, vec3 x);" - "vec4 step(float edge, vec4 x);" - - "float smoothstep(float edge0, float edge1, float x);" - "vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);" - "vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);" - "vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);" - "vec2 smoothstep(float edge0, float edge1, vec2 x);" - "vec3 smoothstep(float edge0, float edge1, vec3 x);" - "vec4 smoothstep(float edge0, float edge1, vec4 x);" - - "\n"); - - if (version >= 130) { - commonBuiltins.append( - " int abs( int x);" - "ivec2 abs(ivec2 x);" - "ivec3 abs(ivec3 x);" - "ivec4 abs(ivec4 x);" - - " int sign( int x);" - "ivec2 sign(ivec2 x);" - "ivec3 sign(ivec3 x);" - "ivec4 sign(ivec4 x);" - - "float trunc(float x);" - "vec2 trunc(vec2 x);" - "vec3 trunc(vec3 x);" - "vec4 trunc(vec4 x);" - - "float round(float x);" - "vec2 round(vec2 x);" - "vec3 round(vec3 x);" - "vec4 round(vec4 x);" - - "float roundEven(float x);" - "vec2 roundEven(vec2 x);" - "vec3 roundEven(vec3 x);" - "vec4 roundEven(vec4 x);" - - "float modf(float, out float);" - "vec2 modf(vec2, out vec2 );" - "vec3 modf(vec3, out vec3 );" - "vec4 modf(vec4, out vec4 );" - - " int min(int x, int y);" - "ivec2 min(ivec2 x, int y);" - "ivec3 min(ivec3 x, int y);" - "ivec4 min(ivec4 x, int y);" - "ivec2 min(ivec2 x, ivec2 y);" - "ivec3 min(ivec3 x, ivec3 y);" - "ivec4 min(ivec4 x, ivec4 y);" - - " uint min(uint x, uint y);" - "uvec2 min(uvec2 x, uint y);" - "uvec3 min(uvec3 x, uint y);" - "uvec4 min(uvec4 x, uint y);" - "uvec2 min(uvec2 x, uvec2 y);" - "uvec3 min(uvec3 x, uvec3 y);" - "uvec4 min(uvec4 x, uvec4 y);" - - " int max(int x, int y);" - "ivec2 max(ivec2 x, int y);" - "ivec3 max(ivec3 x, int y);" - "ivec4 max(ivec4 x, int y);" - "ivec2 max(ivec2 x, ivec2 y);" - "ivec3 max(ivec3 x, ivec3 y);" - "ivec4 max(ivec4 x, ivec4 y);" - - " uint max(uint x, uint y);" - "uvec2 max(uvec2 x, uint y);" - "uvec3 max(uvec3 x, uint y);" - "uvec4 max(uvec4 x, uint y);" - "uvec2 max(uvec2 x, uvec2 y);" - "uvec3 max(uvec3 x, uvec3 y);" - "uvec4 max(uvec4 x, uvec4 y);" - - "int clamp(int x, int minVal, int maxVal);" - "ivec2 clamp(ivec2 x, int minVal, int maxVal);" - "ivec3 clamp(ivec3 x, int minVal, int maxVal);" - "ivec4 clamp(ivec4 x, int minVal, int maxVal);" - "ivec2 clamp(ivec2 x, ivec2 minVal, ivec2 maxVal);" - "ivec3 clamp(ivec3 x, ivec3 minVal, ivec3 maxVal);" - "ivec4 clamp(ivec4 x, ivec4 minVal, ivec4 maxVal);" - - "uint clamp(uint x, uint minVal, uint maxVal);" - "uvec2 clamp(uvec2 x, uint minVal, uint maxVal);" - "uvec3 clamp(uvec3 x, uint minVal, uint maxVal);" - "uvec4 clamp(uvec4 x, uint minVal, uint maxVal);" - "uvec2 clamp(uvec2 x, uvec2 minVal, uvec2 maxVal);" - "uvec3 clamp(uvec3 x, uvec3 minVal, uvec3 maxVal);" - "uvec4 clamp(uvec4 x, uvec4 minVal, uvec4 maxVal);" - - "float mix(float x, float y, bool a);" - "vec2 mix(vec2 x, vec2 y, bvec2 a);" - "vec3 mix(vec3 x, vec3 y, bvec3 a);" - "vec4 mix(vec4 x, vec4 y, bvec4 a);" - - "bool isnan(float x);" - "bvec2 isnan(vec2 x);" - "bvec3 isnan(vec3 x);" - "bvec4 isnan(vec4 x);" - - "bool isinf(float x);" - "bvec2 isinf(vec2 x);" - "bvec3 isinf(vec3 x);" - "bvec4 isinf(vec4 x);" - - "\n"); - } - // // double functions added to desktop 4.00, but not fma, frexp, ldexp, or pack/unpack // - if (profile != EEsProfile && version >= 400) { + if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double sqrt(double);" @@ -825,7 +932,203 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } - if (profile != EEsProfile && version >= 450) { + if (profile == EEsProfile && version >= 310) { // Explicit Types + commonBuiltins.append( + + "float64_t sqrt(float64_t);" + "f64vec2 sqrt(f64vec2);" + "f64vec3 sqrt(f64vec3);" + "f64vec4 sqrt(f64vec4);" + + "float64_t inversesqrt(float64_t);" + "f64vec2 inversesqrt(f64vec2);" + "f64vec3 inversesqrt(f64vec3);" + "f64vec4 inversesqrt(f64vec4);" + + "float64_t abs(float64_t);" + "f64vec2 abs(f64vec2);" + "f64vec3 abs(f64vec3);" + "f64vec4 abs(f64vec4);" + + "float64_t sign(float64_t);" + "f64vec2 sign(f64vec2);" + "f64vec3 sign(f64vec3);" + "f64vec4 sign(f64vec4);" + + "float64_t floor(float64_t);" + "f64vec2 floor(f64vec2);" + "f64vec3 floor(f64vec3);" + "f64vec4 floor(f64vec4);" + + "float64_t trunc(float64_t);" + "f64vec2 trunc(f64vec2);" + "f64vec3 trunc(f64vec3);" + "f64vec4 trunc(f64vec4);" + + "float64_t round(float64_t);" + "f64vec2 round(f64vec2);" + "f64vec3 round(f64vec3);" + "f64vec4 round(f64vec4);" + + "float64_t roundEven(float64_t);" + "f64vec2 roundEven(f64vec2);" + "f64vec3 roundEven(f64vec3);" + "f64vec4 roundEven(f64vec4);" + + "float64_t ceil(float64_t);" + "f64vec2 ceil(f64vec2);" + "f64vec3 ceil(f64vec3);" + "f64vec4 ceil(f64vec4);" + + "float64_t fract(float64_t);" + "f64vec2 fract(f64vec2);" + "f64vec3 fract(f64vec3);" + "f64vec4 fract(f64vec4);" + + "float64_t mod(float64_t, float64_t);" + "f64vec2 mod(f64vec2 , float64_t);" + "f64vec3 mod(f64vec3 , float64_t);" + "f64vec4 mod(f64vec4 , float64_t);" + "f64vec2 mod(f64vec2 , f64vec2);" + "f64vec3 mod(f64vec3 , f64vec3);" + "f64vec4 mod(f64vec4 , f64vec4);" + + "float64_t modf(float64_t, out float64_t);" + "f64vec2 modf(f64vec2, out f64vec2);" + "f64vec3 modf(f64vec3, out f64vec3);" + "f64vec4 modf(f64vec4, out f64vec4);" + + "float64_t min(float64_t, float64_t);" + "f64vec2 min(f64vec2, float64_t);" + "f64vec3 min(f64vec3, float64_t);" + "f64vec4 min(f64vec4, float64_t);" + "f64vec2 min(f64vec2, f64vec2);" + "f64vec3 min(f64vec3, f64vec3);" + "f64vec4 min(f64vec4, f64vec4);" + + "float64_t max(float64_t, float64_t);" + "f64vec2 max(f64vec2 , float64_t);" + "f64vec3 max(f64vec3 , float64_t);" + "f64vec4 max(f64vec4 , float64_t);" + "f64vec2 max(f64vec2 , f64vec2);" + "f64vec3 max(f64vec3 , f64vec3);" + "f64vec4 max(f64vec4 , f64vec4);" + + "float64_t clamp(float64_t, float64_t, float64_t);" + "f64vec2 clamp(f64vec2 , float64_t, float64_t);" + "f64vec3 clamp(f64vec3 , float64_t, float64_t);" + "f64vec4 clamp(f64vec4 , float64_t, float64_t);" + "f64vec2 clamp(f64vec2 , f64vec2 , f64vec2);" + "f64vec3 clamp(f64vec3 , f64vec3 , f64vec3);" + "f64vec4 clamp(f64vec4 , f64vec4 , f64vec4);" + + "float64_t mix(float64_t, float64_t, float64_t);" + "f64vec2 mix(f64vec2, f64vec2, float64_t);" + "f64vec3 mix(f64vec3, f64vec3, float64_t);" + "f64vec4 mix(f64vec4, f64vec4, float64_t);" + "f64vec2 mix(f64vec2, f64vec2, f64vec2);" + "f64vec3 mix(f64vec3, f64vec3, f64vec3);" + "f64vec4 mix(f64vec4, f64vec4, f64vec4);" + "float64_t mix(float64_t, float64_t, bool);" + "f64vec2 mix(f64vec2, f64vec2, bvec2);" + "f64vec3 mix(f64vec3, f64vec3, bvec3);" + "f64vec4 mix(f64vec4, f64vec4, bvec4);" + + "float64_t step(float64_t, float64_t);" + "f64vec2 step(f64vec2 , f64vec2);" + "f64vec3 step(f64vec3 , f64vec3);" + "f64vec4 step(f64vec4 , f64vec4);" + "f64vec2 step(float64_t, f64vec2);" + "f64vec3 step(float64_t, f64vec3);" + "f64vec4 step(float64_t, f64vec4);" + + "float64_t smoothstep(float64_t, float64_t, float64_t);" + "f64vec2 smoothstep(f64vec2 , f64vec2 , f64vec2);" + "f64vec3 smoothstep(f64vec3 , f64vec3 , f64vec3);" + "f64vec4 smoothstep(f64vec4 , f64vec4 , f64vec4);" + "f64vec2 smoothstep(float64_t, float64_t, f64vec2);" + "f64vec3 smoothstep(float64_t, float64_t, f64vec3);" + "f64vec4 smoothstep(float64_t, float64_t, f64vec4);" + + "float64_t length(float64_t);" + "float64_t length(f64vec2);" + "float64_t length(f64vec3);" + "float64_t length(f64vec4);" + + "float64_t distance(float64_t, float64_t);" + "float64_t distance(f64vec2 , f64vec2);" + "float64_t distance(f64vec3 , f64vec3);" + "float64_t distance(f64vec4 , f64vec4);" + + "float64_t dot(float64_t, float64_t);" + "float64_t dot(f64vec2 , f64vec2);" + "float64_t dot(f64vec3 , f64vec3);" + "float64_t dot(f64vec4 , f64vec4);" + + "f64vec3 cross(f64vec3, f64vec3);" + + "float64_t normalize(float64_t);" + "f64vec2 normalize(f64vec2);" + "f64vec3 normalize(f64vec3);" + "f64vec4 normalize(f64vec4);" + + "float64_t faceforward(float64_t, float64_t, float64_t);" + "f64vec2 faceforward(f64vec2, f64vec2, f64vec2);" + "f64vec3 faceforward(f64vec3, f64vec3, f64vec3);" + "f64vec4 faceforward(f64vec4, f64vec4, f64vec4);" + + "float64_t reflect(float64_t, float64_t);" + "f64vec2 reflect(f64vec2 , f64vec2 );" + "f64vec3 reflect(f64vec3 , f64vec3 );" + "f64vec4 reflect(f64vec4 , f64vec4 );" + + "float64_t refract(float64_t, float64_t, float64_t);" + "f64vec2 refract(f64vec2 , f64vec2 , float64_t);" + "f64vec3 refract(f64vec3 , f64vec3 , float64_t);" + "f64vec4 refract(f64vec4 , f64vec4 , float64_t);" + + "f64mat2 matrixCompMult(f64mat2, f64mat2);" + "f64mat3 matrixCompMult(f64mat3, f64mat3);" + "f64mat4 matrixCompMult(f64mat4, f64mat4);" + "f64mat2x3 matrixCompMult(f64mat2x3, f64mat2x3);" + "f64mat2x4 matrixCompMult(f64mat2x4, f64mat2x4);" + "f64mat3x2 matrixCompMult(f64mat3x2, f64mat3x2);" + "f64mat3x4 matrixCompMult(f64mat3x4, f64mat3x4);" + "f64mat4x2 matrixCompMult(f64mat4x2, f64mat4x2);" + "f64mat4x3 matrixCompMult(f64mat4x3, f64mat4x3);" + + "f64mat2 outerProduct(f64vec2, f64vec2);" + "f64mat3 outerProduct(f64vec3, f64vec3);" + "f64mat4 outerProduct(f64vec4, f64vec4);" + "f64mat2x3 outerProduct(f64vec3, f64vec2);" + "f64mat3x2 outerProduct(f64vec2, f64vec3);" + "f64mat2x4 outerProduct(f64vec4, f64vec2);" + "f64mat4x2 outerProduct(f64vec2, f64vec4);" + "f64mat3x4 outerProduct(f64vec4, f64vec3);" + "f64mat4x3 outerProduct(f64vec3, f64vec4);" + + "f64mat2 transpose(f64mat2);" + "f64mat3 transpose(f64mat3);" + "f64mat4 transpose(f64mat4);" + "f64mat2x3 transpose(f64mat3x2);" + "f64mat3x2 transpose(f64mat2x3);" + "f64mat2x4 transpose(f64mat4x2);" + "f64mat4x2 transpose(f64mat2x4);" + "f64mat3x4 transpose(f64mat4x3);" + "f64mat4x3 transpose(f64mat3x4);" + + "float64_t determinant(f64mat2);" + "float64_t determinant(f64mat3);" + "float64_t determinant(f64mat4);" + + "f64mat2 inverse(f64mat2);" + "f64mat3 inverse(f64mat3);" + "f64mat4 inverse(f64mat4);" + + "\n"); + } + + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) { commonBuiltins.append( "int64_t abs(int64_t);" @@ -892,25 +1195,25 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "u64vec3 mix(u64vec3, u64vec3, bvec3);" "u64vec4 mix(u64vec4, u64vec4, bvec4);" - "int64_t doubleBitsToInt64(double);" - "i64vec2 doubleBitsToInt64(dvec2);" - "i64vec3 doubleBitsToInt64(dvec3);" - "i64vec4 doubleBitsToInt64(dvec4);" + "int64_t doubleBitsToInt64(float64_t);" + "i64vec2 doubleBitsToInt64(f64vec2);" + "i64vec3 doubleBitsToInt64(f64vec3);" + "i64vec4 doubleBitsToInt64(f64vec4);" - "uint64_t doubleBitsToUint64(double);" - "u64vec2 doubleBitsToUint64(dvec2);" - "u64vec3 doubleBitsToUint64(dvec3);" - "u64vec4 doubleBitsToUint64(dvec4);" + "uint64_t doubleBitsToUint64(float64_t);" + "u64vec2 doubleBitsToUint64(f64vec2);" + "u64vec3 doubleBitsToUint64(f64vec3);" + "u64vec4 doubleBitsToUint64(f64vec4);" - "double int64BitsToDouble(int64_t);" - "dvec2 int64BitsToDouble(i64vec2);" - "dvec3 int64BitsToDouble(i64vec3);" - "dvec4 int64BitsToDouble(i64vec4);" + "float64_t int64BitsToDouble(int64_t);" + "f64vec2 int64BitsToDouble(i64vec2);" + "f64vec3 int64BitsToDouble(i64vec3);" + "f64vec4 int64BitsToDouble(i64vec4);" - "double uint64BitsToDouble(uint64_t);" - "dvec2 uint64BitsToDouble(u64vec2);" - "dvec3 uint64BitsToDouble(u64vec3);" - "dvec4 uint64BitsToDouble(u64vec4);" + "float64_t uint64BitsToDouble(uint64_t);" + "f64vec2 uint64BitsToDouble(u64vec2);" + "f64vec3 uint64BitsToDouble(u64vec3);" + "f64vec4 uint64BitsToDouble(u64vec4);" "int64_t packInt2x32(ivec2);" "uint64_t packUint2x32(uvec2);" @@ -959,31 +1262,40 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "bvec3 notEqual(u64vec3, u64vec3);" "bvec4 notEqual(u64vec4, u64vec4);" - "int findLSB(int64_t);" - "ivec2 findLSB(i64vec2);" - "ivec3 findLSB(i64vec3);" - "ivec4 findLSB(i64vec4);" + "int64_t bitCount(int64_t);" + "i64vec2 bitCount(i64vec2);" + "i64vec3 bitCount(i64vec3);" + "i64vec4 bitCount(i64vec4);" - "int findLSB(uint64_t);" - "ivec2 findLSB(u64vec2);" - "ivec3 findLSB(u64vec3);" - "ivec4 findLSB(u64vec4);" + "int64_t bitCount(uint64_t);" + "i64vec2 bitCount(u64vec2);" + "i64vec3 bitCount(u64vec3);" + "i64vec4 bitCount(u64vec4);" - "int findMSB(int64_t);" - "ivec2 findMSB(i64vec2);" - "ivec3 findMSB(i64vec3);" - "ivec4 findMSB(i64vec4);" + "int64_t findLSB(int64_t);" + "i64vec2 findLSB(i64vec2);" + "i64vec3 findLSB(i64vec3);" + "i64vec4 findLSB(i64vec4);" - "int findMSB(uint64_t);" - "ivec2 findMSB(u64vec2);" - "ivec3 findMSB(u64vec3);" - "ivec4 findMSB(u64vec4);" + "int64_t findLSB(uint64_t);" + "i64vec2 findLSB(u64vec2);" + "i64vec3 findLSB(u64vec3);" + "i64vec4 findLSB(u64vec4);" + + "int64_t findMSB(int64_t);" + "i64vec2 findMSB(i64vec2);" + "i64vec3 findMSB(i64vec3);" + "i64vec4 findMSB(i64vec4);" + + "int64_t findMSB(uint64_t);" + "i64vec2 findMSB(u64vec2);" + "i64vec3 findMSB(u64vec3);" + "i64vec4 findMSB(u64vec4);" "\n" ); } -#ifdef AMD_EXTENSIONS // GL_AMD_shader_trinary_minmax if (profile != EEsProfile && version >= 430) { commonBuiltins.append( @@ -1080,48 +1392,32 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n" ); } -#endif +#endif // !GLSLANG_ANGLE if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 430)) { commonBuiltins.append( - "uint atomicAdd(coherent volatile inout uint, uint);" - " int atomicAdd(coherent volatile inout int, int);" "uint atomicAdd(coherent volatile inout uint, uint, int, int, int);" " int atomicAdd(coherent volatile inout int, int, int, int, int);" - "uint atomicMin(coherent volatile inout uint, uint);" - " int atomicMin(coherent volatile inout int, int);" "uint atomicMin(coherent volatile inout uint, uint, int, int, int);" " int atomicMin(coherent volatile inout int, int, int, int, int);" - "uint atomicMax(coherent volatile inout uint, uint);" - " int atomicMax(coherent volatile inout int, int);" "uint atomicMax(coherent volatile inout uint, uint, int, int, int);" " int atomicMax(coherent volatile inout int, int, int, int, int);" - "uint atomicAnd(coherent volatile inout uint, uint);" - " int atomicAnd(coherent volatile inout int, int);" "uint atomicAnd(coherent volatile inout uint, uint, int, int, int);" " int atomicAnd(coherent volatile inout int, int, int, int, int);" - "uint atomicOr (coherent volatile inout uint, uint);" - " int atomicOr (coherent volatile inout int, int);" "uint atomicOr (coherent volatile inout uint, uint, int, int, int);" " int atomicOr (coherent volatile inout int, int, int, int, int);" - "uint atomicXor(coherent volatile inout uint, uint);" - " int atomicXor(coherent volatile inout int, int);" "uint atomicXor(coherent volatile inout uint, uint, int, int, int);" " int atomicXor(coherent volatile inout int, int, int, int, int);" - "uint atomicExchange(coherent volatile inout uint, uint);" - " int atomicExchange(coherent volatile inout int, int);" "uint atomicExchange(coherent volatile inout uint, uint, int, int, int);" " int atomicExchange(coherent volatile inout int, int, int, int, int);" - "uint atomicCompSwap(coherent volatile inout uint, uint, uint);" - " int atomicCompSwap(coherent volatile inout int, int, int);" "uint atomicCompSwap(coherent volatile inout uint, uint, uint, int, int, int, int, int);" " int atomicCompSwap(coherent volatile inout int, int, int, int, int, int, int, int);" @@ -1134,17 +1430,30 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 440) { commonBuiltins.append( "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t);" " int64_t atomicMin(coherent volatile inout int64_t, int64_t);" "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t, int, int, int);" " int64_t atomicMin(coherent volatile inout int64_t, int64_t, int, int, int);" + "float16_t atomicMin(coherent volatile inout float16_t, float16_t);" + "float16_t atomicMin(coherent volatile inout float16_t, float16_t, int, int, int);" + " float atomicMin(coherent volatile inout float, float);" + " float atomicMin(coherent volatile inout float, float, int, int, int);" + " double atomicMin(coherent volatile inout double, double);" + " double atomicMin(coherent volatile inout double, double, int, int, int);" "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);" " int64_t atomicMax(coherent volatile inout int64_t, int64_t);" "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t, int, int, int);" " int64_t atomicMax(coherent volatile inout int64_t, int64_t, int, int, int);" + "float16_t atomicMax(coherent volatile inout float16_t, float16_t);" + "float16_t atomicMax(coherent volatile inout float16_t, float16_t, int, int, int);" + " float atomicMax(coherent volatile inout float, float);" + " float atomicMax(coherent volatile inout float, float, int, int, int);" + " double atomicMax(coherent volatile inout double, double);" + " double atomicMax(coherent volatile inout double, double, int, int, int);" "uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);" " int64_t atomicAnd(coherent volatile inout int64_t, int64_t);" @@ -1165,11 +1474,23 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV " int64_t atomicAdd(coherent volatile inout int64_t, int64_t);" "uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);" " int64_t atomicAdd(coherent volatile inout int64_t, int64_t, int, int, int);" + "float16_t atomicAdd(coherent volatile inout float16_t, float16_t);" + "float16_t atomicAdd(coherent volatile inout float16_t, float16_t, int, int, int);" + " float atomicAdd(coherent volatile inout float, float);" + " float atomicAdd(coherent volatile inout float, float, int, int, int);" + " double atomicAdd(coherent volatile inout double, double);" + " double atomicAdd(coherent volatile inout double, double, int, int, int);" "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t);" " int64_t atomicExchange(coherent volatile inout int64_t, int64_t);" "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);" " int64_t atomicExchange(coherent volatile inout int64_t, int64_t, int, int, int);" + "float16_t atomicExchange(coherent volatile inout float16_t, float16_t);" + "float16_t atomicExchange(coherent volatile inout float16_t, float16_t, int, int, int);" + " float atomicExchange(coherent volatile inout float, float);" + " float atomicExchange(coherent volatile inout float, float, int, int, int);" + " double atomicExchange(coherent volatile inout double, double);" + " double atomicExchange(coherent volatile inout double, double, int, int, int);" "uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t);" " int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);" @@ -1178,35 +1499,22 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);" " int64_t atomicLoad(coherent volatile in int64_t, int, int, int);" + "float16_t atomicLoad(coherent volatile in float16_t, int, int, int);" + " float atomicLoad(coherent volatile in float, int, int, int);" + " double atomicLoad(coherent volatile in double, int, int, int);" "void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);" "void atomicStore(coherent volatile out int64_t, int64_t, int, int, int);" + "void atomicStore(coherent volatile out float16_t, float16_t, int, int, int);" + "void atomicStore(coherent volatile out float, float, int, int, int);" + "void atomicStore(coherent volatile out double, double, int, int, int);" "\n"); } - - if ((profile == EEsProfile && version >= 310) || - (profile != EEsProfile && version >= 450)) { - commonBuiltins.append( - "int mix(int x, int y, bool a);" - "ivec2 mix(ivec2 x, ivec2 y, bvec2 a);" - "ivec3 mix(ivec3 x, ivec3 y, bvec3 a);" - "ivec4 mix(ivec4 x, ivec4 y, bvec4 a);" - - "uint mix(uint x, uint y, bool a);" - "uvec2 mix(uvec2 x, uvec2 y, bvec2 a);" - "uvec3 mix(uvec3 x, uvec3 y, bvec3 a);" - "uvec4 mix(uvec4 x, uvec4 y, bvec4 a);" - - "bool mix(bool x, bool y, bool a);" - "bvec2 mix(bvec2 x, bvec2 y, bvec2 a);" - "bvec3 mix(bvec3 x, bvec3 y, bvec3 a);" - "bvec4 mix(bvec4 x, bvec4 y, bvec4 a);" - - "\n"); - } +#endif // !GLSLANG_ANGLE +#endif // !GLSLANG_WEB if ((profile == EEsProfile && version >= 300) || - (profile != EEsProfile && version >= 330)) { + (profile != EEsProfile && version >= 150)) { // GL_ARB_shader_bit_encoding commonBuiltins.append( "int floatBitsToInt(highp float value);" "ivec2 floatBitsToInt(highp vec2 value);" @@ -1231,6 +1539,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_WEB if ((profile != EEsProfile && version >= 400) || (profile == EEsProfile && version >= 310)) { // GL_OES_gpu_shader5 @@ -1240,17 +1549,28 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec3 fma(vec3, vec3, vec3 );" "vec4 fma(vec4, vec4, vec4 );" "\n"); + } - if (profile != EEsProfile) { +#ifndef GLSLANG_ANGLE + if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double fma(double, double, double);" "dvec2 fma(dvec2, dvec2, dvec2 );" "dvec3 fma(dvec3, dvec3, dvec3 );" "dvec4 fma(dvec4, dvec4, dvec4 );" "\n"); - } } + if (profile == EEsProfile && version >= 310) { // ARB_gpu_shader_fp64 + commonBuiltins.append( + "float64_t fma(float64_t, float64_t, float64_t);" + "f64vec2 fma(f64vec2, f64vec2, f64vec2 );" + "f64vec3 fma(f64vec3, f64vec3, f64vec3 );" + "f64vec4 fma(f64vec4, f64vec4, f64vec4 );" + "\n"); + } +#endif + if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 400)) { commonBuiltins.append( @@ -1267,7 +1587,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } - if (profile != EEsProfile && version >= 400) { +#ifndef GLSLANG_ANGLE + if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double frexp(double, out int);" "dvec2 frexp( dvec2, out ivec2);" @@ -1285,8 +1606,25 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } + if (profile == EEsProfile && version >= 310) { // ARB_gpu_shader_fp64 + commonBuiltins.append( + "float64_t frexp(float64_t, out int);" + "f64vec2 frexp( f64vec2, out ivec2);" + "f64vec3 frexp( f64vec3, out ivec3);" + "f64vec4 frexp( f64vec4, out ivec4);" + + "float64_t ldexp(float64_t, int);" + "f64vec2 ldexp( f64vec2, ivec2);" + "f64vec3 ldexp( f64vec3, ivec3);" + "f64vec4 ldexp( f64vec4, ivec4);" + + "\n"); + } +#endif +#endif + if ((profile == EEsProfile && version >= 300) || - (profile != EEsProfile && version >= 400)) { + (profile != EEsProfile && version >= 150)) { commonBuiltins.append( "highp uint packUnorm2x16(vec2);" "vec2 unpackUnorm2x16(highp uint);" @@ -1294,7 +1632,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } if ((profile == EEsProfile && version >= 300) || - (profile != EEsProfile && version >= 420)) { + (profile != EEsProfile && version >= 150)) { commonBuiltins.append( "highp uint packSnorm2x16(vec2);" " vec2 unpackSnorm2x16(highp uint);" @@ -1306,14 +1644,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append( "mediump vec2 unpackHalf2x16(highp uint);" "\n"); - } else if (profile != EEsProfile && version >= 420) { + } else if (profile != EEsProfile && version >= 150) { commonBuiltins.append( " vec2 unpackHalf2x16(highp uint);" "\n"); } +#ifndef GLSLANG_WEB if ((profile == EEsProfile && version >= 310) || - (profile != EEsProfile && version >= 400)) { + (profile != EEsProfile && version >= 150)) { commonBuiltins.append( "highp uint packSnorm4x8(vec4);" "highp uint packUnorm4x8(vec4);" @@ -1325,54 +1664,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "mediump vec4 unpackSnorm4x8(highp uint);" "mediump vec4 unpackUnorm4x8(highp uint);" "\n"); - } else if (profile != EEsProfile && version >= 400) { + } else if (profile != EEsProfile && version >= 150) { commonBuiltins.append( "vec4 unpackSnorm4x8(highp uint);" "vec4 unpackUnorm4x8(highp uint);" "\n"); } - - // - // Geometric Functions. - // - commonBuiltins.append( - "float length(float x);" - "float length(vec2 x);" - "float length(vec3 x);" - "float length(vec4 x);" - - "float distance(float p0, float p1);" - "float distance(vec2 p0, vec2 p1);" - "float distance(vec3 p0, vec3 p1);" - "float distance(vec4 p0, vec4 p1);" - - "float dot(float x, float y);" - "float dot(vec2 x, vec2 y);" - "float dot(vec3 x, vec3 y);" - "float dot(vec4 x, vec4 y);" - - "vec3 cross(vec3 x, vec3 y);" - "float normalize(float x);" - "vec2 normalize(vec2 x);" - "vec3 normalize(vec3 x);" - "vec4 normalize(vec4 x);" - - "float faceforward(float N, float I, float Nref);" - "vec2 faceforward(vec2 N, vec2 I, vec2 Nref);" - "vec3 faceforward(vec3 N, vec3 I, vec3 Nref);" - "vec4 faceforward(vec4 N, vec4 I, vec4 Nref);" - - "float reflect(float I, float N);" - "vec2 reflect(vec2 I, vec2 N);" - "vec3 reflect(vec3 I, vec3 N);" - "vec4 reflect(vec4 I, vec4 N);" - - "float refract(float I, float N, float eta);" - "vec2 refract(vec2 I, vec2 N, float eta);" - "vec3 refract(vec3 I, vec3 N, float eta);" - "vec4 refract(vec4 I, vec4 N, float eta);" - - "\n"); +#endif // // Matrix Functions. @@ -1431,109 +1729,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } } - // - // Vector relational functions. - // - commonBuiltins.append( - "bvec2 lessThan(vec2 x, vec2 y);" - "bvec3 lessThan(vec3 x, vec3 y);" - "bvec4 lessThan(vec4 x, vec4 y);" - - "bvec2 lessThan(ivec2 x, ivec2 y);" - "bvec3 lessThan(ivec3 x, ivec3 y);" - "bvec4 lessThan(ivec4 x, ivec4 y);" - - "bvec2 lessThanEqual(vec2 x, vec2 y);" - "bvec3 lessThanEqual(vec3 x, vec3 y);" - "bvec4 lessThanEqual(vec4 x, vec4 y);" - - "bvec2 lessThanEqual(ivec2 x, ivec2 y);" - "bvec3 lessThanEqual(ivec3 x, ivec3 y);" - "bvec4 lessThanEqual(ivec4 x, ivec4 y);" - - "bvec2 greaterThan(vec2 x, vec2 y);" - "bvec3 greaterThan(vec3 x, vec3 y);" - "bvec4 greaterThan(vec4 x, vec4 y);" - - "bvec2 greaterThan(ivec2 x, ivec2 y);" - "bvec3 greaterThan(ivec3 x, ivec3 y);" - "bvec4 greaterThan(ivec4 x, ivec4 y);" - - "bvec2 greaterThanEqual(vec2 x, vec2 y);" - "bvec3 greaterThanEqual(vec3 x, vec3 y);" - "bvec4 greaterThanEqual(vec4 x, vec4 y);" - - "bvec2 greaterThanEqual(ivec2 x, ivec2 y);" - "bvec3 greaterThanEqual(ivec3 x, ivec3 y);" - "bvec4 greaterThanEqual(ivec4 x, ivec4 y);" - - "bvec2 equal(vec2 x, vec2 y);" - "bvec3 equal(vec3 x, vec3 y);" - "bvec4 equal(vec4 x, vec4 y);" - - "bvec2 equal(ivec2 x, ivec2 y);" - "bvec3 equal(ivec3 x, ivec3 y);" - "bvec4 equal(ivec4 x, ivec4 y);" - - "bvec2 equal(bvec2 x, bvec2 y);" - "bvec3 equal(bvec3 x, bvec3 y);" - "bvec4 equal(bvec4 x, bvec4 y);" - - "bvec2 notEqual(vec2 x, vec2 y);" - "bvec3 notEqual(vec3 x, vec3 y);" - "bvec4 notEqual(vec4 x, vec4 y);" - - "bvec2 notEqual(ivec2 x, ivec2 y);" - "bvec3 notEqual(ivec3 x, ivec3 y);" - "bvec4 notEqual(ivec4 x, ivec4 y);" - - "bvec2 notEqual(bvec2 x, bvec2 y);" - "bvec3 notEqual(bvec3 x, bvec3 y);" - "bvec4 notEqual(bvec4 x, bvec4 y);" - - "bool any(bvec2 x);" - "bool any(bvec3 x);" - "bool any(bvec4 x);" - - "bool all(bvec2 x);" - "bool all(bvec3 x);" - "bool all(bvec4 x);" - - "bvec2 not(bvec2 x);" - "bvec3 not(bvec3 x);" - "bvec4 not(bvec4 x);" - - "\n"); - - if (version >= 130) { - commonBuiltins.append( - "bvec2 lessThan(uvec2 x, uvec2 y);" - "bvec3 lessThan(uvec3 x, uvec3 y);" - "bvec4 lessThan(uvec4 x, uvec4 y);" - - "bvec2 lessThanEqual(uvec2 x, uvec2 y);" - "bvec3 lessThanEqual(uvec3 x, uvec3 y);" - "bvec4 lessThanEqual(uvec4 x, uvec4 y);" - - "bvec2 greaterThan(uvec2 x, uvec2 y);" - "bvec3 greaterThan(uvec3 x, uvec3 y);" - "bvec4 greaterThan(uvec4 x, uvec4 y);" - - "bvec2 greaterThanEqual(uvec2 x, uvec2 y);" - "bvec3 greaterThanEqual(uvec3 x, uvec3 y);" - "bvec4 greaterThanEqual(uvec4 x, uvec4 y);" - - "bvec2 equal(uvec2 x, uvec2 y);" - "bvec3 equal(uvec3 x, uvec3 y);" - "bvec4 equal(uvec4 x, uvec4 y);" - - "bvec2 notEqual(uvec2 x, uvec2 y);" - "bvec3 notEqual(uvec3 x, uvec3 y);" - "bvec4 notEqual(uvec4 x, uvec4 y);" - - "\n"); - } - +#ifndef GLSLANG_WEB +#ifndef GLSLANG_ANGLE // // Original-style texture functions existing in all stages. // (Per-stage functions below.) @@ -1667,6 +1864,22 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } + if (profile != EEsProfile && version == 450) { + commonBuiltins.append( + "uint atomicCounterAddARB(atomic_uint, uint);" + "uint atomicCounterSubtractARB(atomic_uint, uint);" + "uint atomicCounterMinARB(atomic_uint, uint);" + "uint atomicCounterMaxARB(atomic_uint, uint);" + "uint atomicCounterAndARB(atomic_uint, uint);" + "uint atomicCounterOrARB(atomic_uint, uint);" + "uint atomicCounterXorARB(atomic_uint, uint);" + "uint atomicCounterExchangeARB(atomic_uint, uint);" + "uint atomicCounterCompSwapARB(atomic_uint, uint, uint);" + + "\n"); + } + + if (profile != EEsProfile && version >= 460) { commonBuiltins.append( "uint atomicCounterAdd(atomic_uint, uint);" @@ -1682,6 +1895,37 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } } + else if (spvVersion.vulkanRelaxed) { + // + // Atomic counter functions act as aliases to normal atomic functions. + // replace definitions to take 'volatile coherent uint' instead of 'atomic_uint' + // and map to equivalent non-counter atomic op + // + if ((profile != EEsProfile && version >= 300) || + (profile == EEsProfile && version >= 310)) { + commonBuiltins.append( + "uint atomicCounterIncrement(volatile coherent uint);" + "uint atomicCounterDecrement(volatile coherent uint);" + "uint atomicCounter(volatile coherent uint);" + + "\n"); + } + if (profile != EEsProfile && version >= 460) { + commonBuiltins.append( + "uint atomicCounterAdd(volatile coherent uint, uint);" + "uint atomicCounterSubtract(volatile coherent uint, uint);" + "uint atomicCounterMin(volatile coherent uint, uint);" + "uint atomicCounterMax(volatile coherent uint, uint);" + "uint atomicCounterAnd(volatile coherent uint, uint);" + "uint atomicCounterOr(volatile coherent uint, uint);" + "uint atomicCounterXor(volatile coherent uint, uint);" + "uint atomicCounterExchange(volatile coherent uint, uint);" + "uint atomicCounterCompSwap(volatile coherent uint, uint, uint);" + + "\n"); + } + } +#endif // !GLSLANG_ANGLE // Bitfield if ((profile == EEsProfile && version >= 310) || @@ -1824,6 +2068,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_ANGLE // GL_ARB_shader_ballot if (profile != EEsProfile && version >= 450) { commonBuiltins.append( @@ -1873,7 +2118,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { commonBuiltins.append( "void subgroupBarrier();" "void subgroupMemoryBarrier();" @@ -1883,58 +2129,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "bool subgroupAll(bool);\n" "bool subgroupAny(bool);\n" - - "bool subgroupAllEqual(float);\n" - "bool subgroupAllEqual(vec2);\n" - "bool subgroupAllEqual(vec3);\n" - "bool subgroupAllEqual(vec4);\n" - "bool subgroupAllEqual(int);\n" - "bool subgroupAllEqual(ivec2);\n" - "bool subgroupAllEqual(ivec3);\n" - "bool subgroupAllEqual(ivec4);\n" - "bool subgroupAllEqual(uint);\n" - "bool subgroupAllEqual(uvec2);\n" - "bool subgroupAllEqual(uvec3);\n" - "bool subgroupAllEqual(uvec4);\n" - "bool subgroupAllEqual(bool);\n" - "bool subgroupAllEqual(bvec2);\n" - "bool subgroupAllEqual(bvec3);\n" - "bool subgroupAllEqual(bvec4);\n" - - "float subgroupBroadcast(float, uint);\n" - "vec2 subgroupBroadcast(vec2, uint);\n" - "vec3 subgroupBroadcast(vec3, uint);\n" - "vec4 subgroupBroadcast(vec4, uint);\n" - "int subgroupBroadcast(int, uint);\n" - "ivec2 subgroupBroadcast(ivec2, uint);\n" - "ivec3 subgroupBroadcast(ivec3, uint);\n" - "ivec4 subgroupBroadcast(ivec4, uint);\n" - "uint subgroupBroadcast(uint, uint);\n" - "uvec2 subgroupBroadcast(uvec2, uint);\n" - "uvec3 subgroupBroadcast(uvec3, uint);\n" - "uvec4 subgroupBroadcast(uvec4, uint);\n" - "bool subgroupBroadcast(bool, uint);\n" - "bvec2 subgroupBroadcast(bvec2, uint);\n" - "bvec3 subgroupBroadcast(bvec3, uint);\n" - "bvec4 subgroupBroadcast(bvec4, uint);\n" - - "float subgroupBroadcastFirst(float);\n" - "vec2 subgroupBroadcastFirst(vec2);\n" - "vec3 subgroupBroadcastFirst(vec3);\n" - "vec4 subgroupBroadcastFirst(vec4);\n" - "int subgroupBroadcastFirst(int);\n" - "ivec2 subgroupBroadcastFirst(ivec2);\n" - "ivec3 subgroupBroadcastFirst(ivec3);\n" - "ivec4 subgroupBroadcastFirst(ivec4);\n" - "uint subgroupBroadcastFirst(uint);\n" - "uvec2 subgroupBroadcastFirst(uvec2);\n" - "uvec3 subgroupBroadcastFirst(uvec3);\n" - "uvec4 subgroupBroadcastFirst(uvec4);\n" - "bool subgroupBroadcastFirst(bool);\n" - "bvec2 subgroupBroadcastFirst(bvec2);\n" - "bvec3 subgroupBroadcastFirst(bvec3);\n" - "bvec4 subgroupBroadcastFirst(bvec4);\n" - "uvec4 subgroupBallot(bool);\n" "bool subgroupInverseBallot(uvec4);\n" "bool subgroupBallotBitExtract(uvec4, uint);\n" @@ -1943,1015 +2137,136 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "uint subgroupBallotExclusiveBitCount(uvec4);\n" "uint subgroupBallotFindLSB(uvec4);\n" "uint subgroupBallotFindMSB(uvec4);\n" - - "float subgroupShuffle(float, uint);\n" - "vec2 subgroupShuffle(vec2, uint);\n" - "vec3 subgroupShuffle(vec3, uint);\n" - "vec4 subgroupShuffle(vec4, uint);\n" - "int subgroupShuffle(int, uint);\n" - "ivec2 subgroupShuffle(ivec2, uint);\n" - "ivec3 subgroupShuffle(ivec3, uint);\n" - "ivec4 subgroupShuffle(ivec4, uint);\n" - "uint subgroupShuffle(uint, uint);\n" - "uvec2 subgroupShuffle(uvec2, uint);\n" - "uvec3 subgroupShuffle(uvec3, uint);\n" - "uvec4 subgroupShuffle(uvec4, uint);\n" - "bool subgroupShuffle(bool, uint);\n" - "bvec2 subgroupShuffle(bvec2, uint);\n" - "bvec3 subgroupShuffle(bvec3, uint);\n" - "bvec4 subgroupShuffle(bvec4, uint);\n" - - "float subgroupShuffleXor(float, uint);\n" - "vec2 subgroupShuffleXor(vec2, uint);\n" - "vec3 subgroupShuffleXor(vec3, uint);\n" - "vec4 subgroupShuffleXor(vec4, uint);\n" - "int subgroupShuffleXor(int, uint);\n" - "ivec2 subgroupShuffleXor(ivec2, uint);\n" - "ivec3 subgroupShuffleXor(ivec3, uint);\n" - "ivec4 subgroupShuffleXor(ivec4, uint);\n" - "uint subgroupShuffleXor(uint, uint);\n" - "uvec2 subgroupShuffleXor(uvec2, uint);\n" - "uvec3 subgroupShuffleXor(uvec3, uint);\n" - "uvec4 subgroupShuffleXor(uvec4, uint);\n" - "bool subgroupShuffleXor(bool, uint);\n" - "bvec2 subgroupShuffleXor(bvec2, uint);\n" - "bvec3 subgroupShuffleXor(bvec3, uint);\n" - "bvec4 subgroupShuffleXor(bvec4, uint);\n" - - "float subgroupShuffleUp(float, uint delta);\n" - "vec2 subgroupShuffleUp(vec2, uint delta);\n" - "vec3 subgroupShuffleUp(vec3, uint delta);\n" - "vec4 subgroupShuffleUp(vec4, uint delta);\n" - "int subgroupShuffleUp(int, uint delta);\n" - "ivec2 subgroupShuffleUp(ivec2, uint delta);\n" - "ivec3 subgroupShuffleUp(ivec3, uint delta);\n" - "ivec4 subgroupShuffleUp(ivec4, uint delta);\n" - "uint subgroupShuffleUp(uint, uint delta);\n" - "uvec2 subgroupShuffleUp(uvec2, uint delta);\n" - "uvec3 subgroupShuffleUp(uvec3, uint delta);\n" - "uvec4 subgroupShuffleUp(uvec4, uint delta);\n" - "bool subgroupShuffleUp(bool, uint delta);\n" - "bvec2 subgroupShuffleUp(bvec2, uint delta);\n" - "bvec3 subgroupShuffleUp(bvec3, uint delta);\n" - "bvec4 subgroupShuffleUp(bvec4, uint delta);\n" - - "float subgroupShuffleDown(float, uint delta);\n" - "vec2 subgroupShuffleDown(vec2, uint delta);\n" - "vec3 subgroupShuffleDown(vec3, uint delta);\n" - "vec4 subgroupShuffleDown(vec4, uint delta);\n" - "int subgroupShuffleDown(int, uint delta);\n" - "ivec2 subgroupShuffleDown(ivec2, uint delta);\n" - "ivec3 subgroupShuffleDown(ivec3, uint delta);\n" - "ivec4 subgroupShuffleDown(ivec4, uint delta);\n" - "uint subgroupShuffleDown(uint, uint delta);\n" - "uvec2 subgroupShuffleDown(uvec2, uint delta);\n" - "uvec3 subgroupShuffleDown(uvec3, uint delta);\n" - "uvec4 subgroupShuffleDown(uvec4, uint delta);\n" - "bool subgroupShuffleDown(bool, uint delta);\n" - "bvec2 subgroupShuffleDown(bvec2, uint delta);\n" - "bvec3 subgroupShuffleDown(bvec3, uint delta);\n" - "bvec4 subgroupShuffleDown(bvec4, uint delta);\n" - - "float subgroupAdd(float);\n" - "vec2 subgroupAdd(vec2);\n" - "vec3 subgroupAdd(vec3);\n" - "vec4 subgroupAdd(vec4);\n" - "int subgroupAdd(int);\n" - "ivec2 subgroupAdd(ivec2);\n" - "ivec3 subgroupAdd(ivec3);\n" - "ivec4 subgroupAdd(ivec4);\n" - "uint subgroupAdd(uint);\n" - "uvec2 subgroupAdd(uvec2);\n" - "uvec3 subgroupAdd(uvec3);\n" - "uvec4 subgroupAdd(uvec4);\n" - - "float subgroupMul(float);\n" - "vec2 subgroupMul(vec2);\n" - "vec3 subgroupMul(vec3);\n" - "vec4 subgroupMul(vec4);\n" - "int subgroupMul(int);\n" - "ivec2 subgroupMul(ivec2);\n" - "ivec3 subgroupMul(ivec3);\n" - "ivec4 subgroupMul(ivec4);\n" - "uint subgroupMul(uint);\n" - "uvec2 subgroupMul(uvec2);\n" - "uvec3 subgroupMul(uvec3);\n" - "uvec4 subgroupMul(uvec4);\n" - - "float subgroupMin(float);\n" - "vec2 subgroupMin(vec2);\n" - "vec3 subgroupMin(vec3);\n" - "vec4 subgroupMin(vec4);\n" - "int subgroupMin(int);\n" - "ivec2 subgroupMin(ivec2);\n" - "ivec3 subgroupMin(ivec3);\n" - "ivec4 subgroupMin(ivec4);\n" - "uint subgroupMin(uint);\n" - "uvec2 subgroupMin(uvec2);\n" - "uvec3 subgroupMin(uvec3);\n" - "uvec4 subgroupMin(uvec4);\n" - - "float subgroupMax(float);\n" - "vec2 subgroupMax(vec2);\n" - "vec3 subgroupMax(vec3);\n" - "vec4 subgroupMax(vec4);\n" - "int subgroupMax(int);\n" - "ivec2 subgroupMax(ivec2);\n" - "ivec3 subgroupMax(ivec3);\n" - "ivec4 subgroupMax(ivec4);\n" - "uint subgroupMax(uint);\n" - "uvec2 subgroupMax(uvec2);\n" - "uvec3 subgroupMax(uvec3);\n" - "uvec4 subgroupMax(uvec4);\n" - - "int subgroupAnd(int);\n" - "ivec2 subgroupAnd(ivec2);\n" - "ivec3 subgroupAnd(ivec3);\n" - "ivec4 subgroupAnd(ivec4);\n" - "uint subgroupAnd(uint);\n" - "uvec2 subgroupAnd(uvec2);\n" - "uvec3 subgroupAnd(uvec3);\n" - "uvec4 subgroupAnd(uvec4);\n" - "bool subgroupAnd(bool);\n" - "bvec2 subgroupAnd(bvec2);\n" - "bvec3 subgroupAnd(bvec3);\n" - "bvec4 subgroupAnd(bvec4);\n" - - "int subgroupOr(int);\n" - "ivec2 subgroupOr(ivec2);\n" - "ivec3 subgroupOr(ivec3);\n" - "ivec4 subgroupOr(ivec4);\n" - "uint subgroupOr(uint);\n" - "uvec2 subgroupOr(uvec2);\n" - "uvec3 subgroupOr(uvec3);\n" - "uvec4 subgroupOr(uvec4);\n" - "bool subgroupOr(bool);\n" - "bvec2 subgroupOr(bvec2);\n" - "bvec3 subgroupOr(bvec3);\n" - "bvec4 subgroupOr(bvec4);\n" - - "int subgroupXor(int);\n" - "ivec2 subgroupXor(ivec2);\n" - "ivec3 subgroupXor(ivec3);\n" - "ivec4 subgroupXor(ivec4);\n" - "uint subgroupXor(uint);\n" - "uvec2 subgroupXor(uvec2);\n" - "uvec3 subgroupXor(uvec3);\n" - "uvec4 subgroupXor(uvec4);\n" - "bool subgroupXor(bool);\n" - "bvec2 subgroupXor(bvec2);\n" - "bvec3 subgroupXor(bvec3);\n" - "bvec4 subgroupXor(bvec4);\n" - - "float subgroupInclusiveAdd(float);\n" - "vec2 subgroupInclusiveAdd(vec2);\n" - "vec3 subgroupInclusiveAdd(vec3);\n" - "vec4 subgroupInclusiveAdd(vec4);\n" - "int subgroupInclusiveAdd(int);\n" - "ivec2 subgroupInclusiveAdd(ivec2);\n" - "ivec3 subgroupInclusiveAdd(ivec3);\n" - "ivec4 subgroupInclusiveAdd(ivec4);\n" - "uint subgroupInclusiveAdd(uint);\n" - "uvec2 subgroupInclusiveAdd(uvec2);\n" - "uvec3 subgroupInclusiveAdd(uvec3);\n" - "uvec4 subgroupInclusiveAdd(uvec4);\n" - - "float subgroupInclusiveMul(float);\n" - "vec2 subgroupInclusiveMul(vec2);\n" - "vec3 subgroupInclusiveMul(vec3);\n" - "vec4 subgroupInclusiveMul(vec4);\n" - "int subgroupInclusiveMul(int);\n" - "ivec2 subgroupInclusiveMul(ivec2);\n" - "ivec3 subgroupInclusiveMul(ivec3);\n" - "ivec4 subgroupInclusiveMul(ivec4);\n" - "uint subgroupInclusiveMul(uint);\n" - "uvec2 subgroupInclusiveMul(uvec2);\n" - "uvec3 subgroupInclusiveMul(uvec3);\n" - "uvec4 subgroupInclusiveMul(uvec4);\n" - - "float subgroupInclusiveMin(float);\n" - "vec2 subgroupInclusiveMin(vec2);\n" - "vec3 subgroupInclusiveMin(vec3);\n" - "vec4 subgroupInclusiveMin(vec4);\n" - "int subgroupInclusiveMin(int);\n" - "ivec2 subgroupInclusiveMin(ivec2);\n" - "ivec3 subgroupInclusiveMin(ivec3);\n" - "ivec4 subgroupInclusiveMin(ivec4);\n" - "uint subgroupInclusiveMin(uint);\n" - "uvec2 subgroupInclusiveMin(uvec2);\n" - "uvec3 subgroupInclusiveMin(uvec3);\n" - "uvec4 subgroupInclusiveMin(uvec4);\n" - - "float subgroupInclusiveMax(float);\n" - "vec2 subgroupInclusiveMax(vec2);\n" - "vec3 subgroupInclusiveMax(vec3);\n" - "vec4 subgroupInclusiveMax(vec4);\n" - "int subgroupInclusiveMax(int);\n" - "ivec2 subgroupInclusiveMax(ivec2);\n" - "ivec3 subgroupInclusiveMax(ivec3);\n" - "ivec4 subgroupInclusiveMax(ivec4);\n" - "uint subgroupInclusiveMax(uint);\n" - "uvec2 subgroupInclusiveMax(uvec2);\n" - "uvec3 subgroupInclusiveMax(uvec3);\n" - "uvec4 subgroupInclusiveMax(uvec4);\n" - - "int subgroupInclusiveAnd(int);\n" - "ivec2 subgroupInclusiveAnd(ivec2);\n" - "ivec3 subgroupInclusiveAnd(ivec3);\n" - "ivec4 subgroupInclusiveAnd(ivec4);\n" - "uint subgroupInclusiveAnd(uint);\n" - "uvec2 subgroupInclusiveAnd(uvec2);\n" - "uvec3 subgroupInclusiveAnd(uvec3);\n" - "uvec4 subgroupInclusiveAnd(uvec4);\n" - "bool subgroupInclusiveAnd(bool);\n" - "bvec2 subgroupInclusiveAnd(bvec2);\n" - "bvec3 subgroupInclusiveAnd(bvec3);\n" - "bvec4 subgroupInclusiveAnd(bvec4);\n" - - "int subgroupInclusiveOr(int);\n" - "ivec2 subgroupInclusiveOr(ivec2);\n" - "ivec3 subgroupInclusiveOr(ivec3);\n" - "ivec4 subgroupInclusiveOr(ivec4);\n" - "uint subgroupInclusiveOr(uint);\n" - "uvec2 subgroupInclusiveOr(uvec2);\n" - "uvec3 subgroupInclusiveOr(uvec3);\n" - "uvec4 subgroupInclusiveOr(uvec4);\n" - "bool subgroupInclusiveOr(bool);\n" - "bvec2 subgroupInclusiveOr(bvec2);\n" - "bvec3 subgroupInclusiveOr(bvec3);\n" - "bvec4 subgroupInclusiveOr(bvec4);\n" - - "int subgroupInclusiveXor(int);\n" - "ivec2 subgroupInclusiveXor(ivec2);\n" - "ivec3 subgroupInclusiveXor(ivec3);\n" - "ivec4 subgroupInclusiveXor(ivec4);\n" - "uint subgroupInclusiveXor(uint);\n" - "uvec2 subgroupInclusiveXor(uvec2);\n" - "uvec3 subgroupInclusiveXor(uvec3);\n" - "uvec4 subgroupInclusiveXor(uvec4);\n" - "bool subgroupInclusiveXor(bool);\n" - "bvec2 subgroupInclusiveXor(bvec2);\n" - "bvec3 subgroupInclusiveXor(bvec3);\n" - "bvec4 subgroupInclusiveXor(bvec4);\n" - - "float subgroupExclusiveAdd(float);\n" - "vec2 subgroupExclusiveAdd(vec2);\n" - "vec3 subgroupExclusiveAdd(vec3);\n" - "vec4 subgroupExclusiveAdd(vec4);\n" - "int subgroupExclusiveAdd(int);\n" - "ivec2 subgroupExclusiveAdd(ivec2);\n" - "ivec3 subgroupExclusiveAdd(ivec3);\n" - "ivec4 subgroupExclusiveAdd(ivec4);\n" - "uint subgroupExclusiveAdd(uint);\n" - "uvec2 subgroupExclusiveAdd(uvec2);\n" - "uvec3 subgroupExclusiveAdd(uvec3);\n" - "uvec4 subgroupExclusiveAdd(uvec4);\n" - - "float subgroupExclusiveMul(float);\n" - "vec2 subgroupExclusiveMul(vec2);\n" - "vec3 subgroupExclusiveMul(vec3);\n" - "vec4 subgroupExclusiveMul(vec4);\n" - "int subgroupExclusiveMul(int);\n" - "ivec2 subgroupExclusiveMul(ivec2);\n" - "ivec3 subgroupExclusiveMul(ivec3);\n" - "ivec4 subgroupExclusiveMul(ivec4);\n" - "uint subgroupExclusiveMul(uint);\n" - "uvec2 subgroupExclusiveMul(uvec2);\n" - "uvec3 subgroupExclusiveMul(uvec3);\n" - "uvec4 subgroupExclusiveMul(uvec4);\n" - - "float subgroupExclusiveMin(float);\n" - "vec2 subgroupExclusiveMin(vec2);\n" - "vec3 subgroupExclusiveMin(vec3);\n" - "vec4 subgroupExclusiveMin(vec4);\n" - "int subgroupExclusiveMin(int);\n" - "ivec2 subgroupExclusiveMin(ivec2);\n" - "ivec3 subgroupExclusiveMin(ivec3);\n" - "ivec4 subgroupExclusiveMin(ivec4);\n" - "uint subgroupExclusiveMin(uint);\n" - "uvec2 subgroupExclusiveMin(uvec2);\n" - "uvec3 subgroupExclusiveMin(uvec3);\n" - "uvec4 subgroupExclusiveMin(uvec4);\n" - - "float subgroupExclusiveMax(float);\n" - "vec2 subgroupExclusiveMax(vec2);\n" - "vec3 subgroupExclusiveMax(vec3);\n" - "vec4 subgroupExclusiveMax(vec4);\n" - "int subgroupExclusiveMax(int);\n" - "ivec2 subgroupExclusiveMax(ivec2);\n" - "ivec3 subgroupExclusiveMax(ivec3);\n" - "ivec4 subgroupExclusiveMax(ivec4);\n" - "uint subgroupExclusiveMax(uint);\n" - "uvec2 subgroupExclusiveMax(uvec2);\n" - "uvec3 subgroupExclusiveMax(uvec3);\n" - "uvec4 subgroupExclusiveMax(uvec4);\n" - - "int subgroupExclusiveAnd(int);\n" - "ivec2 subgroupExclusiveAnd(ivec2);\n" - "ivec3 subgroupExclusiveAnd(ivec3);\n" - "ivec4 subgroupExclusiveAnd(ivec4);\n" - "uint subgroupExclusiveAnd(uint);\n" - "uvec2 subgroupExclusiveAnd(uvec2);\n" - "uvec3 subgroupExclusiveAnd(uvec3);\n" - "uvec4 subgroupExclusiveAnd(uvec4);\n" - "bool subgroupExclusiveAnd(bool);\n" - "bvec2 subgroupExclusiveAnd(bvec2);\n" - "bvec3 subgroupExclusiveAnd(bvec3);\n" - "bvec4 subgroupExclusiveAnd(bvec4);\n" - - "int subgroupExclusiveOr(int);\n" - "ivec2 subgroupExclusiveOr(ivec2);\n" - "ivec3 subgroupExclusiveOr(ivec3);\n" - "ivec4 subgroupExclusiveOr(ivec4);\n" - "uint subgroupExclusiveOr(uint);\n" - "uvec2 subgroupExclusiveOr(uvec2);\n" - "uvec3 subgroupExclusiveOr(uvec3);\n" - "uvec4 subgroupExclusiveOr(uvec4);\n" - "bool subgroupExclusiveOr(bool);\n" - "bvec2 subgroupExclusiveOr(bvec2);\n" - "bvec3 subgroupExclusiveOr(bvec3);\n" - "bvec4 subgroupExclusiveOr(bvec4);\n" - - "int subgroupExclusiveXor(int);\n" - "ivec2 subgroupExclusiveXor(ivec2);\n" - "ivec3 subgroupExclusiveXor(ivec3);\n" - "ivec4 subgroupExclusiveXor(ivec4);\n" - "uint subgroupExclusiveXor(uint);\n" - "uvec2 subgroupExclusiveXor(uvec2);\n" - "uvec3 subgroupExclusiveXor(uvec3);\n" - "uvec4 subgroupExclusiveXor(uvec4);\n" - "bool subgroupExclusiveXor(bool);\n" - "bvec2 subgroupExclusiveXor(bvec2);\n" - "bvec3 subgroupExclusiveXor(bvec3);\n" - "bvec4 subgroupExclusiveXor(bvec4);\n" - - "float subgroupClusteredAdd(float, uint);\n" - "vec2 subgroupClusteredAdd(vec2, uint);\n" - "vec3 subgroupClusteredAdd(vec3, uint);\n" - "vec4 subgroupClusteredAdd(vec4, uint);\n" - "int subgroupClusteredAdd(int, uint);\n" - "ivec2 subgroupClusteredAdd(ivec2, uint);\n" - "ivec3 subgroupClusteredAdd(ivec3, uint);\n" - "ivec4 subgroupClusteredAdd(ivec4, uint);\n" - "uint subgroupClusteredAdd(uint, uint);\n" - "uvec2 subgroupClusteredAdd(uvec2, uint);\n" - "uvec3 subgroupClusteredAdd(uvec3, uint);\n" - "uvec4 subgroupClusteredAdd(uvec4, uint);\n" - - "float subgroupClusteredMul(float, uint);\n" - "vec2 subgroupClusteredMul(vec2, uint);\n" - "vec3 subgroupClusteredMul(vec3, uint);\n" - "vec4 subgroupClusteredMul(vec4, uint);\n" - "int subgroupClusteredMul(int, uint);\n" - "ivec2 subgroupClusteredMul(ivec2, uint);\n" - "ivec3 subgroupClusteredMul(ivec3, uint);\n" - "ivec4 subgroupClusteredMul(ivec4, uint);\n" - "uint subgroupClusteredMul(uint, uint);\n" - "uvec2 subgroupClusteredMul(uvec2, uint);\n" - "uvec3 subgroupClusteredMul(uvec3, uint);\n" - "uvec4 subgroupClusteredMul(uvec4, uint);\n" - - "float subgroupClusteredMin(float, uint);\n" - "vec2 subgroupClusteredMin(vec2, uint);\n" - "vec3 subgroupClusteredMin(vec3, uint);\n" - "vec4 subgroupClusteredMin(vec4, uint);\n" - "int subgroupClusteredMin(int, uint);\n" - "ivec2 subgroupClusteredMin(ivec2, uint);\n" - "ivec3 subgroupClusteredMin(ivec3, uint);\n" - "ivec4 subgroupClusteredMin(ivec4, uint);\n" - "uint subgroupClusteredMin(uint, uint);\n" - "uvec2 subgroupClusteredMin(uvec2, uint);\n" - "uvec3 subgroupClusteredMin(uvec3, uint);\n" - "uvec4 subgroupClusteredMin(uvec4, uint);\n" - - "float subgroupClusteredMax(float, uint);\n" - "vec2 subgroupClusteredMax(vec2, uint);\n" - "vec3 subgroupClusteredMax(vec3, uint);\n" - "vec4 subgroupClusteredMax(vec4, uint);\n" - "int subgroupClusteredMax(int, uint);\n" - "ivec2 subgroupClusteredMax(ivec2, uint);\n" - "ivec3 subgroupClusteredMax(ivec3, uint);\n" - "ivec4 subgroupClusteredMax(ivec4, uint);\n" - "uint subgroupClusteredMax(uint, uint);\n" - "uvec2 subgroupClusteredMax(uvec2, uint);\n" - "uvec3 subgroupClusteredMax(uvec3, uint);\n" - "uvec4 subgroupClusteredMax(uvec4, uint);\n" - - "int subgroupClusteredAnd(int, uint);\n" - "ivec2 subgroupClusteredAnd(ivec2, uint);\n" - "ivec3 subgroupClusteredAnd(ivec3, uint);\n" - "ivec4 subgroupClusteredAnd(ivec4, uint);\n" - "uint subgroupClusteredAnd(uint, uint);\n" - "uvec2 subgroupClusteredAnd(uvec2, uint);\n" - "uvec3 subgroupClusteredAnd(uvec3, uint);\n" - "uvec4 subgroupClusteredAnd(uvec4, uint);\n" - "bool subgroupClusteredAnd(bool, uint);\n" - "bvec2 subgroupClusteredAnd(bvec2, uint);\n" - "bvec3 subgroupClusteredAnd(bvec3, uint);\n" - "bvec4 subgroupClusteredAnd(bvec4, uint);\n" - - "int subgroupClusteredOr(int, uint);\n" - "ivec2 subgroupClusteredOr(ivec2, uint);\n" - "ivec3 subgroupClusteredOr(ivec3, uint);\n" - "ivec4 subgroupClusteredOr(ivec4, uint);\n" - "uint subgroupClusteredOr(uint, uint);\n" - "uvec2 subgroupClusteredOr(uvec2, uint);\n" - "uvec3 subgroupClusteredOr(uvec3, uint);\n" - "uvec4 subgroupClusteredOr(uvec4, uint);\n" - "bool subgroupClusteredOr(bool, uint);\n" - "bvec2 subgroupClusteredOr(bvec2, uint);\n" - "bvec3 subgroupClusteredOr(bvec3, uint);\n" - "bvec4 subgroupClusteredOr(bvec4, uint);\n" - - "int subgroupClusteredXor(int, uint);\n" - "ivec2 subgroupClusteredXor(ivec2, uint);\n" - "ivec3 subgroupClusteredXor(ivec3, uint);\n" - "ivec4 subgroupClusteredXor(ivec4, uint);\n" - "uint subgroupClusteredXor(uint, uint);\n" - "uvec2 subgroupClusteredXor(uvec2, uint);\n" - "uvec3 subgroupClusteredXor(uvec3, uint);\n" - "uvec4 subgroupClusteredXor(uvec4, uint);\n" - "bool subgroupClusteredXor(bool, uint);\n" - "bvec2 subgroupClusteredXor(bvec2, uint);\n" - "bvec3 subgroupClusteredXor(bvec3, uint);\n" - "bvec4 subgroupClusteredXor(bvec4, uint);\n" - - "float subgroupQuadBroadcast(float, uint);\n" - "vec2 subgroupQuadBroadcast(vec2, uint);\n" - "vec3 subgroupQuadBroadcast(vec3, uint);\n" - "vec4 subgroupQuadBroadcast(vec4, uint);\n" - "int subgroupQuadBroadcast(int, uint);\n" - "ivec2 subgroupQuadBroadcast(ivec2, uint);\n" - "ivec3 subgroupQuadBroadcast(ivec3, uint);\n" - "ivec4 subgroupQuadBroadcast(ivec4, uint);\n" - "uint subgroupQuadBroadcast(uint, uint);\n" - "uvec2 subgroupQuadBroadcast(uvec2, uint);\n" - "uvec3 subgroupQuadBroadcast(uvec3, uint);\n" - "uvec4 subgroupQuadBroadcast(uvec4, uint);\n" - "bool subgroupQuadBroadcast(bool, uint);\n" - "bvec2 subgroupQuadBroadcast(bvec2, uint);\n" - "bvec3 subgroupQuadBroadcast(bvec3, uint);\n" - "bvec4 subgroupQuadBroadcast(bvec4, uint);\n" - - "float subgroupQuadSwapHorizontal(float);\n" - "vec2 subgroupQuadSwapHorizontal(vec2);\n" - "vec3 subgroupQuadSwapHorizontal(vec3);\n" - "vec4 subgroupQuadSwapHorizontal(vec4);\n" - "int subgroupQuadSwapHorizontal(int);\n" - "ivec2 subgroupQuadSwapHorizontal(ivec2);\n" - "ivec3 subgroupQuadSwapHorizontal(ivec3);\n" - "ivec4 subgroupQuadSwapHorizontal(ivec4);\n" - "uint subgroupQuadSwapHorizontal(uint);\n" - "uvec2 subgroupQuadSwapHorizontal(uvec2);\n" - "uvec3 subgroupQuadSwapHorizontal(uvec3);\n" - "uvec4 subgroupQuadSwapHorizontal(uvec4);\n" - "bool subgroupQuadSwapHorizontal(bool);\n" - "bvec2 subgroupQuadSwapHorizontal(bvec2);\n" - "bvec3 subgroupQuadSwapHorizontal(bvec3);\n" - "bvec4 subgroupQuadSwapHorizontal(bvec4);\n" - - "float subgroupQuadSwapVertical(float);\n" - "vec2 subgroupQuadSwapVertical(vec2);\n" - "vec3 subgroupQuadSwapVertical(vec3);\n" - "vec4 subgroupQuadSwapVertical(vec4);\n" - "int subgroupQuadSwapVertical(int);\n" - "ivec2 subgroupQuadSwapVertical(ivec2);\n" - "ivec3 subgroupQuadSwapVertical(ivec3);\n" - "ivec4 subgroupQuadSwapVertical(ivec4);\n" - "uint subgroupQuadSwapVertical(uint);\n" - "uvec2 subgroupQuadSwapVertical(uvec2);\n" - "uvec3 subgroupQuadSwapVertical(uvec3);\n" - "uvec4 subgroupQuadSwapVertical(uvec4);\n" - "bool subgroupQuadSwapVertical(bool);\n" - "bvec2 subgroupQuadSwapVertical(bvec2);\n" - "bvec3 subgroupQuadSwapVertical(bvec3);\n" - "bvec4 subgroupQuadSwapVertical(bvec4);\n" - - "float subgroupQuadSwapDiagonal(float);\n" - "vec2 subgroupQuadSwapDiagonal(vec2);\n" - "vec3 subgroupQuadSwapDiagonal(vec3);\n" - "vec4 subgroupQuadSwapDiagonal(vec4);\n" - "int subgroupQuadSwapDiagonal(int);\n" - "ivec2 subgroupQuadSwapDiagonal(ivec2);\n" - "ivec3 subgroupQuadSwapDiagonal(ivec3);\n" - "ivec4 subgroupQuadSwapDiagonal(ivec4);\n" - "uint subgroupQuadSwapDiagonal(uint);\n" - "uvec2 subgroupQuadSwapDiagonal(uvec2);\n" - "uvec3 subgroupQuadSwapDiagonal(uvec3);\n" - "uvec4 subgroupQuadSwapDiagonal(uvec4);\n" - "bool subgroupQuadSwapDiagonal(bool);\n" - "bvec2 subgroupQuadSwapDiagonal(bvec2);\n" - "bvec3 subgroupQuadSwapDiagonal(bvec3);\n" - "bvec4 subgroupQuadSwapDiagonal(bvec4);\n" - -#ifdef NV_EXTENSIONS - "uvec4 subgroupPartitionNV(float);\n" - "uvec4 subgroupPartitionNV(vec2);\n" - "uvec4 subgroupPartitionNV(vec3);\n" - "uvec4 subgroupPartitionNV(vec4);\n" - "uvec4 subgroupPartitionNV(int);\n" - "uvec4 subgroupPartitionNV(ivec2);\n" - "uvec4 subgroupPartitionNV(ivec3);\n" - "uvec4 subgroupPartitionNV(ivec4);\n" - "uvec4 subgroupPartitionNV(uint);\n" - "uvec4 subgroupPartitionNV(uvec2);\n" - "uvec4 subgroupPartitionNV(uvec3);\n" - "uvec4 subgroupPartitionNV(uvec4);\n" - "uvec4 subgroupPartitionNV(bool);\n" - "uvec4 subgroupPartitionNV(bvec2);\n" - "uvec4 subgroupPartitionNV(bvec3);\n" - "uvec4 subgroupPartitionNV(bvec4);\n" - - "float subgroupPartitionedAddNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedAddNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedAddNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedAddNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedAddNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedAddNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedAddNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedAddNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedAddNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedAddNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedAddNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedAddNV(uvec4, uvec4 ballot);\n" - - "float subgroupPartitionedMulNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedMulNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedMulNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedMulNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedMulNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedMulNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedMulNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedMulNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedMulNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedMulNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedMulNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedMulNV(uvec4, uvec4 ballot);\n" - - "float subgroupPartitionedMinNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedMinNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedMinNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedMinNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedMinNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedMinNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedMinNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedMinNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedMinNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedMinNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedMinNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedMinNV(uvec4, uvec4 ballot);\n" - - "float subgroupPartitionedMaxNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedMaxNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedMaxNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedMaxNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedMaxNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedMaxNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedMaxNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedMaxNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedMaxNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedMaxNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedMaxNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedMaxNV(uvec4, uvec4 ballot);\n" - - "int subgroupPartitionedAndNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedAndNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedAndNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedAndNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedAndNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedAndNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedAndNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedAndNV(uvec4, uvec4 ballot);\n" - "bool subgroupPartitionedAndNV(bool, uvec4 ballot);\n" - "bvec2 subgroupPartitionedAndNV(bvec2, uvec4 ballot);\n" - "bvec3 subgroupPartitionedAndNV(bvec3, uvec4 ballot);\n" - "bvec4 subgroupPartitionedAndNV(bvec4, uvec4 ballot);\n" - - "int subgroupPartitionedOrNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedOrNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedOrNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedOrNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedOrNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedOrNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedOrNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedOrNV(uvec4, uvec4 ballot);\n" - "bool subgroupPartitionedOrNV(bool, uvec4 ballot);\n" - "bvec2 subgroupPartitionedOrNV(bvec2, uvec4 ballot);\n" - "bvec3 subgroupPartitionedOrNV(bvec3, uvec4 ballot);\n" - "bvec4 subgroupPartitionedOrNV(bvec4, uvec4 ballot);\n" - - "int subgroupPartitionedXorNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedXorNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedXorNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedXorNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedXorNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedXorNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedXorNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedXorNV(uvec4, uvec4 ballot);\n" - "bool subgroupPartitionedXorNV(bool, uvec4 ballot);\n" - "bvec2 subgroupPartitionedXorNV(bvec2, uvec4 ballot);\n" - "bvec3 subgroupPartitionedXorNV(bvec3, uvec4 ballot);\n" - "bvec4 subgroupPartitionedXorNV(bvec4, uvec4 ballot);\n" - - "float subgroupPartitionedInclusiveAddNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedInclusiveAddNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedInclusiveAddNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedInclusiveAddNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedInclusiveAddNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedInclusiveAddNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedInclusiveAddNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedInclusiveAddNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedInclusiveAddNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedInclusiveAddNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedInclusiveAddNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedInclusiveAddNV(uvec4, uvec4 ballot);\n" - - "float subgroupPartitionedInclusiveMulNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedInclusiveMulNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedInclusiveMulNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedInclusiveMulNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedInclusiveMulNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedInclusiveMulNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedInclusiveMulNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedInclusiveMulNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedInclusiveMulNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedInclusiveMulNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedInclusiveMulNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedInclusiveMulNV(uvec4, uvec4 ballot);\n" - - "float subgroupPartitionedInclusiveMinNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedInclusiveMinNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedInclusiveMinNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedInclusiveMinNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedInclusiveMinNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedInclusiveMinNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedInclusiveMinNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedInclusiveMinNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedInclusiveMinNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedInclusiveMinNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedInclusiveMinNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedInclusiveMinNV(uvec4, uvec4 ballot);\n" - - "float subgroupPartitionedInclusiveMaxNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedInclusiveMaxNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedInclusiveMaxNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedInclusiveMaxNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedInclusiveMaxNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedInclusiveMaxNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedInclusiveMaxNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedInclusiveMaxNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedInclusiveMaxNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedInclusiveMaxNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedInclusiveMaxNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedInclusiveMaxNV(uvec4, uvec4 ballot);\n" - - "int subgroupPartitionedInclusiveAndNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedInclusiveAndNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedInclusiveAndNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedInclusiveAndNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedInclusiveAndNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedInclusiveAndNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedInclusiveAndNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedInclusiveAndNV(uvec4, uvec4 ballot);\n" - "bool subgroupPartitionedInclusiveAndNV(bool, uvec4 ballot);\n" - "bvec2 subgroupPartitionedInclusiveAndNV(bvec2, uvec4 ballot);\n" - "bvec3 subgroupPartitionedInclusiveAndNV(bvec3, uvec4 ballot);\n" - "bvec4 subgroupPartitionedInclusiveAndNV(bvec4, uvec4 ballot);\n" - - "int subgroupPartitionedInclusiveOrNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedInclusiveOrNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedInclusiveOrNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedInclusiveOrNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedInclusiveOrNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedInclusiveOrNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedInclusiveOrNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedInclusiveOrNV(uvec4, uvec4 ballot);\n" - "bool subgroupPartitionedInclusiveOrNV(bool, uvec4 ballot);\n" - "bvec2 subgroupPartitionedInclusiveOrNV(bvec2, uvec4 ballot);\n" - "bvec3 subgroupPartitionedInclusiveOrNV(bvec3, uvec4 ballot);\n" - "bvec4 subgroupPartitionedInclusiveOrNV(bvec4, uvec4 ballot);\n" - - "int subgroupPartitionedInclusiveXorNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedInclusiveXorNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedInclusiveXorNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedInclusiveXorNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedInclusiveXorNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedInclusiveXorNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedInclusiveXorNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedInclusiveXorNV(uvec4, uvec4 ballot);\n" - "bool subgroupPartitionedInclusiveXorNV(bool, uvec4 ballot);\n" - "bvec2 subgroupPartitionedInclusiveXorNV(bvec2, uvec4 ballot);\n" - "bvec3 subgroupPartitionedInclusiveXorNV(bvec3, uvec4 ballot);\n" - "bvec4 subgroupPartitionedInclusiveXorNV(bvec4, uvec4 ballot);\n" - - "float subgroupPartitionedExclusiveAddNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedExclusiveAddNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedExclusiveAddNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedExclusiveAddNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedExclusiveAddNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedExclusiveAddNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedExclusiveAddNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedExclusiveAddNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedExclusiveAddNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedExclusiveAddNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedExclusiveAddNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedExclusiveAddNV(uvec4, uvec4 ballot);\n" - - "float subgroupPartitionedExclusiveMulNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedExclusiveMulNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedExclusiveMulNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedExclusiveMulNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedExclusiveMulNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedExclusiveMulNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedExclusiveMulNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedExclusiveMulNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedExclusiveMulNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedExclusiveMulNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedExclusiveMulNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedExclusiveMulNV(uvec4, uvec4 ballot);\n" - - "float subgroupPartitionedExclusiveMinNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedExclusiveMinNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedExclusiveMinNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedExclusiveMinNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedExclusiveMinNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedExclusiveMinNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedExclusiveMinNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedExclusiveMinNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedExclusiveMinNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedExclusiveMinNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedExclusiveMinNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedExclusiveMinNV(uvec4, uvec4 ballot);\n" - - "float subgroupPartitionedExclusiveMaxNV(float, uvec4 ballot);\n" - "vec2 subgroupPartitionedExclusiveMaxNV(vec2, uvec4 ballot);\n" - "vec3 subgroupPartitionedExclusiveMaxNV(vec3, uvec4 ballot);\n" - "vec4 subgroupPartitionedExclusiveMaxNV(vec4, uvec4 ballot);\n" - "int subgroupPartitionedExclusiveMaxNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedExclusiveMaxNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedExclusiveMaxNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedExclusiveMaxNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedExclusiveMaxNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedExclusiveMaxNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedExclusiveMaxNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedExclusiveMaxNV(uvec4, uvec4 ballot);\n" - - "int subgroupPartitionedExclusiveAndNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedExclusiveAndNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedExclusiveAndNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedExclusiveAndNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedExclusiveAndNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedExclusiveAndNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedExclusiveAndNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedExclusiveAndNV(uvec4, uvec4 ballot);\n" - "bool subgroupPartitionedExclusiveAndNV(bool, uvec4 ballot);\n" - "bvec2 subgroupPartitionedExclusiveAndNV(bvec2, uvec4 ballot);\n" - "bvec3 subgroupPartitionedExclusiveAndNV(bvec3, uvec4 ballot);\n" - "bvec4 subgroupPartitionedExclusiveAndNV(bvec4, uvec4 ballot);\n" - - "int subgroupPartitionedExclusiveOrNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedExclusiveOrNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedExclusiveOrNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedExclusiveOrNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedExclusiveOrNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedExclusiveOrNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedExclusiveOrNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedExclusiveOrNV(uvec4, uvec4 ballot);\n" - "bool subgroupPartitionedExclusiveOrNV(bool, uvec4 ballot);\n" - "bvec2 subgroupPartitionedExclusiveOrNV(bvec2, uvec4 ballot);\n" - "bvec3 subgroupPartitionedExclusiveOrNV(bvec3, uvec4 ballot);\n" - "bvec4 subgroupPartitionedExclusiveOrNV(bvec4, uvec4 ballot);\n" - - "int subgroupPartitionedExclusiveXorNV(int, uvec4 ballot);\n" - "ivec2 subgroupPartitionedExclusiveXorNV(ivec2, uvec4 ballot);\n" - "ivec3 subgroupPartitionedExclusiveXorNV(ivec3, uvec4 ballot);\n" - "ivec4 subgroupPartitionedExclusiveXorNV(ivec4, uvec4 ballot);\n" - "uint subgroupPartitionedExclusiveXorNV(uint, uvec4 ballot);\n" - "uvec2 subgroupPartitionedExclusiveXorNV(uvec2, uvec4 ballot);\n" - "uvec3 subgroupPartitionedExclusiveXorNV(uvec3, uvec4 ballot);\n" - "uvec4 subgroupPartitionedExclusiveXorNV(uvec4, uvec4 ballot);\n" - "bool subgroupPartitionedExclusiveXorNV(bool, uvec4 ballot);\n" - "bvec2 subgroupPartitionedExclusiveXorNV(bvec2, uvec4 ballot);\n" - "bvec3 subgroupPartitionedExclusiveXorNV(bvec3, uvec4 ballot);\n" - "bvec4 subgroupPartitionedExclusiveXorNV(bvec4, uvec4 ballot);\n" -#endif - - "\n"); - - if (profile != EEsProfile && version >= 400) { - commonBuiltins.append( - "bool subgroupAllEqual(double);\n" - "bool subgroupAllEqual(dvec2);\n" - "bool subgroupAllEqual(dvec3);\n" - "bool subgroupAllEqual(dvec4);\n" - - "double subgroupBroadcast(double, uint);\n" - "dvec2 subgroupBroadcast(dvec2, uint);\n" - "dvec3 subgroupBroadcast(dvec3, uint);\n" - "dvec4 subgroupBroadcast(dvec4, uint);\n" - - "double subgroupBroadcastFirst(double);\n" - "dvec2 subgroupBroadcastFirst(dvec2);\n" - "dvec3 subgroupBroadcastFirst(dvec3);\n" - "dvec4 subgroupBroadcastFirst(dvec4);\n" - - "double subgroupShuffle(double, uint);\n" - "dvec2 subgroupShuffle(dvec2, uint);\n" - "dvec3 subgroupShuffle(dvec3, uint);\n" - "dvec4 subgroupShuffle(dvec4, uint);\n" - - "double subgroupShuffleXor(double, uint);\n" - "dvec2 subgroupShuffleXor(dvec2, uint);\n" - "dvec3 subgroupShuffleXor(dvec3, uint);\n" - "dvec4 subgroupShuffleXor(dvec4, uint);\n" - - "double subgroupShuffleUp(double, uint delta);\n" - "dvec2 subgroupShuffleUp(dvec2, uint delta);\n" - "dvec3 subgroupShuffleUp(dvec3, uint delta);\n" - "dvec4 subgroupShuffleUp(dvec4, uint delta);\n" - - "double subgroupShuffleDown(double, uint delta);\n" - "dvec2 subgroupShuffleDown(dvec2, uint delta);\n" - "dvec3 subgroupShuffleDown(dvec3, uint delta);\n" - "dvec4 subgroupShuffleDown(dvec4, uint delta);\n" - - "double subgroupAdd(double);\n" - "dvec2 subgroupAdd(dvec2);\n" - "dvec3 subgroupAdd(dvec3);\n" - "dvec4 subgroupAdd(dvec4);\n" - - "double subgroupMul(double);\n" - "dvec2 subgroupMul(dvec2);\n" - "dvec3 subgroupMul(dvec3);\n" - "dvec4 subgroupMul(dvec4);\n" - - "double subgroupMin(double);\n" - "dvec2 subgroupMin(dvec2);\n" - "dvec3 subgroupMin(dvec3);\n" - "dvec4 subgroupMin(dvec4);\n" - - "double subgroupMax(double);\n" - "dvec2 subgroupMax(dvec2);\n" - "dvec3 subgroupMax(dvec3);\n" - "dvec4 subgroupMax(dvec4);\n" - - "double subgroupInclusiveAdd(double);\n" - "dvec2 subgroupInclusiveAdd(dvec2);\n" - "dvec3 subgroupInclusiveAdd(dvec3);\n" - "dvec4 subgroupInclusiveAdd(dvec4);\n" - - "double subgroupInclusiveMul(double);\n" - "dvec2 subgroupInclusiveMul(dvec2);\n" - "dvec3 subgroupInclusiveMul(dvec3);\n" - "dvec4 subgroupInclusiveMul(dvec4);\n" - - "double subgroupInclusiveMin(double);\n" - "dvec2 subgroupInclusiveMin(dvec2);\n" - "dvec3 subgroupInclusiveMin(dvec3);\n" - "dvec4 subgroupInclusiveMin(dvec4);\n" - - "double subgroupInclusiveMax(double);\n" - "dvec2 subgroupInclusiveMax(dvec2);\n" - "dvec3 subgroupInclusiveMax(dvec3);\n" - "dvec4 subgroupInclusiveMax(dvec4);\n" - - "double subgroupExclusiveAdd(double);\n" - "dvec2 subgroupExclusiveAdd(dvec2);\n" - "dvec3 subgroupExclusiveAdd(dvec3);\n" - "dvec4 subgroupExclusiveAdd(dvec4);\n" - - "double subgroupExclusiveMul(double);\n" - "dvec2 subgroupExclusiveMul(dvec2);\n" - "dvec3 subgroupExclusiveMul(dvec3);\n" - "dvec4 subgroupExclusiveMul(dvec4);\n" - - "double subgroupExclusiveMin(double);\n" - "dvec2 subgroupExclusiveMin(dvec2);\n" - "dvec3 subgroupExclusiveMin(dvec3);\n" - "dvec4 subgroupExclusiveMin(dvec4);\n" - - "double subgroupExclusiveMax(double);\n" - "dvec2 subgroupExclusiveMax(dvec2);\n" - "dvec3 subgroupExclusiveMax(dvec3);\n" - "dvec4 subgroupExclusiveMax(dvec4);\n" - - "double subgroupClusteredAdd(double, uint);\n" - "dvec2 subgroupClusteredAdd(dvec2, uint);\n" - "dvec3 subgroupClusteredAdd(dvec3, uint);\n" - "dvec4 subgroupClusteredAdd(dvec4, uint);\n" - - "double subgroupClusteredMul(double, uint);\n" - "dvec2 subgroupClusteredMul(dvec2, uint);\n" - "dvec3 subgroupClusteredMul(dvec3, uint);\n" - "dvec4 subgroupClusteredMul(dvec4, uint);\n" - - "double subgroupClusteredMin(double, uint);\n" - "dvec2 subgroupClusteredMin(dvec2, uint);\n" - "dvec3 subgroupClusteredMin(dvec3, uint);\n" - "dvec4 subgroupClusteredMin(dvec4, uint);\n" - - "double subgroupClusteredMax(double, uint);\n" - "dvec2 subgroupClusteredMax(dvec2, uint);\n" - "dvec3 subgroupClusteredMax(dvec3, uint);\n" - "dvec4 subgroupClusteredMax(dvec4, uint);\n" - - "double subgroupQuadBroadcast(double, uint);\n" - "dvec2 subgroupQuadBroadcast(dvec2, uint);\n" - "dvec3 subgroupQuadBroadcast(dvec3, uint);\n" - "dvec4 subgroupQuadBroadcast(dvec4, uint);\n" - - "double subgroupQuadSwapHorizontal(double);\n" - "dvec2 subgroupQuadSwapHorizontal(dvec2);\n" - "dvec3 subgroupQuadSwapHorizontal(dvec3);\n" - "dvec4 subgroupQuadSwapHorizontal(dvec4);\n" - - "double subgroupQuadSwapVertical(double);\n" - "dvec2 subgroupQuadSwapVertical(dvec2);\n" - "dvec3 subgroupQuadSwapVertical(dvec3);\n" - "dvec4 subgroupQuadSwapVertical(dvec4);\n" - - "double subgroupQuadSwapDiagonal(double);\n" - "dvec2 subgroupQuadSwapDiagonal(dvec2);\n" - "dvec3 subgroupQuadSwapDiagonal(dvec3);\n" - "dvec4 subgroupQuadSwapDiagonal(dvec4);\n" - - -#ifdef NV_EXTENSIONS - "uvec4 subgroupPartitionNV(double);\n" - "uvec4 subgroupPartitionNV(dvec2);\n" - "uvec4 subgroupPartitionNV(dvec3);\n" - "uvec4 subgroupPartitionNV(dvec4);\n" - - "double subgroupPartitionedAddNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedAddNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedAddNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedAddNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedMulNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedMulNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedMulNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedMulNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedMinNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedMinNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedMinNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedMinNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedMaxNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedMaxNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedMaxNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedMaxNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedInclusiveAddNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedInclusiveAddNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedInclusiveAddNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedInclusiveAddNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedInclusiveMulNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedInclusiveMulNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedInclusiveMulNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedInclusiveMulNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedInclusiveMinNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedInclusiveMinNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedInclusiveMinNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedInclusiveMinNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedInclusiveMaxNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedInclusiveMaxNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedInclusiveMaxNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedInclusiveMaxNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedExclusiveAddNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedExclusiveAddNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedExclusiveAddNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedExclusiveAddNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedExclusiveMulNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedExclusiveMulNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedExclusiveMulNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedExclusiveMulNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedExclusiveMinNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedExclusiveMinNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedExclusiveMinNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedExclusiveMinNV(dvec4, uvec4 ballot);\n" - - "double subgroupPartitionedExclusiveMaxNV(double, uvec4 ballot);\n" - "dvec2 subgroupPartitionedExclusiveMaxNV(dvec2, uvec4 ballot);\n" - "dvec3 subgroupPartitionedExclusiveMaxNV(dvec3, uvec4 ballot);\n" - "dvec4 subgroupPartitionedExclusiveMaxNV(dvec4, uvec4 ballot);\n" -#endif - - "\n"); + ); + + // Generate all flavors of subgroup ops. + static const char *subgroupOps[] = + { + "bool subgroupAllEqual(%s);\n", + "%s subgroupBroadcast(%s, uint);\n", + "%s subgroupBroadcastFirst(%s);\n", + "%s subgroupShuffle(%s, uint);\n", + "%s subgroupShuffleXor(%s, uint);\n", + "%s subgroupShuffleUp(%s, uint delta);\n", + "%s subgroupShuffleDown(%s, uint delta);\n", + "%s subgroupAdd(%s);\n", + "%s subgroupMul(%s);\n", + "%s subgroupMin(%s);\n", + "%s subgroupMax(%s);\n", + "%s subgroupAnd(%s);\n", + "%s subgroupOr(%s);\n", + "%s subgroupXor(%s);\n", + "%s subgroupInclusiveAdd(%s);\n", + "%s subgroupInclusiveMul(%s);\n", + "%s subgroupInclusiveMin(%s);\n", + "%s subgroupInclusiveMax(%s);\n", + "%s subgroupInclusiveAnd(%s);\n", + "%s subgroupInclusiveOr(%s);\n", + "%s subgroupInclusiveXor(%s);\n", + "%s subgroupExclusiveAdd(%s);\n", + "%s subgroupExclusiveMul(%s);\n", + "%s subgroupExclusiveMin(%s);\n", + "%s subgroupExclusiveMax(%s);\n", + "%s subgroupExclusiveAnd(%s);\n", + "%s subgroupExclusiveOr(%s);\n", + "%s subgroupExclusiveXor(%s);\n", + "%s subgroupClusteredAdd(%s, uint);\n", + "%s subgroupClusteredMul(%s, uint);\n", + "%s subgroupClusteredMin(%s, uint);\n", + "%s subgroupClusteredMax(%s, uint);\n", + "%s subgroupClusteredAnd(%s, uint);\n", + "%s subgroupClusteredOr(%s, uint);\n", + "%s subgroupClusteredXor(%s, uint);\n", + "%s subgroupQuadBroadcast(%s, uint);\n", + "%s subgroupQuadSwapHorizontal(%s);\n", + "%s subgroupQuadSwapVertical(%s);\n", + "%s subgroupQuadSwapDiagonal(%s);\n", + "uvec4 subgroupPartitionNV(%s);\n", + "%s subgroupPartitionedAddNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedMulNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedMinNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedMaxNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedAndNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedOrNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedXorNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveAddNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveMulNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveMinNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveMaxNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveAndNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveOrNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveXorNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveAddNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveMulNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveMinNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveMaxNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveAndNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveOrNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveXorNV(%s, uvec4 ballot);\n", + }; + + static const char *floatTypes[] = { + "float", "vec2", "vec3", "vec4", + "float16_t", "f16vec2", "f16vec3", "f16vec4", + }; + static const char *doubleTypes[] = { + "double", "dvec2", "dvec3", "dvec4", + }; + static const char *intTypes[] = { + "int8_t", "i8vec2", "i8vec3", "i8vec4", + "int16_t", "i16vec2", "i16vec3", "i16vec4", + "int", "ivec2", "ivec3", "ivec4", + "int64_t", "i64vec2", "i64vec3", "i64vec4", + "uint8_t", "u8vec2", "u8vec3", "u8vec4", + "uint16_t", "u16vec2", "u16vec3", "u16vec4", + "uint", "uvec2", "uvec3", "uvec4", + "uint64_t", "u64vec2", "u64vec3", "u64vec4", + }; + static const char *boolTypes[] = { + "bool", "bvec2", "bvec3", "bvec4", + }; + + for (size_t i = 0; i < sizeof(subgroupOps)/sizeof(subgroupOps[0]); ++i) { + const char *op = subgroupOps[i]; + + // Logical operations don't support float + bool logicalOp = strstr(op, "Or") || strstr(op, "And") || + (strstr(op, "Xor") && !strstr(op, "ShuffleXor")); + // Math operations don't support bool + bool mathOp = strstr(op, "Add") || strstr(op, "Mul") || strstr(op, "Min") || strstr(op, "Max"); + + const int bufSize = 256; + char buf[bufSize]; + + if (!logicalOp) { + for (size_t j = 0; j < sizeof(floatTypes)/sizeof(floatTypes[0]); ++j) { + snprintf(buf, bufSize, op, floatTypes[j], floatTypes[j]); + commonBuiltins.append(buf); + } + if (profile != EEsProfile && version >= 400) { + for (size_t j = 0; j < sizeof(doubleTypes)/sizeof(doubleTypes[0]); ++j) { + snprintf(buf, bufSize, op, doubleTypes[j], doubleTypes[j]); + commonBuiltins.append(buf); + } + } } + if (!mathOp) { + for (size_t j = 0; j < sizeof(boolTypes)/sizeof(boolTypes[0]); ++j) { + snprintf(buf, bufSize, op, boolTypes[j], boolTypes[j]); + commonBuiltins.append(buf); + } + } + for (size_t j = 0; j < sizeof(intTypes)/sizeof(intTypes[0]); ++j) { + snprintf(buf, bufSize, op, intTypes[j], intTypes[j]); + commonBuiltins.append(buf); + } + } stageBuiltins[EShLangCompute].append( "void subgroupMemoryBarrierShared();" "\n" ); -#ifdef NV_EXTENSIONS stageBuiltins[EShLangMeshNV].append( "void subgroupMemoryBarrierShared();" "\n" @@ -2960,7 +2275,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void subgroupMemoryBarrierShared();" "\n" ); -#endif } if (profile != EEsProfile && version >= 460) { @@ -2972,7 +2286,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifdef AMD_EXTENSIONS // GL_AMD_shader_ballot if (profile != EEsProfile && version >= 450) { commonBuiltins.append( @@ -3837,12 +3150,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } // GL_AMD_gcn_shader - if (profile != EEsProfile && version >= 450) { + if (profile != EEsProfile && version >= 440) { commonBuiltins.append( "float cubeFaceIndexAMD(vec3);" "vec2 cubeFaceCoordAMD(vec3);" "uint64_t timeAMD();" + "in int gl_SIMDGroupSizeAMD;" "\n"); } @@ -3868,11 +3182,182 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#endif // AMD_EXTENSIONS + if ((profile != EEsProfile && version >= 130) || + (profile == EEsProfile && version >= 300)) { + commonBuiltins.append( + "uint countLeadingZeros(uint);" + "uvec2 countLeadingZeros(uvec2);" + "uvec3 countLeadingZeros(uvec3);" + "uvec4 countLeadingZeros(uvec4);" + "uint countTrailingZeros(uint);" + "uvec2 countTrailingZeros(uvec2);" + "uvec3 countTrailingZeros(uvec3);" + "uvec4 countTrailingZeros(uvec4);" -#ifdef NV_EXTENSIONS - if ((profile != EEsProfile && version >= 450) || + "uint absoluteDifference(int, int);" + "uvec2 absoluteDifference(ivec2, ivec2);" + "uvec3 absoluteDifference(ivec3, ivec3);" + "uvec4 absoluteDifference(ivec4, ivec4);" + + "uint16_t absoluteDifference(int16_t, int16_t);" + "u16vec2 absoluteDifference(i16vec2, i16vec2);" + "u16vec3 absoluteDifference(i16vec3, i16vec3);" + "u16vec4 absoluteDifference(i16vec4, i16vec4);" + + "uint64_t absoluteDifference(int64_t, int64_t);" + "u64vec2 absoluteDifference(i64vec2, i64vec2);" + "u64vec3 absoluteDifference(i64vec3, i64vec3);" + "u64vec4 absoluteDifference(i64vec4, i64vec4);" + + "uint absoluteDifference(uint, uint);" + "uvec2 absoluteDifference(uvec2, uvec2);" + "uvec3 absoluteDifference(uvec3, uvec3);" + "uvec4 absoluteDifference(uvec4, uvec4);" + + "uint16_t absoluteDifference(uint16_t, uint16_t);" + "u16vec2 absoluteDifference(u16vec2, u16vec2);" + "u16vec3 absoluteDifference(u16vec3, u16vec3);" + "u16vec4 absoluteDifference(u16vec4, u16vec4);" + + "uint64_t absoluteDifference(uint64_t, uint64_t);" + "u64vec2 absoluteDifference(u64vec2, u64vec2);" + "u64vec3 absoluteDifference(u64vec3, u64vec3);" + "u64vec4 absoluteDifference(u64vec4, u64vec4);" + + "int addSaturate(int, int);" + "ivec2 addSaturate(ivec2, ivec2);" + "ivec3 addSaturate(ivec3, ivec3);" + "ivec4 addSaturate(ivec4, ivec4);" + + "int16_t addSaturate(int16_t, int16_t);" + "i16vec2 addSaturate(i16vec2, i16vec2);" + "i16vec3 addSaturate(i16vec3, i16vec3);" + "i16vec4 addSaturate(i16vec4, i16vec4);" + + "int64_t addSaturate(int64_t, int64_t);" + "i64vec2 addSaturate(i64vec2, i64vec2);" + "i64vec3 addSaturate(i64vec3, i64vec3);" + "i64vec4 addSaturate(i64vec4, i64vec4);" + + "uint addSaturate(uint, uint);" + "uvec2 addSaturate(uvec2, uvec2);" + "uvec3 addSaturate(uvec3, uvec3);" + "uvec4 addSaturate(uvec4, uvec4);" + + "uint16_t addSaturate(uint16_t, uint16_t);" + "u16vec2 addSaturate(u16vec2, u16vec2);" + "u16vec3 addSaturate(u16vec3, u16vec3);" + "u16vec4 addSaturate(u16vec4, u16vec4);" + + "uint64_t addSaturate(uint64_t, uint64_t);" + "u64vec2 addSaturate(u64vec2, u64vec2);" + "u64vec3 addSaturate(u64vec3, u64vec3);" + "u64vec4 addSaturate(u64vec4, u64vec4);" + + "int subtractSaturate(int, int);" + "ivec2 subtractSaturate(ivec2, ivec2);" + "ivec3 subtractSaturate(ivec3, ivec3);" + "ivec4 subtractSaturate(ivec4, ivec4);" + + "int16_t subtractSaturate(int16_t, int16_t);" + "i16vec2 subtractSaturate(i16vec2, i16vec2);" + "i16vec3 subtractSaturate(i16vec3, i16vec3);" + "i16vec4 subtractSaturate(i16vec4, i16vec4);" + + "int64_t subtractSaturate(int64_t, int64_t);" + "i64vec2 subtractSaturate(i64vec2, i64vec2);" + "i64vec3 subtractSaturate(i64vec3, i64vec3);" + "i64vec4 subtractSaturate(i64vec4, i64vec4);" + + "uint subtractSaturate(uint, uint);" + "uvec2 subtractSaturate(uvec2, uvec2);" + "uvec3 subtractSaturate(uvec3, uvec3);" + "uvec4 subtractSaturate(uvec4, uvec4);" + + "uint16_t subtractSaturate(uint16_t, uint16_t);" + "u16vec2 subtractSaturate(u16vec2, u16vec2);" + "u16vec3 subtractSaturate(u16vec3, u16vec3);" + "u16vec4 subtractSaturate(u16vec4, u16vec4);" + + "uint64_t subtractSaturate(uint64_t, uint64_t);" + "u64vec2 subtractSaturate(u64vec2, u64vec2);" + "u64vec3 subtractSaturate(u64vec3, u64vec3);" + "u64vec4 subtractSaturate(u64vec4, u64vec4);" + + "int average(int, int);" + "ivec2 average(ivec2, ivec2);" + "ivec3 average(ivec3, ivec3);" + "ivec4 average(ivec4, ivec4);" + + "int16_t average(int16_t, int16_t);" + "i16vec2 average(i16vec2, i16vec2);" + "i16vec3 average(i16vec3, i16vec3);" + "i16vec4 average(i16vec4, i16vec4);" + + "int64_t average(int64_t, int64_t);" + "i64vec2 average(i64vec2, i64vec2);" + "i64vec3 average(i64vec3, i64vec3);" + "i64vec4 average(i64vec4, i64vec4);" + + "uint average(uint, uint);" + "uvec2 average(uvec2, uvec2);" + "uvec3 average(uvec3, uvec3);" + "uvec4 average(uvec4, uvec4);" + + "uint16_t average(uint16_t, uint16_t);" + "u16vec2 average(u16vec2, u16vec2);" + "u16vec3 average(u16vec3, u16vec3);" + "u16vec4 average(u16vec4, u16vec4);" + + "uint64_t average(uint64_t, uint64_t);" + "u64vec2 average(u64vec2, u64vec2);" + "u64vec3 average(u64vec3, u64vec3);" + "u64vec4 average(u64vec4, u64vec4);" + + "int averageRounded(int, int);" + "ivec2 averageRounded(ivec2, ivec2);" + "ivec3 averageRounded(ivec3, ivec3);" + "ivec4 averageRounded(ivec4, ivec4);" + + "int16_t averageRounded(int16_t, int16_t);" + "i16vec2 averageRounded(i16vec2, i16vec2);" + "i16vec3 averageRounded(i16vec3, i16vec3);" + "i16vec4 averageRounded(i16vec4, i16vec4);" + + "int64_t averageRounded(int64_t, int64_t);" + "i64vec2 averageRounded(i64vec2, i64vec2);" + "i64vec3 averageRounded(i64vec3, i64vec3);" + "i64vec4 averageRounded(i64vec4, i64vec4);" + + "uint averageRounded(uint, uint);" + "uvec2 averageRounded(uvec2, uvec2);" + "uvec3 averageRounded(uvec3, uvec3);" + "uvec4 averageRounded(uvec4, uvec4);" + + "uint16_t averageRounded(uint16_t, uint16_t);" + "u16vec2 averageRounded(u16vec2, u16vec2);" + "u16vec3 averageRounded(u16vec3, u16vec3);" + "u16vec4 averageRounded(u16vec4, u16vec4);" + + "uint64_t averageRounded(uint64_t, uint64_t);" + "u64vec2 averageRounded(u64vec2, u64vec2);" + "u64vec3 averageRounded(u64vec3, u64vec3);" + "u64vec4 averageRounded(u64vec4, u64vec4);" + + "int multiply32x16(int, int);" + "ivec2 multiply32x16(ivec2, ivec2);" + "ivec3 multiply32x16(ivec3, ivec3);" + "ivec4 multiply32x16(ivec4, ivec4);" + + "uint multiply32x16(uint, uint);" + "uvec2 multiply32x16(uvec2, uvec2);" + "uvec3 multiply32x16(uvec3, uvec3);" + "uvec4 multiply32x16(uvec4, uvec4);" + "\n"); + } + + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { commonBuiltins.append( "struct gl_TextureFootprint2DNV {" @@ -3904,10 +3389,29 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "bool textureFootprintGradClampNV(sampler2D, vec2, vec2, vec2, float, int, bool, out gl_TextureFootprint2DNV);" "\n"); } +#endif // !GLSLANG_ANGLE -#endif // NV_EXTENSIONS + if ((profile == EEsProfile && version >= 300 && version < 310) || + (profile != EEsProfile && version >= 150 && version < 450)) { // GL_EXT_shader_integer_mix + commonBuiltins.append("int mix(int, int, bool);" + "ivec2 mix(ivec2, ivec2, bvec2);" + "ivec3 mix(ivec3, ivec3, bvec3);" + "ivec4 mix(ivec4, ivec4, bvec4);" + "uint mix(uint, uint, bool );" + "uvec2 mix(uvec2, uvec2, bvec2);" + "uvec3 mix(uvec3, uvec3, bvec3);" + "uvec4 mix(uvec4, uvec4, bvec4);" + "bool mix(bool, bool, bool );" + "bvec2 mix(bvec2, bvec2, bvec2);" + "bvec3 mix(bvec3, bvec3, bvec3);" + "bvec4 mix(bvec4, bvec4, bvec4);" + + "\n"); + } + +#ifndef GLSLANG_ANGLE // GL_AMD_gpu_shader_half_float/Explicit types - if (profile != EEsProfile && version >= 450) { + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) { commonBuiltins.append( "float16_t radians(float16_t);" "f16vec2 radians(f16vec2);" @@ -4255,7 +3759,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } // Explicit types - if (profile != EEsProfile && version >= 450) { + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) { commonBuiltins.append( "int8_t abs(int8_t);" "i8vec2 abs(i8vec2);" @@ -4756,28 +4260,30 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "f64vec3 log2(f64vec3);" "f64vec4 log2(f64vec4);" "\n"); - } - if (profile != EEsProfile && version >= 450) { - stageBuiltins[EShLangFragment].append(derivativesAndControl64bits); - stageBuiltins[EShLangFragment].append( - "float64_t interpolateAtCentroid(float64_t);" - "f64vec2 interpolateAtCentroid(f64vec2);" - "f64vec3 interpolateAtCentroid(f64vec3);" - "f64vec4 interpolateAtCentroid(f64vec4);" + } - "float64_t interpolateAtSample(float64_t, int);" - "f64vec2 interpolateAtSample(f64vec2, int);" - "f64vec3 interpolateAtSample(f64vec3, int);" - "f64vec4 interpolateAtSample(f64vec4, int);" + if (profile != EEsProfile && version >= 450) { + stageBuiltins[EShLangFragment].append(derivativesAndControl64bits); + stageBuiltins[EShLangFragment].append( + "float64_t interpolateAtCentroid(float64_t);" + "f64vec2 interpolateAtCentroid(f64vec2);" + "f64vec3 interpolateAtCentroid(f64vec3);" + "f64vec4 interpolateAtCentroid(f64vec4);" - "float64_t interpolateAtOffset(float64_t, f64vec2);" - "f64vec2 interpolateAtOffset(f64vec2, f64vec2);" - "f64vec3 interpolateAtOffset(f64vec3, f64vec2);" - "f64vec4 interpolateAtOffset(f64vec4, f64vec2);" + "float64_t interpolateAtSample(float64_t, int);" + "f64vec2 interpolateAtSample(f64vec2, int);" + "f64vec3 interpolateAtSample(f64vec3, int);" + "f64vec4 interpolateAtSample(f64vec4, int);" - "\n"); + "float64_t interpolateAtOffset(float64_t, f64vec2);" + "f64vec2 interpolateAtOffset(f64vec2, f64vec2);" + "f64vec3 interpolateAtOffset(f64vec3, f64vec2);" + "f64vec4 interpolateAtOffset(f64vec4, f64vec2);" + + "\n"); } +#endif // !GLSLANG_ANGLE //============================================================================ // @@ -4790,9 +4296,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV // // Geometric Functions. // - if (IncludeLegacy(version, profile, spvVersion)) + if (spvVersion.vulkan == 0 && IncludeLegacy(version, profile, spvVersion)) stageBuiltins[EShLangVertex].append("vec4 ftransform();"); +#ifndef GLSLANG_ANGLE // // Original-style texture Functions with lod. // @@ -4852,6 +4359,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } } +#endif // !GLSLANG_ANGLE if ((profile != EEsProfile && version >= 150) || (profile == EEsProfile && version >= 310)) { @@ -4872,6 +4380,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void EndPrimitive();" "\n"); } +#endif // !GLSLANG_WEB //============================================================================ // @@ -4887,7 +4396,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangCompute].append( "void barrier();" ); -#ifdef NV_EXTENSIONS if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { stageBuiltins[EShLangMeshNV].append( "void barrier();" @@ -4896,23 +4404,26 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void barrier();" ); } -#endif if ((profile != EEsProfile && version >= 130) || esBarrier) commonBuiltins.append( "void memoryBarrier();" ); if ((profile != EEsProfile && version >= 420) || esBarrier) { commonBuiltins.append( - "void memoryBarrierAtomicCounter();" "void memoryBarrierBuffer();" - "void memoryBarrierImage();" ); stageBuiltins[EShLangCompute].append( "void memoryBarrierShared();" "void groupMemoryBarrier();" ); } -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB + if ((profile != EEsProfile && version >= 420) || esBarrier) { + if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed) { + commonBuiltins.append("void memoryBarrierAtomicCounter();"); + } + commonBuiltins.append("void memoryBarrierImage();"); + } if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { stageBuiltins[EShLangMeshNV].append( "void memoryBarrierShared();" @@ -4923,11 +4434,95 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void groupMemoryBarrier();" ); } -#endif commonBuiltins.append("void controlBarrier(int, int, int, int);\n" "void memoryBarrier(int, int, int);\n"); + commonBuiltins.append("void debugPrintfEXT();\n"); + +#ifndef GLSLANG_ANGLE + if (profile != EEsProfile && version >= 450) { + // coopMatStoreNV perhaps ought to have "out" on the buf parameter, but + // adding it introduces undesirable tempArgs on the stack. What we want + // is more like "buf" thought of as a pointer value being an in parameter. + stageBuiltins[EShLangCompute].append( + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent float16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent float[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "void coopMatStoreNV(fcoopmatNV m, volatile coherent float16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent float[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent float64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "fcoopmatNV coopMatMulAddNV(fcoopmatNV A, fcoopmatNV B, fcoopmatNV C);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent int8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent int16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent int[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent int64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent ivec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent ivec4[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent int8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent int16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent int[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent int64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent ivec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent ivec4[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "void coopMatStoreNV(icoopmatNV m, volatile coherent int8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent int16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent int[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent int64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent ivec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent ivec4[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "void coopMatStoreNV(ucoopmatNV m, volatile coherent int8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent int16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent int[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent int64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent ivec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent ivec4[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "icoopmatNV coopMatMulAddNV(icoopmatNV A, icoopmatNV B, icoopmatNV C);\n" + "ucoopmatNV coopMatMulAddNV(ucoopmatNV A, ucoopmatNV B, ucoopmatNV C);\n" + ); + } + //============================================================================ // // Prototypes for built-in functions seen by fragment shaders only. @@ -4969,9 +4564,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } - - stageBuiltins[EShLangFragment].append(derivatives); - stageBuiltins[EShLangFragment].append("\n"); +#endif // !GLSLANG_ANGLE // GL_ARB_derivative_control if (profile != EEsProfile && version >= 400) { @@ -5001,7 +4594,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifdef AMD_EXTENSIONS + stageBuiltins[EShLangFragment].append( + "void beginInvocationInterlockARB(void);" + "void endInvocationInterlockARB(void);"); + + stageBuiltins[EShLangFragment].append( + "bool helperInvocationEXT();" + "\n"); + +#ifndef GLSLANG_ANGLE // GL_AMD_shader_explicit_vertex_parameter if (profile != EEsProfile && version >= 450) { stageBuiltins[EShLangFragment].append( @@ -5052,6 +4653,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } + // GL_ARB_shader_clock & GL_EXT_shader_realtime_clock + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "uvec2 clock2x32ARB();" + "uint64_t clockARB();" + "uvec2 clockRealtime2x32EXT();" + "uint64_t clockRealtimeEXT();" + "\n"); + } + // GL_AMD_shader_fragment_mask if (profile != EEsProfile && version >= 450 && spvVersion.vulkan > 0) { stageBuiltins[EShLangFragment].append( @@ -5065,45 +4676,77 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#endif -#ifdef NV_EXTENSIONS - - // Builtins for GL_NV_ray_tracing + // Builtins for GL_NV_ray_tracing/GL_NV_ray_tracing_motion_blur/GL_EXT_ray_tracing/GL_EXT_ray_query if (profile != EEsProfile && version >= 460) { - stageBuiltins[EShLangRayGenNV].append( + commonBuiltins.append("void rayQueryInitializeEXT(rayQueryEXT, accelerationStructureEXT, uint, uint, vec3, float, vec3, float);" + "void rayQueryTerminateEXT(rayQueryEXT);" + "void rayQueryGenerateIntersectionEXT(rayQueryEXT, float);" + "void rayQueryConfirmIntersectionEXT(rayQueryEXT);" + "bool rayQueryProceedEXT(rayQueryEXT);" + "uint rayQueryGetIntersectionTypeEXT(rayQueryEXT, bool);" + "float rayQueryGetRayTMinEXT(rayQueryEXT);" + "uint rayQueryGetRayFlagsEXT(rayQueryEXT);" + "vec3 rayQueryGetWorldRayOriginEXT(rayQueryEXT);" + "vec3 rayQueryGetWorldRayDirectionEXT(rayQueryEXT);" + "float rayQueryGetIntersectionTEXT(rayQueryEXT, bool);" + "int rayQueryGetIntersectionInstanceCustomIndexEXT(rayQueryEXT, bool);" + "int rayQueryGetIntersectionInstanceIdEXT(rayQueryEXT, bool);" + "uint rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(rayQueryEXT, bool);" + "int rayQueryGetIntersectionGeometryIndexEXT(rayQueryEXT, bool);" + "int rayQueryGetIntersectionPrimitiveIndexEXT(rayQueryEXT, bool);" + "vec2 rayQueryGetIntersectionBarycentricsEXT(rayQueryEXT, bool);" + "bool rayQueryGetIntersectionFrontFaceEXT(rayQueryEXT, bool);" + "bool rayQueryGetIntersectionCandidateAABBOpaqueEXT(rayQueryEXT);" + "vec3 rayQueryGetIntersectionObjectRayDirectionEXT(rayQueryEXT, bool);" + "vec3 rayQueryGetIntersectionObjectRayOriginEXT(rayQueryEXT, bool);" + "mat4x3 rayQueryGetIntersectionObjectToWorldEXT(rayQueryEXT, bool);" + "mat4x3 rayQueryGetIntersectionWorldToObjectEXT(rayQueryEXT, bool);" + "\n"); + + stageBuiltins[EShLangRayGen].append( "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);" + "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void executeCallableNV(uint, int);" + "void executeCallableEXT(uint, int);" "\n"); - stageBuiltins[EShLangIntersectNV].append( + stageBuiltins[EShLangIntersect].append( "bool reportIntersectionNV(float, uint);" + "bool reportIntersectionEXT(float, uint);" "\n"); - stageBuiltins[EShLangAnyHitNV].append( + stageBuiltins[EShLangAnyHit].append( "void ignoreIntersectionNV();" "void terminateRayNV();" "\n"); - stageBuiltins[EShLangClosestHitNV].append( + stageBuiltins[EShLangClosestHit].append( "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);" + "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void executeCallableNV(uint, int);" + "void executeCallableEXT(uint, int);" "\n"); - stageBuiltins[EShLangMissNV].append( + stageBuiltins[EShLangMiss].append( "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);" + "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void executeCallableNV(uint, int);" + "void executeCallableEXT(uint, int);" "\n"); - stageBuiltins[EShLangCallableNV].append( + stageBuiltins[EShLangCallable].append( "void executeCallableNV(uint, int);" + "void executeCallableEXT(uint, int);" "\n"); } +#endif // !GLSLANG_ANGLE //E_SPV_NV_compute_shader_derivatives - - stageBuiltins[EShLangCompute].append(derivatives); - stageBuiltins[EShLangCompute].append(derivativeControls); - stageBuiltins[EShLangCompute].append("\n"); - - + if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450)) { + stageBuiltins[EShLangCompute].append(derivativeControls); + stageBuiltins[EShLangCompute].append("\n"); + } +#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 450) { - stageBuiltins[EShLangCompute].append(derivativesAndControl16bits); stageBuiltins[EShLangCompute].append(derivativesAndControl64bits); stageBuiltins[EShLangCompute].append("\n"); @@ -5113,9 +4756,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { stageBuiltins[EShLangMeshNV].append( "void writePackedPrimitiveIndices4x8NV(uint, uint);" - "\n"); + "\n"); } -#endif +#endif // !GLSLANG_ANGLE +#endif // !GLSLANG_WEB //============================================================================ // @@ -5137,11 +4781,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "highp float diff;" // f - n ); } else { +#ifndef GLSLANG_WEB commonBuiltins.append( "float near;" // n "float far;" // f "float diff;" // f - n ); +#endif } commonBuiltins.append( @@ -5150,6 +4796,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) if (spvVersion.spv == 0 && IncludeLegacy(version, profile, spvVersion)) { // // Matrix state. p. 31, 32, 37, 39, 40. @@ -5267,6 +4914,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE //============================================================================ // @@ -5296,7 +4944,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB +#ifndef GLSLANG_ANGLE //============================================================================ // // Define the interface to the mesh/task shader. @@ -5384,7 +5033,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } } -#endif +#endif // !GLSLANG_ANGLE //============================================================================ // @@ -5497,6 +5146,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in int gl_VertexIndex;" "in int gl_InstanceIndex;" ); + + if (spvVersion.vulkan > 0 && version >= 140 && spvVersion.vulkanRelaxed) + stageBuiltins[EShLangVertex].append( + "in int gl_VertexID;" // declare with 'in' qualifier + "in int gl_InstanceID;" + ); + if (version >= 440) { stageBuiltins[EShLangVertex].append( "in int gl_BaseVertexARB;" @@ -5518,7 +5174,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV ); } -#ifdef NV_EXTENSIONS if (version >= 450) stageBuiltins[EShLangVertex].append( "out int gl_ViewportMask[];" // GL_NV_viewport_array2 @@ -5527,8 +5182,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes "out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes ); -#endif - } else { // ES profile if (version == 100) { @@ -5537,21 +5190,25 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "mediump float gl_PointSize;" // needs qualifier fixed later ); } else { - if (spvVersion.vulkan == 0) + if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed) stageBuiltins[EShLangVertex].append( "in highp int gl_VertexID;" // needs qualifier fixed later "in highp int gl_InstanceID;" // needs qualifier fixed later ); if (spvVersion.vulkan > 0) +#endif stageBuiltins[EShLangVertex].append( "in highp int gl_VertexIndex;" "in highp int gl_InstanceIndex;" ); +#ifndef GLSLANG_WEB if (version < 310) +#endif stageBuiltins[EShLangVertex].append( "highp vec4 gl_Position;" // needs qualifier fixed later "highp float gl_PointSize;" // needs qualifier fixed later ); +#ifndef GLSLANG_WEB else stageBuiltins[EShLangVertex].append( "out gl_PerVertex {" @@ -5576,6 +5233,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangVertex].append( + "out highp int gl_PrimitiveShadingRateEXT;" // GL_EXT_fragment_shading_rate + "\n"); + } //============================================================================ // @@ -5603,10 +5265,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV if (version >= 450) stageBuiltins[EShLangGeometry].append( "float gl_CullDistance[];" -#ifdef NV_EXTENSIONS "vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering "vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes -#endif ); stageBuiltins[EShLangGeometry].append( "} gl_in[];" @@ -5652,7 +5312,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in int gl_InvocationID;" ); -#ifdef NV_EXTENSIONS if (version >= 450) stageBuiltins[EShLangGeometry].append( "out int gl_ViewportMask[];" // GL_NV_viewport_array2 @@ -5661,7 +5320,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes "out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes ); -#endif stageBuiltins[EShLangGeometry].append("\n"); } else if (profile == EEsProfile && version >= 310) { @@ -5693,6 +5351,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangGeometry].append( + "out highp int gl_PrimitiveShadingRateEXT;" // GL_EXT_fragment_shading_rate + "\n"); + } + //============================================================================ // // Define the interface to the tessellation control shader. @@ -5726,13 +5390,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV if (version >= 450) stageBuiltins[EShLangTessControl].append( "float gl_CullDistance[];" -#ifdef NV_EXTENSIONS "int gl_ViewportMask[];" // GL_NV_viewport_array2 "vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering "int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering "vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes "int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes -#endif ); stageBuiltins[EShLangTessControl].append( "} gl_out[];" @@ -5766,7 +5428,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "patch out highp float gl_TessLevelOuter[4];" "patch out highp float gl_TessLevelInner[2];" "patch out highp vec4 gl_BoundingBoxOES[2];" + "patch out highp vec4 gl_BoundingBoxEXT[2];" "\n"); + if (profile == EEsProfile && version >= 320) { + stageBuiltins[EShLangTessControl].append( + "patch out highp vec4 gl_BoundingBox[2];" + "\n" + ); + } } if ((profile != EEsProfile && version >= 140) || @@ -5824,7 +5493,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "out int gl_Layer;" "\n"); -#ifdef NV_EXTENSIONS if (version >= 450) stageBuiltins[EShLangTessEvaluation].append( "out int gl_ViewportMask[];" // GL_NV_viewport_array2 @@ -5833,7 +5501,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes "out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes ); -#endif } else if (profile == EEsProfile && version >= 310) { // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, @@ -5927,19 +5594,25 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "flat in int gl_PrimitiveID;" ); - if (version >= 400) { + if (version >= 130) { // ARB_sample_shading stageBuiltins[EShLangFragment].append( "flat in int gl_SampleID;" " in vec2 gl_SamplePosition;" - "flat in int gl_SampleMaskIn[];" " out int gl_SampleMask[];" ); - if (spvVersion.spv == 0) + + if (spvVersion.spv == 0) { stageBuiltins[EShLangFragment].append( "uniform int gl_NumSamples;" - ); + ); + } } + if (version >= 400) + stageBuiltins[EShLangFragment].append( + "flat in int gl_SampleMaskIn[];" + ); + if (version >= 430) stageBuiltins[EShLangFragment].append( "flat in int gl_Layer;" @@ -5958,7 +5631,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "flat in int gl_FragInvocationCountEXT;" ); -#ifdef AMD_EXTENSIONS if (version >= 450) stageBuiltins[EShLangFragment].append( "in vec2 gl_BaryCoordNoPerspAMD;" @@ -5969,9 +5641,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in vec2 gl_BaryCoordSmoothSampleAMD;" "in vec3 gl_BaryCoordPullModelAMD;" ); -#endif -#ifdef NV_EXTENSIONS if (version >= 430) stageBuiltins[EShLangFragment].append( "in bool gl_FragFullyCoveredNV;" @@ -5984,7 +5654,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in vec3 gl_BaryCoordNoPerspNV;" ); -#endif + if (version >= 450) + stageBuiltins[EShLangFragment].append( + "flat in int gl_ShadingRateEXT;" // GL_EXT_fragment_shading_rate + ); + } else { // ES profile @@ -5996,6 +5670,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "mediump vec2 gl_PointCoord;" // needs qualifier fixed later ); } +#endif if (version >= 300) { stageBuiltins[EShLangFragment].append( "highp vec4 gl_FragCoord;" // needs qualifier fixed later @@ -6004,6 +5679,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "highp float gl_FragDepth;" // needs qualifier fixed later ); } +#ifndef GLSLANG_WEB if (version >= 310) { stageBuiltins[EShLangFragment].append( "bool gl_HelperInvocation;" // needs qualifier fixed later @@ -6031,7 +5707,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "flat in ivec2 gl_FragSizeEXT;" "flat in int gl_FragInvocationCountEXT;" ); -#ifdef NV_EXTENSIONS if (version >= 320) stageBuiltins[EShLangFragment].append( // GL_NV_shading_rate_image "flat in ivec2 gl_FragmentSizeNV;" @@ -6042,17 +5717,38 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in vec3 gl_BaryCoordNV;" "in vec3 gl_BaryCoordNoPerspNV;" ); + if (version >= 310) + stageBuiltins[EShLangFragment].append( + "flat in highp int gl_ShadingRateEXT;" // GL_EXT_fragment_shading_rate + ); + } #endif - } stageBuiltins[EShLangFragment].append("\n"); if (version >= 130) add2ndGenerationSamplingImaging(version, profile, spvVersion); +#ifndef GLSLANG_WEB + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangFragment].append( + "flat in highp int gl_DeviceIndex;" // GL_EXT_device_group + "flat in highp int gl_ViewIndex;" // GL_EXT_multiview + "\n"); + } + + if (version >= 300 /* both ES and non-ES */) { + stageBuiltins[EShLangFragment].append( + "flat in highp uint gl_ViewID_OVR;" // GL_OVR_multiview, GL_OVR_multiview2 + "\n"); + } + +#ifndef GLSLANG_ANGLE // GL_ARB_shader_ballot if (profile != EEsProfile && version >= 450) { - const char* ballotDecls = + const char* ballotDecls = "uniform uint gl_SubGroupSizeARB;" "in uint gl_SubGroupInvocationARB;" "in uint64_t gl_SubGroupEqMaskARB;" @@ -6061,7 +5757,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in uint64_t gl_SubGroupLeMaskARB;" "in uint64_t gl_SubGroupLtMaskARB;" "\n"; - const char* fragmentBallotDecls = + const char* rtBallotDecls = + "uniform volatile uint gl_SubGroupSizeARB;" + "in volatile uint gl_SubGroupInvocationARB;" + "in volatile uint64_t gl_SubGroupEqMaskARB;" + "in volatile uint64_t gl_SubGroupGeMaskARB;" + "in volatile uint64_t gl_SubGroupGtMaskARB;" + "in volatile uint64_t gl_SubGroupLeMaskARB;" + "in volatile uint64_t gl_SubGroupLtMaskARB;" + "\n"; + const char* fragmentBallotDecls = "uniform uint gl_SubGroupSizeARB;" "flat in uint gl_SubGroupInvocationARB;" "flat in uint64_t gl_SubGroupEqMaskARB;" @@ -6076,23 +5781,21 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangGeometry] .append(ballotDecls); stageBuiltins[EShLangCompute] .append(ballotDecls); stageBuiltins[EShLangFragment] .append(fragmentBallotDecls); -#ifdef NV_EXTENSIONS stageBuiltins[EShLangMeshNV] .append(ballotDecls); stageBuiltins[EShLangTaskNV] .append(ballotDecls); -#endif - } - - if ((profile != EEsProfile && version >= 140) || - (profile == EEsProfile && version >= 310)) { - stageBuiltins[EShLangFragment].append( - "flat in highp int gl_DeviceIndex;" // GL_EXT_device_group - "flat in highp int gl_ViewIndex;" // GL_EXT_multiview - "\n"); + stageBuiltins[EShLangRayGen] .append(rtBallotDecls); + stageBuiltins[EShLangIntersect] .append(rtBallotDecls); + // No volatile qualifier on these builtins in any-hit + stageBuiltins[EShLangAnyHit] .append(ballotDecls); + stageBuiltins[EShLangClosestHit] .append(rtBallotDecls); + stageBuiltins[EShLangMiss] .append(rtBallotDecls); + stageBuiltins[EShLangCallable] .append(rtBallotDecls); } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { - const char* ballotDecls = + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + const char* subgroupDecls = "in mediump uint gl_SubgroupSize;" "in mediump uint gl_SubgroupInvocationID;" "in highp uvec4 gl_SubgroupEqMask;" @@ -6100,8 +5803,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in highp uvec4 gl_SubgroupGtMask;" "in highp uvec4 gl_SubgroupLeMask;" "in highp uvec4 gl_SubgroupLtMask;" + // GL_NV_shader_sm_builtins + "in highp uint gl_WarpsPerSMNV;" + "in highp uint gl_SMCountNV;" + "in highp uint gl_WarpIDNV;" + "in highp uint gl_SMIDNV;" "\n"; - const char* fragmentBallotDecls = + const char* fragmentSubgroupDecls = "flat in mediump uint gl_SubgroupSize;" "flat in mediump uint gl_SubgroupInvocationID;" "flat in highp uvec4 gl_SubgroupEqMask;" @@ -6109,141 +5817,214 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "flat in highp uvec4 gl_SubgroupGtMask;" "flat in highp uvec4 gl_SubgroupLeMask;" "flat in highp uvec4 gl_SubgroupLtMask;" + // GL_NV_shader_sm_builtins + "flat in highp uint gl_WarpsPerSMNV;" + "flat in highp uint gl_SMCountNV;" + "flat in highp uint gl_WarpIDNV;" + "flat in highp uint gl_SMIDNV;" + "\n"; + const char* computeSubgroupDecls = + "in highp uint gl_NumSubgroups;" + "in highp uint gl_SubgroupID;" + "\n"; + // These builtins are volatile for RT stages + const char* rtSubgroupDecls = + "in mediump volatile uint gl_SubgroupSize;" + "in mediump volatile uint gl_SubgroupInvocationID;" + "in highp volatile uvec4 gl_SubgroupEqMask;" + "in highp volatile uvec4 gl_SubgroupGeMask;" + "in highp volatile uvec4 gl_SubgroupGtMask;" + "in highp volatile uvec4 gl_SubgroupLeMask;" + "in highp volatile uvec4 gl_SubgroupLtMask;" + // GL_NV_shader_sm_builtins + "in highp uint gl_WarpsPerSMNV;" + "in highp uint gl_SMCountNV;" + "in highp volatile uint gl_WarpIDNV;" + "in highp volatile uint gl_SMIDNV;" "\n"; - stageBuiltins[EShLangVertex] .append(ballotDecls); - stageBuiltins[EShLangTessControl] .append(ballotDecls); - stageBuiltins[EShLangTessEvaluation].append(ballotDecls); - stageBuiltins[EShLangGeometry] .append(ballotDecls); - stageBuiltins[EShLangCompute] .append(ballotDecls); - stageBuiltins[EShLangFragment] .append(fragmentBallotDecls); -#ifdef NV_EXTENSIONS - stageBuiltins[EShLangMeshNV] .append(ballotDecls); - stageBuiltins[EShLangTaskNV] .append(ballotDecls); -#endif - stageBuiltins[EShLangCompute].append( - "highp in uint gl_NumSubgroups;" - "highp in uint gl_SubgroupID;" - "\n"); -#ifdef NV_EXTENSIONS - stageBuiltins[EShLangMeshNV].append( - "highp in uint gl_NumSubgroups;" - "highp in uint gl_SubgroupID;" - "\n"); - stageBuiltins[EShLangTaskNV].append( - "highp in uint gl_NumSubgroups;" - "highp in uint gl_SubgroupID;" - "\n"); -#endif + stageBuiltins[EShLangVertex] .append(subgroupDecls); + stageBuiltins[EShLangTessControl] .append(subgroupDecls); + stageBuiltins[EShLangTessEvaluation].append(subgroupDecls); + stageBuiltins[EShLangGeometry] .append(subgroupDecls); + stageBuiltins[EShLangCompute] .append(subgroupDecls); + stageBuiltins[EShLangCompute] .append(computeSubgroupDecls); + stageBuiltins[EShLangFragment] .append(fragmentSubgroupDecls); + stageBuiltins[EShLangMeshNV] .append(subgroupDecls); + stageBuiltins[EShLangMeshNV] .append(computeSubgroupDecls); + stageBuiltins[EShLangTaskNV] .append(subgroupDecls); + stageBuiltins[EShLangTaskNV] .append(computeSubgroupDecls); + stageBuiltins[EShLangRayGen] .append(rtSubgroupDecls); + stageBuiltins[EShLangIntersect] .append(rtSubgroupDecls); + // No volatile qualifier on these builtins in any-hit + stageBuiltins[EShLangAnyHit] .append(subgroupDecls); + stageBuiltins[EShLangClosestHit] .append(rtSubgroupDecls); + stageBuiltins[EShLangMiss] .append(rtSubgroupDecls); + stageBuiltins[EShLangCallable] .append(rtSubgroupDecls); } -#ifdef NV_EXTENSIONS - // GL_NV_ray_tracing + // GL_NV_ray_tracing/GL_EXT_ray_tracing if (profile != EEsProfile && version >= 460) { const char *constRayFlags = "const uint gl_RayFlagsNoneNV = 0U;" + "const uint gl_RayFlagsNoneEXT = 0U;" "const uint gl_RayFlagsOpaqueNV = 1U;" + "const uint gl_RayFlagsOpaqueEXT = 1U;" "const uint gl_RayFlagsNoOpaqueNV = 2U;" + "const uint gl_RayFlagsNoOpaqueEXT = 2U;" "const uint gl_RayFlagsTerminateOnFirstHitNV = 4U;" + "const uint gl_RayFlagsTerminateOnFirstHitEXT = 4U;" "const uint gl_RayFlagsSkipClosestHitShaderNV = 8U;" + "const uint gl_RayFlagsSkipClosestHitShaderEXT = 8U;" "const uint gl_RayFlagsCullBackFacingTrianglesNV = 16U;" + "const uint gl_RayFlagsCullBackFacingTrianglesEXT = 16U;" "const uint gl_RayFlagsCullFrontFacingTrianglesNV = 32U;" + "const uint gl_RayFlagsCullFrontFacingTrianglesEXT = 32U;" "const uint gl_RayFlagsCullOpaqueNV = 64U;" + "const uint gl_RayFlagsCullOpaqueEXT = 64U;" "const uint gl_RayFlagsCullNoOpaqueNV = 128U;" + "const uint gl_RayFlagsCullNoOpaqueEXT = 128U;" + "const uint gl_RayFlagsSkipTrianglesEXT = 256U;" + "const uint gl_RayFlagsSkipAABBEXT = 512U;" + "const uint gl_HitKindFrontFacingTriangleEXT = 254U;" + "const uint gl_HitKindBackFacingTriangleEXT = 255U;" "\n"; + + const char *constRayQueryIntersection = + "const uint gl_RayQueryCandidateIntersectionEXT = 0U;" + "const uint gl_RayQueryCommittedIntersectionEXT = 1U;" + "const uint gl_RayQueryCommittedIntersectionNoneEXT = 0U;" + "const uint gl_RayQueryCommittedIntersectionTriangleEXT = 1U;" + "const uint gl_RayQueryCommittedIntersectionGeneratedEXT = 2U;" + "const uint gl_RayQueryCandidateIntersectionTriangleEXT = 0U;" + "const uint gl_RayQueryCandidateIntersectionAABBEXT = 1U;" + "\n"; + const char *rayGenDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" + "in uvec3 gl_LaunchSizeEXT;" "\n"; const char *intersectDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" + "in uvec3 gl_LaunchSizeEXT;" "in int gl_PrimitiveID;" "in int gl_InstanceID;" "in int gl_InstanceCustomIndexNV;" + "in int gl_InstanceCustomIndexEXT;" + "in int gl_GeometryIndexEXT;" "in vec3 gl_WorldRayOriginNV;" + "in vec3 gl_WorldRayOriginEXT;" "in vec3 gl_WorldRayDirectionNV;" + "in vec3 gl_WorldRayDirectionEXT;" "in vec3 gl_ObjectRayOriginNV;" + "in vec3 gl_ObjectRayOriginEXT;" "in vec3 gl_ObjectRayDirectionNV;" + "in vec3 gl_ObjectRayDirectionEXT;" "in float gl_RayTminNV;" + "in float gl_RayTminEXT;" "in float gl_RayTmaxNV;" + "in volatile float gl_RayTmaxEXT;" "in mat4x3 gl_ObjectToWorldNV;" + "in mat4x3 gl_ObjectToWorldEXT;" + "in mat3x4 gl_ObjectToWorld3x4EXT;" "in mat4x3 gl_WorldToObjectNV;" + "in mat4x3 gl_WorldToObjectEXT;" + "in mat3x4 gl_WorldToObject3x4EXT;" "in uint gl_IncomingRayFlagsNV;" + "in uint gl_IncomingRayFlagsEXT;" + "in float gl_CurrentRayTimeNV;" "\n"; const char *hitDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" + "in uvec3 gl_LaunchSizeEXT;" "in int gl_PrimitiveID;" "in int gl_InstanceID;" "in int gl_InstanceCustomIndexNV;" + "in int gl_InstanceCustomIndexEXT;" + "in int gl_GeometryIndexEXT;" "in vec3 gl_WorldRayOriginNV;" + "in vec3 gl_WorldRayOriginEXT;" "in vec3 gl_WorldRayDirectionNV;" + "in vec3 gl_WorldRayDirectionEXT;" "in vec3 gl_ObjectRayOriginNV;" + "in vec3 gl_ObjectRayOriginEXT;" "in vec3 gl_ObjectRayDirectionNV;" + "in vec3 gl_ObjectRayDirectionEXT;" "in float gl_RayTminNV;" + "in float gl_RayTminEXT;" "in float gl_RayTmaxNV;" + "in float gl_RayTmaxEXT;" "in float gl_HitTNV;" + "in float gl_HitTEXT;" "in uint gl_HitKindNV;" + "in uint gl_HitKindEXT;" "in mat4x3 gl_ObjectToWorldNV;" + "in mat4x3 gl_ObjectToWorldEXT;" + "in mat3x4 gl_ObjectToWorld3x4EXT;" "in mat4x3 gl_WorldToObjectNV;" + "in mat4x3 gl_WorldToObjectEXT;" + "in mat3x4 gl_WorldToObject3x4EXT;" "in uint gl_IncomingRayFlagsNV;" + "in uint gl_IncomingRayFlagsEXT;" + "in float gl_CurrentRayTimeNV;" "\n"; const char *missDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" + "in uvec3 gl_LaunchSizeEXT;" "in vec3 gl_WorldRayOriginNV;" + "in vec3 gl_WorldRayOriginEXT;" "in vec3 gl_WorldRayDirectionNV;" + "in vec3 gl_WorldRayDirectionEXT;" "in vec3 gl_ObjectRayOriginNV;" "in vec3 gl_ObjectRayDirectionNV;" "in float gl_RayTminNV;" + "in float gl_RayTminEXT;" "in float gl_RayTmaxNV;" + "in float gl_RayTmaxEXT;" "in uint gl_IncomingRayFlagsNV;" + "in uint gl_IncomingRayFlagsEXT;" + "in float gl_CurrentRayTimeNV;" "\n"; const char *callableDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" - "in uint gl_IncomingRayFlagsNV;" + "in uvec3 gl_LaunchSizeEXT;" "\n"; - stageBuiltins[EShLangRayGenNV].append(rayGenDecls); - stageBuiltins[EShLangRayGenNV].append(constRayFlags); - stageBuiltins[EShLangIntersectNV].append(intersectDecls); - stageBuiltins[EShLangIntersectNV].append(constRayFlags); + commonBuiltins.append(constRayQueryIntersection); + commonBuiltins.append(constRayFlags); - stageBuiltins[EShLangAnyHitNV].append(hitDecls); - stageBuiltins[EShLangAnyHitNV].append(constRayFlags); - - stageBuiltins[EShLangClosestHitNV].append(hitDecls); - stageBuiltins[EShLangClosestHitNV].append(constRayFlags); - - stageBuiltins[EShLangMissNV].append(missDecls); - stageBuiltins[EShLangMissNV].append(constRayFlags); - - stageBuiltins[EShLangCallableNV].append(callableDecls); - stageBuiltins[EShLangCallableNV].append(constRayFlags); + stageBuiltins[EShLangRayGen].append(rayGenDecls); + stageBuiltins[EShLangIntersect].append(intersectDecls); + stageBuiltins[EShLangAnyHit].append(hitDecls); + stageBuiltins[EShLangClosestHit].append(hitDecls); + stageBuiltins[EShLangMiss].append(missDecls); + stageBuiltins[EShLangCallable].append(callableDecls); } + if ((profile != EEsProfile && version >= 140)) { const char *deviceIndex = "in highp int gl_DeviceIndex;" // GL_EXT_device_group "\n"; - stageBuiltins[EShLangRayGenNV].append(deviceIndex); - stageBuiltins[EShLangIntersectNV].append(deviceIndex); - stageBuiltins[EShLangAnyHitNV].append(deviceIndex); - stageBuiltins[EShLangClosestHitNV].append(deviceIndex); - stageBuiltins[EShLangMissNV].append(deviceIndex); - } -#endif - - if (version >= 300 /* both ES and non-ES */) { - stageBuiltins[EShLangFragment].append( - "flat in highp uint gl_ViewID_OVR;" // GL_OVR_multiview, GL_OVR_multiview2 - "\n"); + stageBuiltins[EShLangRayGen].append(deviceIndex); + stageBuiltins[EShLangIntersect].append(deviceIndex); + stageBuiltins[EShLangAnyHit].append(deviceIndex); + stageBuiltins[EShLangClosestHit].append(deviceIndex); + stageBuiltins[EShLangMiss].append(deviceIndex); } if ((profile != EEsProfile && version >= 420) || @@ -6253,6 +6034,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append("const int gl_ScopeSubgroup = 3;\n"); commonBuiltins.append("const int gl_ScopeInvocation = 4;\n"); commonBuiltins.append("const int gl_ScopeQueueFamily = 5;\n"); + commonBuiltins.append("const int gl_ScopeShaderCallEXT = 6;\n"); commonBuiltins.append("const int gl_SemanticsRelaxed = 0x0;\n"); commonBuiltins.append("const int gl_SemanticsAcquire = 0x2;\n"); @@ -6260,6 +6042,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append("const int gl_SemanticsAcquireRelease = 0x8;\n"); commonBuiltins.append("const int gl_SemanticsMakeAvailable = 0x2000;\n"); commonBuiltins.append("const int gl_SemanticsMakeVisible = 0x4000;\n"); + commonBuiltins.append("const int gl_SemanticsVolatile = 0x8000;\n"); commonBuiltins.append("const int gl_StorageSemanticsNone = 0x0;\n"); commonBuiltins.append("const int gl_StorageSemanticsBuffer = 0x40;\n"); @@ -6268,6 +6051,59 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append("const int gl_StorageSemanticsOutput = 0x1000;\n"); } + // Adding these to common built-ins triggers an assert due to a memory corruption in related code when testing + // So instead add to each stage individually, avoiding the GLSLang bug + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) { + for (int stage=EShLangVertex; stage(stage)].append("const highp int gl_ShadingRateFlag2VerticalPixelsEXT = 1;\n"); + stageBuiltins[static_cast(stage)].append("const highp int gl_ShadingRateFlag4VerticalPixelsEXT = 2;\n"); + stageBuiltins[static_cast(stage)].append("const highp int gl_ShadingRateFlag2HorizontalPixelsEXT = 4;\n"); + stageBuiltins[static_cast(stage)].append("const highp int gl_ShadingRateFlag4HorizontalPixelsEXT = 8;\n"); + } + } + + // GL_EXT_shader_image_int64 + if ((profile != EEsProfile && version >= 420) || + (profile == EEsProfile && version >= 310)) { + + const TBasicType bTypes[] = { EbtInt64, EbtUint64 }; + for (int ms = 0; ms <= 1; ++ms) { // loop over "bool" multisample or not + for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not + for (int dim = Esd1D; dim < EsdSubpass; ++dim) { // 1D, ..., buffer + if ((dim == Esd1D || dim == EsdRect) && profile == EEsProfile) + continue; + + if ((dim == Esd3D || dim == EsdRect || dim == EsdBuffer) && arrayed) + continue; + + if (dim != Esd2D && ms) + continue; + + // Loop over the bTypes + for (size_t bType = 0; bType < sizeof(bTypes)/sizeof(TBasicType); ++bType) { + // + // Now, make all the function prototypes for the type we just built... + // + TSampler sampler; + + sampler.setImage(bTypes[bType], (TSamplerDim)dim, arrayed ? true : false, + false, + ms ? true : false); + + TString typeName = sampler.getString(); + + addQueryFunctions(sampler, typeName, version, profile); + addImageFunctions(sampler, typeName, version, profile); + } + } + } + } + } +#endif // !GLSLANG_ANGLE + +#endif // !GLSLANG_WEB + // printf("%s\n", commonBuiltins.c_str()); // printf("%s\n", stageBuiltins[EShLangFragment].c_str()); } @@ -6282,19 +6118,30 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // In this function proper, enumerate the types, then calls the next set of functions // to enumerate all the uses for that type. // -#ifdef AMD_EXTENSIONS - TBasicType bTypes[4] = { EbtFloat, EbtFloat16, EbtInt, EbtUint }; -#else - TBasicType bTypes[3] = { EbtFloat, EbtInt, EbtUint }; -#endif - bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140); - bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); // enumerate all the types - for (int image = 0; image <= 1; ++image) { // loop over "bool" image vs sampler - + const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + EbtFloat16 +#endif + }; +#ifdef GLSLANG_WEB + bool skipBuffer = true; + bool skipCubeArrayed = true; + const int image = 0; +#else + bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140); + bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); + for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler +#endif + { for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not - for (int ms = 0; ms <=1; ++ms) { +#ifdef GLSLANG_WEB + const int ms = 0; +#else + for (int ms = 0; ms <= 1; ++ms) // loop over "bool" multisample or not +#endif + { if ((ms || image) && shadow) continue; if (ms && profile != EEsProfile && version < 150) @@ -6305,7 +6152,20 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c continue; for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not - for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, 2D, ..., buffer +#ifdef GLSLANG_WEB + for (int dim = Esd2D; dim <= EsdCube; ++dim) { // 2D, 3D, and Cube +#else +#if defined(GLSLANG_ANGLE) + for (int dim = Esd2D; dim < EsdNumDims; ++dim) { // 2D, ..., buffer, subpass +#else + for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, ..., buffer, subpass +#endif + if (dim == EsdSubpass && spvVersion.vulkan == 0) + continue; + if (dim == EsdSubpass && (image || shadow || arrayed)) + continue; + if ((dim == Esd1D || dim == EsdRect) && profile == EEsProfile) + continue; if (dim == EsdSubpass && spvVersion.vulkan == 0) continue; if (dim == EsdSubpass && (image || shadow || arrayed)) @@ -6314,43 +6174,40 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c continue; if (dim != Esd2D && dim != EsdSubpass && ms) continue; - if ((dim == Esd3D || dim == EsdRect) && arrayed) - continue; - if (dim == Esd3D && shadow) - continue; - if (dim == EsdCube && arrayed && skipCubeArrayed) - continue; if (dim == EsdBuffer && skipBuffer) continue; if (dim == EsdBuffer && (shadow || arrayed || ms)) continue; if (ms && arrayed && profile == EEsProfile && version < 310) continue; -#ifdef AMD_EXTENSIONS - for (int bType = 0; bType < 4; ++bType) { // float, float16, int, uint results - - if (shadow && bType > 1) - continue; - - if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile ||version < 450)) - continue; -#else - for (int bType = 0; bType < 3; ++bType) { // float, int, uint results - - if (shadow && bType > 0) - continue; #endif + if (dim == Esd3D && shadow) + continue; + if (dim == EsdCube && arrayed && skipCubeArrayed) + continue; + if ((dim == Esd3D || dim == EsdRect) && arrayed) + continue; + + // Loop over the bTypes + for (size_t bType = 0; bType < sizeof(bTypes)/sizeof(TBasicType); ++bType) { +#ifndef GLSLANG_WEB + if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile || version < 450)) + continue; if (dim == EsdRect && version < 140 && bType > 0) continue; - +#endif + if (shadow && (bTypes[bType] == EbtInt || bTypes[bType] == EbtUint)) + continue; // // Now, make all the function prototypes for the type we just built... // - TSampler sampler; +#ifndef GLSLANG_WEB if (dim == EsdSubpass) { sampler.setSubpass(bTypes[bType], ms ? true : false); - } else if (image) { + } else +#endif + if (image) { sampler.setImage(bTypes[bType], (TSamplerDim)dim, arrayed ? true : false, shadow ? true : false, ms ? true : false); @@ -6362,10 +6219,12 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c TString typeName = sampler.getString(); +#ifndef GLSLANG_WEB if (dim == EsdSubpass) { addSubpassSampling(sampler, typeName, version, profile); continue; } +#endif addQueryFunctions(sampler, typeName, version, profile); @@ -6373,8 +6232,8 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c addImageFunctions(sampler, typeName, version, profile); else { addSamplingFunctions(sampler, typeName, version, profile); +#ifndef GLSLANG_WEB addGatherFunctions(sampler, typeName, version, profile); - if (spvVersion.vulkan > 0 && sampler.isCombined() && !sampler.shadow) { // Base Vulkan allows texelFetch() for // textureBuffer (i.e. without sampler). @@ -6389,6 +6248,7 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c addSamplingFunctions(sampler, textureTypeName, version, profile); addQueryFunctions(sampler, textureTypeName, version, profile); } +#endif } } } @@ -6400,7 +6260,6 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // // sparseTexelsResidentARB() // - if (profile != EEsProfile && version >= 450) { commonBuiltins.append("bool sparseTexelsResidentARB(int code);\n"); } @@ -6414,14 +6273,25 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) { - if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430))) - return; - // // textureSize() and imageSize() // int sizeDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0) - (sampler.dim == EsdCube ? 1 : 0); + +#ifdef GLSLANG_WEB + commonBuiltins.append("highp "); + commonBuiltins.append("ivec"); + commonBuiltins.append(postfixes[sizeDims]); + commonBuiltins.append(" textureSize("); + commonBuiltins.append(typeName); + commonBuiltins.append(",int);\n"); + return; +#endif + + if (sampler.isImage() && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 420))) + return; + if (profile == EEsProfile) commonBuiltins.append("highp "); if (sizeDims == 1) @@ -6430,12 +6300,12 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append("ivec"); commonBuiltins.append(postfixes[sizeDims]); } - if (sampler.image) + if (sampler.isImage()) commonBuiltins.append(" imageSize(readonly writeonly volatile coherent "); else commonBuiltins.append(" textureSize("); commonBuiltins.append(typeName); - if (! sampler.image && sampler.dim != EsdRect && sampler.dim != EsdBuffer && ! sampler.ms) + if (! sampler.isImage() && ! sampler.isRect() && ! sampler.isBuffer() && ! sampler.isMultiSample()) commonBuiltins.append(",int);\n"); else commonBuiltins.append(");\n"); @@ -6446,9 +6316,9 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int // GL_ARB_shader_texture_image_samples // TODO: spec issue? there are no memory qualifiers; how to query a writeonly/readonly image, etc? - if (profile != EEsProfile && version >= 430 && sampler.ms) { + if (profile != EEsProfile && version >= 430 && sampler.isMultiSample()) { commonBuiltins.append("int "); - if (sampler.image) + if (sampler.isImage()) commonBuiltins.append("imageSamples(readonly writeonly volatile coherent "); else commonBuiltins.append("textureSamples("); @@ -6458,42 +6328,30 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int // // textureQueryLod(), fragment stage only - // + // Also enabled with extension GL_ARB_texture_query_lod - if (profile != EEsProfile && version >= 400 && sampler.combined && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { -#ifdef AMD_EXTENSIONS + if (profile != EEsProfile && version >= 150 && sampler.isCombined() && sampler.dim != EsdRect && + ! sampler.isMultiSample() && ! sampler.isBuffer()) { for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) { if (f16TexAddr && sampler.type != EbtFloat16) continue; -#endif stageBuiltins[EShLangFragment].append("vec2 textureQueryLod("); stageBuiltins[EShLangFragment].append(typeName); if (dimMap[sampler.dim] == 1) -#ifdef AMD_EXTENSIONS if (f16TexAddr) stageBuiltins[EShLangFragment].append(", float16_t"); else stageBuiltins[EShLangFragment].append(", float"); -#else - stageBuiltins[EShLangFragment].append(", float"); -#endif else { -#ifdef AMD_EXTENSIONS if (f16TexAddr) stageBuiltins[EShLangFragment].append(", f16vec"); else stageBuiltins[EShLangFragment].append(", vec"); -#else - stageBuiltins[EShLangFragment].append(", vec"); -#endif stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]); } stageBuiltins[EShLangFragment].append(");\n"); -#ifdef AMD_EXTENSIONS } -#endif -#ifdef NV_EXTENSIONS stageBuiltins[EShLangCompute].append("vec2 textureQueryLod("); stageBuiltins[EShLangCompute].append(typeName); if (dimMap[sampler.dim] == 1) @@ -6503,14 +6361,14 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]); } stageBuiltins[EShLangCompute].append(");\n"); -#endif } // // textureQueryLevels() // - if (profile != EEsProfile && version >= 430 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { + if (profile != EEsProfile && version >= 430 && ! sampler.isImage() && sampler.dim != EsdRect && + ! sampler.isMultiSample() && ! sampler.isBuffer()) { commonBuiltins.append("int textureQueryLevels("); commonBuiltins.append(typeName); commonBuiltins.append(");\n"); @@ -6537,7 +6395,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int imageParams.append(", ivec"); imageParams.append(postfixes[dims]); } - if (sampler.ms) + if (sampler.isMultiSample()) imageParams.append(", int"); if (profile == EEsProfile) @@ -6553,7 +6411,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append(prefixes[sampler.type]); commonBuiltins.append("vec4);\n"); - if (sampler.dim != Esd1D && sampler.dim != EsdBuffer && profile != EEsProfile && version >= 450) { + if (! sampler.is1D() && ! sampler.isBuffer() && profile != EEsProfile && version >= 450) { commonBuiltins.append("int sparseImageLoadARB(readonly volatile coherent "); commonBuiltins.append(imageParams); commonBuiltins.append(", out "); @@ -6564,8 +6422,16 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int if ( profile != EEsProfile || (profile == EEsProfile && version >= 310)) { - if (sampler.type == EbtInt || sampler.type == EbtUint) { - const char* dataType = sampler.type == EbtInt ? "highp int" : "highp uint"; + if (sampler.type == EbtInt || sampler.type == EbtUint || sampler.type == EbtInt64 || sampler.type == EbtUint64 ) { + + const char* dataType; + switch (sampler.type) { + case(EbtInt): dataType = "highp int"; break; + case(EbtUint): dataType = "highp uint"; break; + case(EbtInt64): dataType = "highp int64_t"; break; + case(EbtUint64): dataType = "highp uint64_t"; break; + default: dataType = ""; + } const int numBuiltins = 7; @@ -6621,17 +6487,61 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int // not int or uint // GL_ARB_ES3_1_compatibility // TODO: spec issue: are there restrictions on the kind of layout() that can be used? what about dropping memory qualifiers? - if ((profile != EEsProfile && version >= 450) || - (profile == EEsProfile && version >= 310)) { + if (profile == EEsProfile && version >= 310) { commonBuiltins.append("float imageAtomicExchange(volatile coherent "); commonBuiltins.append(imageParams); commonBuiltins.append(", float);\n"); } + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append("float imageAtomicAdd(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float);\n"); + + commonBuiltins.append("float imageAtomicAdd(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float"); + commonBuiltins.append(", int, int, int);\n"); + + commonBuiltins.append("float imageAtomicExchange(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float);\n"); + + commonBuiltins.append("float imageAtomicExchange(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float"); + commonBuiltins.append(", int, int, int);\n"); + + commonBuiltins.append("float imageAtomicLoad(readonly volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", int, int, int);\n"); + + commonBuiltins.append("void imageAtomicStore(writeonly volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float"); + commonBuiltins.append(", int, int, int);\n"); + + commonBuiltins.append("float imageAtomicMin(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float);\n"); + + commonBuiltins.append("float imageAtomicMin(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float"); + commonBuiltins.append(", int, int, int);\n"); + + commonBuiltins.append("float imageAtomicMax(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float);\n"); + + commonBuiltins.append("float imageAtomicMax(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float"); + commonBuiltins.append(", int, int, int);\n"); + } } } -#ifdef AMD_EXTENSIONS - if (sampler.dim == EsdRect || sampler.dim == EsdBuffer || sampler.shadow || sampler.ms) + if (sampler.dim == EsdRect || sampler.dim == EsdBuffer || sampler.shadow || sampler.isMultiSample()) return; if (profile == EEsProfile || version < 450) @@ -6657,7 +6567,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append(prefixes[sampler.type]); commonBuiltins.append("vec4);\n"); - if (sampler.dim != Esd1D) { + if (! sampler.is1D()) { commonBuiltins.append("int sparseImageLoadLodAMD(readonly volatile coherent "); commonBuiltins.append(imageLodParams); commonBuiltins.append(", out "); @@ -6665,7 +6575,6 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append("vec4"); commonBuiltins.append(");\n"); } -#endif } // @@ -6680,7 +6589,7 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, in stageBuiltins[EShLangFragment].append("vec4 subpassLoad"); stageBuiltins[EShLangFragment].append("("); stageBuiltins[EShLangFragment].append(typeName.c_str()); - if (sampler.ms) + if (sampler.isMultiSample()) stageBuiltins[EShLangFragment].append(", int"); stageBuiltins[EShLangFragment].append(");\n"); } @@ -6693,17 +6602,26 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, in // void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) { +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; +#endif + // // texturing // for (int proj = 0; proj <= 1; ++proj) { // loop over "bool" projective or not - if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms || !sampler.combined)) + if (proj && (sampler.dim == EsdCube || sampler.isBuffer() || sampler.arrayed || sampler.isMultiSample() + || !sampler.isCombined())) continue; for (int lod = 0; lod <= 1; ++lod) { - if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms || !sampler.combined)) + if (lod && (sampler.isBuffer() || sampler.isRect() || sampler.isMultiSample() || !sampler.isCombined())) continue; if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow) continue; @@ -6712,18 +6630,18 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, for (int bias = 0; bias <= 1; ++bias) { - if (bias && (lod || sampler.ms || !sampler.combined)) + if (bias && (lod || sampler.isMultiSample() || !sampler.isCombined())) continue; if (bias && (sampler.dim == Esd2D || sampler.dim == EsdCube) && sampler.shadow && sampler.arrayed) continue; - if (bias && (sampler.dim == EsdRect || sampler.dim == EsdBuffer)) + if (bias && (sampler.isRect() || sampler.isBuffer())) continue; for (int offset = 0; offset <= 1; ++offset) { // loop over "bool" offset or not if (proj + offset + bias + lod > 3) continue; - if (offset && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.ms)) + if (offset && (sampler.dim == EsdCube || sampler.isBuffer() || sampler.isMultiSample())) continue; for (int fetch = 0; fetch <= 1; ++fetch) { // loop over "bool" fetch or not @@ -6734,14 +6652,15 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, continue; if (fetch && (sampler.shadow || sampler.dim == EsdCube)) continue; - if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer || !sampler.combined)) + if (fetch == 0 && (sampler.isMultiSample() || sampler.isBuffer() + || !sampler.isCombined())) continue; for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not - if (grad && (lod || bias || sampler.ms || !sampler.combined)) + if (grad && (lod || bias || sampler.isMultiSample() || !sampler.isCombined())) continue; - if (grad && sampler.dim == EsdBuffer) + if (grad && sampler.isBuffer()) continue; if (proj + offset + fetch + grad + bias + lod > 3) continue; @@ -6761,31 +6680,46 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, if (extraProj && ! proj) continue; - if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.combined)) + if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.isCombined())) continue; -#ifdef AMD_EXTENSIONS - for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing + // loop over 16-bit floating-point texel addressing +#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) + const int f16TexAddr = 0; +#else + for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) +#endif + { if (f16TexAddr && sampler.type != EbtFloat16) continue; if (f16TexAddr && sampler.shadow && ! compare) { compare = true; // compare argument is always present totalDims--; } + // loop over "bool" lod clamp +#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) + const int lodClamp = 0; +#else + for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) #endif - for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) { // loop over "bool" lod clamp - + { if (lodClamp && (profile == EEsProfile || version < 450)) continue; if (lodClamp && (proj || lod || fetch)) continue; - for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not - + // loop over "bool" sparse or not +#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) + const int sparse = 0; +#else + for (int sparse = 0; sparse <= 1; ++sparse) +#endif + { if (sparse && (profile == EEsProfile || version < 450)) continue; - // Sparse sampling is not for 1D/1D array texture, buffer texture, and projective texture - if (sparse && (sampler.dim == Esd1D || sampler.dim == EsdBuffer || proj)) + // Sparse sampling is not for 1D/1D array texture, buffer texture, and + // projective texture + if (sparse && (sampler.is1D() || sampler.isBuffer() || proj)) continue; TString s; @@ -6795,14 +6729,10 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, s.append("int "); else { if (sampler.shadow) -#ifdef AMD_EXTENSIONS if (sampler.type == EbtFloat16) s.append("float16_t "); else s.append("float "); -#else - s.append("float "); -#endif else { s.append(prefixes[sampler.type]); s.append("vec4 "); @@ -6834,13 +6764,12 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, s.append("Offset"); if (lodClamp) s.append("Clamp"); - if (lodClamp || sparse) + if (lodClamp != 0 || sparse) s.append("ARB"); s.append("("); // sampler type s.append(typeName); -#ifdef AMD_EXTENSIONS // P coordinate if (extraProj) { if (f16TexAddr) @@ -6858,31 +6787,15 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, s.append(postfixes[totalDims]); } } -#else - // P coordinate - if (extraProj) - s.append(",vec4"); - else { - s.append(","); - TBasicType t = fetch ? EbtInt : EbtFloat; - if (totalDims == 1) - s.append(TType::getBasicString(t)); - else { - s.append(prefixes[t]); - s.append("vec"); - s.append(postfixes[totalDims]); - } - } -#endif // non-optional compare if (compare) s.append(",float"); // non-optional lod argument (lod that's not driven by lod loop) or sample - if ((fetch && sampler.dim != EsdBuffer && sampler.dim != EsdRect && !sampler.ms) || - (sampler.ms && fetch)) + if ((fetch && !sampler.isBuffer() && + !sampler.isRect() && !sampler.isMultiSample()) + || (sampler.isMultiSample() && fetch)) s.append(",int"); -#ifdef AMD_EXTENSIONS // non-optional lod if (lod) { if (f16TexAddr) @@ -6911,23 +6824,6 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, s.append(postfixes[dimMap[sampler.dim]]); } } -#else - // non-optional lod - if (lod) - s.append(",float"); - - // gradient arguments - if (grad) { - if (dimMap[sampler.dim] == 1) - s.append(",float,float"); - else { - s.append(",vec"); - s.append(postfixes[dimMap[sampler.dim]]); - s.append(",vec"); - s.append(postfixes[dimMap[sampler.dim]]); - } - } -#endif // offset if (offset) { if (dimMap[sampler.dim] == 1) @@ -6938,7 +6834,6 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, } } -#ifdef AMD_EXTENSIONS // lod clamp if (lodClamp) { if (f16TexAddr) @@ -6946,29 +6841,19 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, else s.append(",float"); } -#else - // lod clamp - if (lodClamp) - s.append(",float"); -#endif // texel out (for sparse texture) if (sparse) { s.append(",out "); if (sampler.shadow) -#ifdef AMD_EXTENSIONS if (sampler.type == EbtFloat16) s.append("float16_t"); else s.append("float"); -#else - s.append("float"); -#endif else { s.append(prefixes[sampler.type]); s.append("vec4"); } } -#ifdef AMD_EXTENSIONS // optional bias if (bias) { if (f16TexAddr) @@ -6976,27 +6861,18 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, else s.append(",float"); } -#else - // optional bias - if (bias) - s.append(",float"); -#endif s.append(");\n"); // Add to the per-language set of built-ins - if (bias || lodClamp) { + if (!grad && (bias || lodClamp != 0)) { stageBuiltins[EShLangFragment].append(s); -#ifdef NV_EXTENSIONS stageBuiltins[EShLangCompute].append(s); -#endif } else commonBuiltins.append(s); } } -#ifdef AMD_EXTENSIONS } -#endif } } } @@ -7014,6 +6890,14 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, // void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) { +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; +#endif + switch (sampler.dim) { case Esd2D: case EsdRect: @@ -7023,18 +6907,16 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in return; } - if (sampler.ms) + if (sampler.isMultiSample()) return; if (version < 140 && sampler.dim == EsdRect && sampler.type != EbtFloat) return; -#ifdef AMD_EXTENSIONS for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing if (f16TexAddr && sampler.type != EbtFloat16) continue; -#endif for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument @@ -7082,14 +6964,10 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in s.append(typeName); // P coordinate argument -#ifdef AMD_EXTENSIONS if (f16TexAddr) s.append(",f16vec"); else s.append(",vec"); -#else - s.append(",vec"); -#endif int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); s.append(postfixes[totalDims]); @@ -7117,14 +6995,11 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in s.append(");\n"); commonBuiltins.append(s); -#ifdef AMD_EXTENSIONS } -#endif } } } -#ifdef AMD_EXTENSIONS if (sampler.dim == EsdRect || sampler.shadow) return; @@ -7250,7 +7125,6 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in } } } -#endif } // @@ -7262,6 +7136,14 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in // void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language) { +#ifdef GLSLANG_WEB + version = 310; + profile = EEsProfile; +#elif defined(GLSLANG_ANGLE) + version = 450; + profile = ECoreProfile; +#endif + // // Initialize the context-dependent (resource-dependent) built-in strings for parsing. // @@ -7273,7 +7155,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf //============================================================================ TString& s = commonBuiltins; - const int maxSize = 80; + const int maxSize = 200; char builtInConstant[maxSize]; // @@ -7319,6 +7201,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } +#ifndef GLSLANG_WEB if (version >= 310) { // geometry @@ -7377,18 +7260,56 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf "in gl_PerVertex {" "highp vec4 gl_Position;" "highp float gl_PointSize;" -#ifdef NV_EXTENSIONS "highp vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering "highp vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes -#endif "} gl_in[gl_MaxPatchVertices];" "\n"); } } + if (version >= 320) { + // tessellation + + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlImageUniforms = %d;", resources.maxTessControlImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationImageUniforms = %d;", resources.maxTessEvaluationImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounters = %d;", resources.maxTessControlAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounters = %d;", resources.maxTessEvaluationAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounterBuffers = %d;", resources.maxTessControlAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounterBuffers = %d;", resources.maxTessEvaluationAtomicCounterBuffers); + s.append(builtInConstant); + } + + if (version >= 100) { + // GL_EXT_blend_func_extended + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxDualSourceDrawBuffersEXT = %d;", resources.maxDualSourceDrawBuffersEXT); + s.append(builtInConstant); + // this is here instead of with the others in initialize(version, profile) due to the dependence on gl_MaxDualSourceDrawBuffersEXT + if (language == EShLangFragment) { + s.append( + "mediump vec4 gl_SecondaryFragColorEXT;" + "mediump vec4 gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT];" + "\n"); + } + } } else { // non-ES profile + if (version > 400) { + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformVectors = %d;", resources.maxVertexUniformVectors); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingVectors = %d;", resources.maxVaryingVectors); + s.append(builtInConstant); + } + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs); s.append(builtInConstant); @@ -7419,7 +7340,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents); s.append(builtInConstant); - if (version < 150 || ARBCompatibility) { + // Moved from just being deprecated into compatibility profile only as of 4.20 + if (version < 420 || profile == ECompatibilityProfile) { snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats); s.append(builtInConstant); } @@ -7567,10 +7489,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf if (profile != EEsProfile && version >= 450) s.append( "float gl_CullDistance[];" -#ifdef NV_EXTENSIONS "vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering "vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes -#endif ); s.append( "} gl_in[gl_MaxPatchVertices];" @@ -7604,8 +7524,29 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackInterleavedComponents = %d;", resources.maxTransformFeedbackInterleavedComponents); s.append(builtInConstant); } +#endif } + // compute + if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { + snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupCountX, + resources.maxComputeWorkGroupCountY, + resources.maxComputeWorkGroupCountZ); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupSizeX, + resources.maxComputeWorkGroupSizeY, + resources.maxComputeWorkGroupSizeZ); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeUniformComponents = %d;", resources.maxComputeUniformComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeTextureImageUnits = %d;", resources.maxComputeTextureImageUnits); + s.append(builtInConstant); + + s.append("\n"); + } + +#ifndef GLSLANG_WEB // images (some in compute below) if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 130)) { @@ -7621,6 +7562,19 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } + // compute + if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeImageUniforms = %d;", resources.maxComputeImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounters = %d;", resources.maxComputeAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounterBuffers = %d;", resources.maxComputeAtomicCounterBuffers); + s.append(builtInConstant); + + s.append("\n"); + } + +#ifndef GLSLANG_ANGLE // atomic counters (some in compute below) if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { @@ -7657,31 +7611,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } - - // compute - if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { - snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupCountX, - resources.maxComputeWorkGroupCountY, - resources.maxComputeWorkGroupCountZ); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupSizeX, - resources.maxComputeWorkGroupSizeY, - resources.maxComputeWorkGroupSizeZ); - s.append(builtInConstant); - - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeUniformComponents = %d;", resources.maxComputeUniformComponents); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeTextureImageUnits = %d;", resources.maxComputeTextureImageUnits); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeImageUniforms = %d;", resources.maxComputeImageUniforms); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounters = %d;", resources.maxComputeAtomicCounters); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounterBuffers = %d;", resources.maxComputeAtomicCounterBuffers); - s.append(builtInConstant); - - s.append("\n"); - } +#endif // !GLSLANG_ANGLE // GL_ARB_cull_distance if (profile != EEsProfile && version >= 450) { @@ -7698,15 +7628,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } -#ifdef AMD_EXTENSIONS - // GL_AMD_gcn_shader - if (profile != EEsProfile && version >= 450) { - snprintf(builtInConstant, maxSize, "const int gl_SIMDGroupSizeAMD = 64;"); - s.append(builtInConstant); - } -#endif - -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_ANGLE // SPV_NV_mesh_shader if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { snprintf(builtInConstant, maxSize, "const int gl_MaxMeshOutputVerticesNV = %d;", resources.maxMeshOutputVerticesNV); @@ -7729,6 +7651,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } +#endif #endif s.append("\n"); @@ -7810,6 +7733,14 @@ static void BuiltInVariable(const char* blockName, const char* name, TBuiltInVar // void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) { +#ifdef GLSLANG_WEB + version = 310; + profile = EEsProfile; +#elif defined(GLSLANG_ANGLE) + version = 450; + profile = ECoreProfile; +#endif + // // Tag built-in variables and functions with additional qualifier and extension information // that cannot be declared with the text strings. @@ -7824,6 +7755,23 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion switch(language) { case EShLangVertex: + if (spvVersion.vulkan > 0) { + BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable); + BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable); + } + +#ifndef GLSLANG_WEB + if (spvVersion.vulkan == 0) { + SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable); + SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); + } + + if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) { + // treat these built-ins as aliases of VertexIndex and InstanceIndex + BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable); + BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable); + } + if (profile != EEsProfile) { if (version >= 440) { symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters); @@ -7850,19 +7798,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("readInvocationARB", 1, &E_GL_ARB_shader_ballot); symbolTable.setFunctionExtensions("readFirstInvocationARB", 1, &E_GL_ARB_shader_ballot); - BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); - BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); - BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); - BuiltInVariable("gl_SubGroupGtMaskARB", EbvSubGroupGtMask, symbolTable); - BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); - BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); - - if (spvVersion.vulkan > 0) - // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan - SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); - else - BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); - if (version >= 430) { symbolTable.setFunctionExtensions("anyInvocationARB", 1, &E_GL_ARB_shader_group_vote); symbolTable.setFunctionExtensions("allInvocationsARB", 1, &E_GL_ARB_shader_group_vote); @@ -7870,7 +7805,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } } -#ifdef AMD_EXTENSIONS + if (profile != EEsProfile) { symbolTable.setFunctionExtensions("minInvocationsAMD", 1, &E_GL_AMD_shader_ballot); symbolTable.setFunctionExtensions("maxInvocationsAMD", 1, &E_GL_AMD_shader_ballot); @@ -7904,6 +7839,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } if (profile != EEsProfile) { + symbolTable.setVariableExtensions("gl_SIMDGroupSizeAMD", 1, &E_GL_AMD_gcn_shader); + SpecialQualifier("gl_SIMDGroupSizeAMD", EvqVaryingIn, EbvSubGroupSize, symbolTable); + symbolTable.setFunctionExtensions("cubeFaceIndexAMD", 1, &E_GL_AMD_gcn_shader); symbolTable.setFunctionExtensions("cubeFaceCoordAMD", 1, &E_GL_AMD_gcn_shader); symbolTable.setFunctionExtensions("timeAMD", 1, &E_GL_AMD_gcn_shader); @@ -7913,15 +7851,21 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("fragmentMaskFetchAMD", 1, &E_GL_AMD_shader_fragment_mask); symbolTable.setFunctionExtensions("fragmentFetchAMD", 1, &E_GL_AMD_shader_fragment_mask); } -#endif -#ifdef NV_EXTENSIONS + symbolTable.setFunctionExtensions("countLeadingZeros", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("countTrailingZeros", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("absoluteDifference", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("addSaturate", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("subtractSaturate", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("average", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("averageRounded", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("multiply32x16", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("textureFootprintNV", 1, &E_GL_NV_shader_texture_footprint); symbolTable.setFunctionExtensions("textureFootprintClampNV", 1, &E_GL_NV_shader_texture_footprint); symbolTable.setFunctionExtensions("textureFootprintLodNV", 1, &E_GL_NV_shader_texture_footprint); symbolTable.setFunctionExtensions("textureFootprintGradNV", 1, &E_GL_NV_shader_texture_footprint); symbolTable.setFunctionExtensions("textureFootprintGradClampNV", 1, &E_GL_NV_shader_texture_footprint); -#endif // Compatibility variables, vertex only if (spvVersion.spv == 0) { BuiltInVariable("gl_Color", EbvColor, symbolTable); @@ -7962,16 +7906,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic); } - if (spvVersion.vulkan == 0) { - SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable); - SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); - } - - if (spvVersion.vulkan > 0) { - BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable); - BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable); - } - if (version >= 300 /* both ES and non-ES */) { symbolTable.setVariableExtensions("gl_ViewID_OVR", Num_OVR_multiview_EXTs, OVR_multiview_EXTs); BuiltInVariable("gl_ViewID_OVR", EbvViewIndex, symbolTable); @@ -7981,32 +7915,41 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers); symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers); } - // Fall through case EShLangTessControl: if (profile == EEsProfile && version >= 310) { + BuiltInVariable("gl_BoundingBoxEXT", EbvBoundingBox, symbolTable); + symbolTable.setVariableExtensions("gl_BoundingBoxEXT", 1, + &E_GL_EXT_primitive_bounding_box); BuiltInVariable("gl_BoundingBoxOES", EbvBoundingBox, symbolTable); - if (version < 320) - symbolTable.setVariableExtensions("gl_BoundingBoxOES", Num_AEP_primitive_bounding_box, - AEP_primitive_bounding_box); - } + symbolTable.setVariableExtensions("gl_BoundingBoxOES", 1, + &E_GL_OES_primitive_bounding_box); + if (version >= 320) { + BuiltInVariable("gl_BoundingBox", EbvBoundingBox, symbolTable); + } + } // Fall through case EShLangTessEvaluation: case EShLangGeometry: +#endif // !GLSLANG_WEB SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable); SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable); - SpecialQualifier("gl_ClipVertex", EvqClipVertex, EbvClipVertex, symbolTable); BuiltInVariable("gl_in", "gl_Position", EbvPosition, symbolTable); BuiltInVariable("gl_in", "gl_PointSize", EbvPointSize, symbolTable); - BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable); - BuiltInVariable("gl_in", "gl_CullDistance", EbvCullDistance, symbolTable); BuiltInVariable("gl_out", "gl_Position", EbvPosition, symbolTable); BuiltInVariable("gl_out", "gl_PointSize", EbvPointSize, symbolTable); + +#ifndef GLSLANG_WEB + SpecialQualifier("gl_ClipVertex", EvqClipVertex, EbvClipVertex, symbolTable); + + BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable); + BuiltInVariable("gl_in", "gl_CullDistance", EbvCullDistance, symbolTable); + BuiltInVariable("gl_out", "gl_ClipDistance", EbvClipDistance, symbolTable); BuiltInVariable("gl_out", "gl_CullDistance", EbvCullDistance, symbolTable); @@ -8018,19 +7961,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_Layer", EbvLayer, symbolTable); BuiltInVariable("gl_ViewportIndex", EbvViewportIndex, symbolTable); -#ifdef NV_EXTENSIONS if (language != EShLangGeometry) { symbolTable.setVariableExtensions("gl_Layer", Num_viewportEXTs, viewportEXTs); symbolTable.setVariableExtensions("gl_ViewportIndex", Num_viewportEXTs, viewportEXTs); } -#else - if (language != EShLangGeometry && version >= 410) { - symbolTable.setVariableExtensions("gl_Layer", 1, &E_GL_ARB_shader_viewport_layer_array); - symbolTable.setVariableExtensions("gl_ViewportIndex", 1, &E_GL_ARB_shader_viewport_layer_array); - } -#endif - -#ifdef NV_EXTENSIONS symbolTable.setVariableExtensions("gl_ViewportMask", 1, &E_GL_NV_viewport_array2); symbolTable.setVariableExtensions("gl_SecondaryPositionNV", 1, &E_GL_NV_stereo_view_rendering); symbolTable.setVariableExtensions("gl_SecondaryViewportMaskNV", 1, &E_GL_NV_stereo_view_rendering); @@ -8043,7 +7977,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); BuiltInVariable("gl_ViewportMaskPerViewNV", EbvViewportMaskPerViewNV, symbolTable); - if (language != EShLangVertex) { + if (language == EShLangVertex || language == EShLangGeometry) { symbolTable.setVariableExtensions("gl_in", "gl_SecondaryPositionNV", 1, &E_GL_NV_stereo_view_rendering); symbolTable.setVariableExtensions("gl_in", "gl_PositionPerViewNV", 1, &E_GL_NVX_multiview_per_view_attributes); @@ -8061,7 +7995,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_out", "gl_SecondaryViewportMaskNV", EbvSecondaryViewportMaskNV, symbolTable); BuiltInVariable("gl_out", "gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); BuiltInVariable("gl_out", "gl_ViewportMaskPerViewNV", EbvViewportMaskPerViewNV, symbolTable); -#endif BuiltInVariable("gl_PatchVerticesIn", EbvPatchVertices, symbolTable); BuiltInVariable("gl_TessLevelOuter", EbvTessLevelOuter, symbolTable); @@ -8117,9 +8050,25 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); } - + + if (profile != EEsProfile) { + BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); + BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); + BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); + BuiltInVariable("gl_SubGroupGtMaskARB", EbvSubGroupGtMask, symbolTable); + BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); + BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); + + if (spvVersion.vulkan > 0) + // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan + SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + else + BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); + } + // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupInvocationID", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupEqMask", 1, &E_GL_KHR_shader_subgroup_ballot); @@ -8135,8 +8084,32 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubgroupGtMask", EbvSubgroupGtMask2, symbolTable); BuiltInVariable("gl_SubgroupLeMask", EbvSubgroupLeMask2, symbolTable); BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); + + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); } + if (language == EShLangGeometry || language == EShLangVertex) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 450)) { + symbolTable.setVariableExtensions("gl_PrimitiveShadingRateEXT", 1, &E_GL_EXT_fragment_shading_rate); + BuiltInVariable("gl_PrimitiveShadingRateEXT", EbvPrimitiveShadingRateKHR, symbolTable); + + symbolTable.setVariableExtensions("gl_ShadingRateFlag2VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + } + } + +#endif // !GLSLANG_WEB break; case EShLangFragment: @@ -8153,6 +8126,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } } SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable); +#ifndef GLSLANG_WEB SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable); SpecialQualifier("gl_HelperInvocation", EvqVaryingIn, EbvHelperInvocation, symbolTable); @@ -8165,18 +8139,61 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_FragStencilRefARB", EbvFragStencilRef, symbolTable); } - if ((profile != EEsProfile && version >= 400) || + if (profile != EEsProfile && version < 400) { + symbolTable.setFunctionExtensions("textureQueryLod", 1, &E_GL_ARB_texture_query_lod); + } + + if (profile != EEsProfile && version >= 460) { + symbolTable.setFunctionExtensions("rayQueryInitializeEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryTerminateEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGenerateIntersectionEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryConfirmIntersectionEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryProceedEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionTypeEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionTEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetRayFlagsEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetRayTMinEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionInstanceCustomIndexEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionInstanceIdEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionGeometryIndexEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionPrimitiveIndexEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionBarycentricsEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionFrontFaceEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionCandidateAABBOpaqueEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionObjectRayDirectionEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionObjectRayOriginEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionObjectToWorldEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionWorldToObjectEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetWorldRayOriginEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetWorldRayDirectionEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setVariableExtensions("gl_RayFlagsSkipAABBEXT", 1, &E_GL_EXT_ray_flags_primitive_culling); + symbolTable.setVariableExtensions("gl_RayFlagsSkipTrianglesEXT", 1, &E_GL_EXT_ray_flags_primitive_culling); + } + + if ((profile != EEsProfile && version >= 130) || (profile == EEsProfile && version >= 310)) { - BuiltInVariable("gl_SampleID", EbvSampleId, symbolTable); - BuiltInVariable("gl_SamplePosition", EbvSamplePosition, symbolTable); - BuiltInVariable("gl_SampleMaskIn", EbvSampleMask, symbolTable); - BuiltInVariable("gl_SampleMask", EbvSampleMask, symbolTable); - if (profile == EEsProfile && version < 320) { - symbolTable.setVariableExtensions("gl_SampleID", 1, &E_GL_OES_sample_variables); - symbolTable.setVariableExtensions("gl_SamplePosition", 1, &E_GL_OES_sample_variables); - symbolTable.setVariableExtensions("gl_SampleMaskIn", 1, &E_GL_OES_sample_variables); - symbolTable.setVariableExtensions("gl_SampleMask", 1, &E_GL_OES_sample_variables); - symbolTable.setVariableExtensions("gl_NumSamples", 1, &E_GL_OES_sample_variables); + BuiltInVariable("gl_SampleID", EbvSampleId, symbolTable); + BuiltInVariable("gl_SamplePosition", EbvSamplePosition, symbolTable); + BuiltInVariable("gl_SampleMask", EbvSampleMask, symbolTable); + + if (profile != EEsProfile && version < 400) { + BuiltInVariable("gl_NumSamples", EbvSampleMask, symbolTable); + + symbolTable.setVariableExtensions("gl_SampleMask", 1, &E_GL_ARB_sample_shading); + symbolTable.setVariableExtensions("gl_SampleID", 1, &E_GL_ARB_sample_shading); + symbolTable.setVariableExtensions("gl_SamplePosition", 1, &E_GL_ARB_sample_shading); + symbolTable.setVariableExtensions("gl_NumSamples", 1, &E_GL_ARB_sample_shading); + } else { + BuiltInVariable("gl_SampleMaskIn", EbvSampleMask, symbolTable); + + if (profile == EEsProfile && version < 320) { + symbolTable.setVariableExtensions("gl_SampleID", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_SamplePosition", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_SampleMaskIn", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_SampleMask", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_NumSamples", 1, &E_GL_OES_sample_variables); + } } } @@ -8266,6 +8283,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("atomicCounter" , 1, &E_GL_ARB_shader_atomic_counters); } + // E_GL_ARB_shader_atomic_counter_ops + if (profile != EEsProfile && version == 450) { + symbolTable.setFunctionExtensions("atomicCounterAddARB" , 1, &E_GL_ARB_shader_atomic_counter_ops); + symbolTable.setFunctionExtensions("atomicCounterSubtractARB", 1, &E_GL_ARB_shader_atomic_counter_ops); + symbolTable.setFunctionExtensions("atomicCounterMinARB" , 1, &E_GL_ARB_shader_atomic_counter_ops); + symbolTable.setFunctionExtensions("atomicCounterMaxARB" , 1, &E_GL_ARB_shader_atomic_counter_ops); + symbolTable.setFunctionExtensions("atomicCounterAndARB" , 1, &E_GL_ARB_shader_atomic_counter_ops); + symbolTable.setFunctionExtensions("atomicCounterOrARB" , 1, &E_GL_ARB_shader_atomic_counter_ops); + symbolTable.setFunctionExtensions("atomicCounterXorARB" , 1, &E_GL_ARB_shader_atomic_counter_ops); + symbolTable.setFunctionExtensions("atomicCounterExchangeARB", 1, &E_GL_ARB_shader_atomic_counter_ops); + symbolTable.setFunctionExtensions("atomicCounterCompSwapARB", 1, &E_GL_ARB_shader_atomic_counter_ops); + } + // E_GL_ARB_derivative_control if (profile != EEsProfile && version < 450) { symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_ARB_derivative_control); @@ -8307,7 +8337,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("textureGradOffsetClampARB", 1, &E_GL_ARB_sparse_texture_clamp); } -#ifdef AMD_EXTENSIONS // E_GL_AMD_shader_explicit_vertex_parameter if (profile != EEsProfile) { symbolTable.setVariableExtensions("gl_BaryCoordNoPerspAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); @@ -8345,9 +8374,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("imageStoreLodAMD", 1, &E_GL_AMD_shader_image_load_store_lod); symbolTable.setFunctionExtensions("sparseImageLoadLodAMD", 1, &E_GL_AMD_shader_image_load_store_lod); } -#endif - -#ifdef NV_EXTENSIONS if (profile != EEsProfile && version >= 430) { symbolTable.setVariableExtensions("gl_FragFullyCoveredNV", 1, &E_GL_NV_conservative_raster_underestimation); BuiltInVariable("gl_FragFullyCoveredNV", EbvFragFullyCoveredNV, symbolTable); @@ -8363,20 +8389,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_BaryCoordNV", EbvBaryCoordNV, symbolTable); BuiltInVariable("gl_BaryCoordNoPerspNV", EbvBaryCoordNoPerspNV, symbolTable); } - if (((profile != EEsProfile && version >= 450) || - (profile == EEsProfile && version >= 320)) && - language == EShLangCompute) { - symbolTable.setFunctionExtensions("dFdx", 1, &E_GL_NV_compute_shader_derivatives); - symbolTable.setFunctionExtensions("dFdy", 1, &E_GL_NV_compute_shader_derivatives); - symbolTable.setFunctionExtensions("fwidth", 1, &E_GL_NV_compute_shader_derivatives); - symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_NV_compute_shader_derivatives); - symbolTable.setFunctionExtensions("dFdyFine", 1, &E_GL_NV_compute_shader_derivatives); - symbolTable.setFunctionExtensions("fwidthFine", 1, &E_GL_NV_compute_shader_derivatives); - symbolTable.setFunctionExtensions("dFdxCoarse", 1, &E_GL_NV_compute_shader_derivatives); - symbolTable.setFunctionExtensions("dFdyCoarse", 1, &E_GL_NV_compute_shader_derivatives); - symbolTable.setFunctionExtensions("fwidthCoarse", 1, &E_GL_NV_compute_shader_derivatives); - } -#endif if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) { @@ -8388,6 +8400,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth); + symbolTable.setFunctionExtensions("clockARB", 1, &E_GL_ARB_shader_clock); + symbolTable.setFunctionExtensions("clock2x32ARB", 1, &E_GL_ARB_shader_clock); + + symbolTable.setFunctionExtensions("clockRealtimeEXT", 1, &E_GL_EXT_shader_realtime_clock); + symbolTable.setFunctionExtensions("clockRealtime2x32EXT", 1, &E_GL_EXT_shader_realtime_clock); + if (profile == EEsProfile && version < 320) { symbolTable.setVariableExtensions("gl_PrimitiveID", Num_AEP_geometry_shader, AEP_geometry_shader); symbolTable.setVariableExtensions("gl_Layer", Num_AEP_geometry_shader, AEP_geometry_shader); @@ -8404,6 +8422,45 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic); } + if (profile != EEsProfile && version < 330 ) { + symbolTable.setFunctionExtensions("floatBitsToInt", 1, &E_GL_ARB_shader_bit_encoding); + symbolTable.setFunctionExtensions("floatBitsToUint", 1, &E_GL_ARB_shader_bit_encoding); + symbolTable.setFunctionExtensions("intBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding); + symbolTable.setFunctionExtensions("uintBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding); + } + + if (profile != EEsProfile && version < 430 ) { + symbolTable.setFunctionExtensions("imageSize", 1, &E_GL_ARB_shader_image_size); + } + + // GL_ARB_shader_storage_buffer_object + if (profile != EEsProfile && version < 430 ) { + symbolTable.setFunctionExtensions("atomicAdd", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicMin", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicMax", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicAnd", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicOr", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicXor", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicExchange", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicCompSwap", 1, &E_GL_ARB_shader_storage_buffer_object); + } + + // GL_ARB_shading_language_packing + if (profile != EEsProfile && version < 400 ) { + symbolTable.setFunctionExtensions("packUnorm2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackUnorm2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("packSnorm4x8", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("packUnorm4x8", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackSnorm4x8", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackUnorm4x8", 1, &E_GL_ARB_shading_language_packing); + } + if (profile != EEsProfile && version < 420 ) { + symbolTable.setFunctionExtensions("packSnorm2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackSnorm2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackHalf2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("packHalf2x16", 1, &E_GL_ARB_shading_language_packing); + } + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); @@ -8438,7 +8495,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupInvocationID", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupEqMask", 1, &E_GL_KHR_shader_subgroup_ballot); @@ -8509,8 +8567,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("subgroupQuadSwapHorizontal", 1, &E_GL_KHR_shader_subgroup_quad); symbolTable.setFunctionExtensions("subgroupQuadSwapVertical", 1, &E_GL_KHR_shader_subgroup_quad); symbolTable.setFunctionExtensions("subgroupQuadSwapDiagonal", 1, &E_GL_KHR_shader_subgroup_quad); - -#ifdef NV_EXTENSIONS symbolTable.setFunctionExtensions("subgroupPartitionNV", 1, &E_GL_NV_shader_subgroup_partitioned); symbolTable.setFunctionExtensions("subgroupPartitionedAddNV", 1, &E_GL_NV_shader_subgroup_partitioned); symbolTable.setFunctionExtensions("subgroupPartitionedMulNV", 1, &E_GL_NV_shader_subgroup_partitioned); @@ -8533,8 +8589,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveAndNV", 1, &E_GL_NV_shader_subgroup_partitioned); symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveOrNV", 1, &E_GL_NV_shader_subgroup_partitioned); symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveXorNV", 1, &E_GL_NV_shader_subgroup_partitioned); -#endif + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); } if (profile == EEsProfile) { @@ -8554,6 +8618,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_SemanticsAcquireRelease", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setVariableExtensions("gl_SemanticsMakeAvailable", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setVariableExtensions("gl_SemanticsMakeVisible", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_SemanticsVolatile", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setVariableExtensions("gl_StorageSemanticsNone", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setVariableExtensions("gl_StorageSemanticsBuffer", 1, &E_GL_KHR_memory_scope_semantics); @@ -8561,6 +8626,20 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_StorageSemanticsImage", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setVariableExtensions("gl_StorageSemanticsOutput", 1, &E_GL_KHR_memory_scope_semantics); } + + symbolTable.setFunctionExtensions("helperInvocationEXT", 1, &E_GL_EXT_demote_to_helper_invocation); + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 450)) { + symbolTable.setVariableExtensions("gl_ShadingRateEXT", 1, &E_GL_EXT_fragment_shading_rate); + BuiltInVariable("gl_ShadingRateEXT", EbvShadingRateKHR, symbolTable); + + symbolTable.setVariableExtensions("gl_ShadingRateFlag2VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + } +#endif // !GLSLANG_WEB break; case EShLangCompute: @@ -8570,6 +8649,15 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_LocalInvocationID", EbvLocalInvocationId, symbolTable); BuiltInVariable("gl_GlobalInvocationID", EbvGlobalInvocationId, symbolTable); BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); + +#ifndef GLSLANG_WEB + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); + symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); + } if (profile != EEsProfile && version < 430) { symbolTable.setVariableExtensions("gl_NumWorkGroups", 1, &E_GL_ARB_compute_shader); @@ -8595,7 +8683,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_ARB_compute_shader); } + symbolTable.setFunctionExtensions("controlBarrier", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setFunctionExtensions("debugPrintfEXT", 1, &E_GL_EXT_debug_printf); // GL_ARB_shader_ballot if (profile != EEsProfile) { @@ -8622,7 +8712,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupInvocationID", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupEqMask", 1, &E_GL_KHR_shader_subgroup_ballot); @@ -8638,18 +8729,21 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubgroupGtMask", EbvSubgroupGtMask2, symbolTable); BuiltInVariable("gl_SubgroupLeMask", EbvSubgroupLeMask2, symbolTable); BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); - } - if ((profile != EEsProfile && version >= 140) || - (profile == EEsProfile && version >= 310)) { - symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); - BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); - symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); - BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { symbolTable.setVariableExtensions("gl_NumSubgroups", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupID", 1, &E_GL_KHR_shader_subgroup_basic); @@ -8658,53 +8752,192 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic); } + + { + const char *coopExt[2] = { E_GL_NV_cooperative_matrix, E_GL_NV_integer_cooperative_matrix }; + symbolTable.setFunctionExtensions("coopMatLoadNV", 2, coopExt); + symbolTable.setFunctionExtensions("coopMatStoreNV", 2, coopExt); + symbolTable.setFunctionExtensions("coopMatMulAddNV", 2, coopExt); + } + + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + symbolTable.setFunctionExtensions("dFdx", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdy", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("fwidth", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdyFine", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("fwidthFine", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdxCoarse", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdyCoarse", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("fwidthCoarse", 1, &E_GL_NV_compute_shader_derivatives); + } + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 450)) { + symbolTable.setVariableExtensions("gl_ShadingRateFlag2VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + } +#endif // !GLSLANG_WEB break; -#ifdef NV_EXTENSIONS - case EShLangRayGenNV: - case EShLangIntersectNV: - case EShLangAnyHitNV: - case EShLangClosestHitNV: - case EShLangMissNV: - case EShLangCallableNV: + +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + case EShLangRayGen: + case EShLangIntersect: + case EShLangAnyHit: + case EShLangClosestHit: + case EShLangMiss: + case EShLangCallable: if (profile != EEsProfile && version >= 460) { + const char *rtexts[] = { E_GL_NV_ray_tracing, E_GL_EXT_ray_tracing }; symbolTable.setVariableExtensions("gl_LaunchIDNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_LaunchIDEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_LaunchSizeNV", 1, &E_GL_NV_ray_tracing); - symbolTable.setVariableExtensions("gl_PrimitiveID", 1, &E_GL_NV_ray_tracing); - symbolTable.setVariableExtensions("gl_InstanceID", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_LaunchSizeEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_PrimitiveID", 2, rtexts); + symbolTable.setVariableExtensions("gl_InstanceID", 2, rtexts); symbolTable.setVariableExtensions("gl_InstanceCustomIndexNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_InstanceCustomIndexEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_GeometryIndexEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_WorldRayOriginNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldRayOriginEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_WorldRayDirectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldRayDirectionEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_ObjectRayOriginNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectRayOriginEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_ObjectRayDirectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectRayDirectionEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_RayTminNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_RayTminEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_RayTmaxNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_RayTmaxEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_HitTNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_HitTEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_HitKindNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_HitKindEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_ObjectToWorldNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectToWorldEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectToWorld3x4EXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_WorldToObjectNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldToObjectEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldToObject3x4EXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_CurrentRayTimeNV", 1, &E_GL_NV_ray_tracing_motion_blur); symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); - BuiltInVariable("gl_LaunchIDNV", EbvLaunchIdNV, symbolTable); - BuiltInVariable("gl_LaunchSizeNV", EbvLaunchSizeNV, symbolTable); - BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable); - BuiltInVariable("gl_InstanceID", EbvInstanceId, symbolTable); - BuiltInVariable("gl_InstanceCustomIndexNV", EbvInstanceCustomIndexNV,symbolTable); - BuiltInVariable("gl_WorldRayOriginNV", EbvWorldRayOriginNV, symbolTable); - BuiltInVariable("gl_WorldRayDirectionNV", EbvWorldRayDirectionNV, symbolTable); - BuiltInVariable("gl_ObjectRayOriginNV", EbvObjectRayOriginNV, symbolTable); - BuiltInVariable("gl_ObjectRayDirectionNV", EbvObjectRayDirectionNV, symbolTable); - BuiltInVariable("gl_RayTminNV", EbvRayTminNV, symbolTable); - BuiltInVariable("gl_RayTmaxNV", EbvRayTmaxNV, symbolTable); - BuiltInVariable("gl_HitTNV", EbvHitTNV, symbolTable); - BuiltInVariable("gl_HitKindNV", EbvHitKindNV, symbolTable); - BuiltInVariable("gl_ObjectToWorldNV", EbvObjectToWorldNV, symbolTable); - BuiltInVariable("gl_WorldToObjectNV", EbvWorldToObjectNV, symbolTable); - BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlagsNV, symbolTable); - BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); - } + + symbolTable.setFunctionExtensions("traceNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("traceRayMotionNV", 1, &E_GL_NV_ray_tracing_motion_blur); + symbolTable.setFunctionExtensions("traceRayEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setFunctionExtensions("reportIntersectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("reportIntersectionEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setFunctionExtensions("ignoreIntersectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("terminateRayNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("executeCallableNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("executeCallableEXT", 1, &E_GL_EXT_ray_tracing); + + + BuiltInVariable("gl_LaunchIDNV", EbvLaunchId, symbolTable); + BuiltInVariable("gl_LaunchIDEXT", EbvLaunchId, symbolTable); + BuiltInVariable("gl_LaunchSizeNV", EbvLaunchSize, symbolTable); + BuiltInVariable("gl_LaunchSizeEXT", EbvLaunchSize, symbolTable); + BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable); + BuiltInVariable("gl_InstanceID", EbvInstanceId, symbolTable); + BuiltInVariable("gl_InstanceCustomIndexNV", EbvInstanceCustomIndex,symbolTable); + BuiltInVariable("gl_InstanceCustomIndexEXT", EbvInstanceCustomIndex,symbolTable); + BuiltInVariable("gl_GeometryIndexEXT", EbvGeometryIndex, symbolTable); + BuiltInVariable("gl_WorldRayOriginNV", EbvWorldRayOrigin, symbolTable); + BuiltInVariable("gl_WorldRayOriginEXT", EbvWorldRayOrigin, symbolTable); + BuiltInVariable("gl_WorldRayDirectionNV", EbvWorldRayDirection, symbolTable); + BuiltInVariable("gl_WorldRayDirectionEXT", EbvWorldRayDirection, symbolTable); + BuiltInVariable("gl_ObjectRayOriginNV", EbvObjectRayOrigin, symbolTable); + BuiltInVariable("gl_ObjectRayOriginEXT", EbvObjectRayOrigin, symbolTable); + BuiltInVariable("gl_ObjectRayDirectionNV", EbvObjectRayDirection, symbolTable); + BuiltInVariable("gl_ObjectRayDirectionEXT", EbvObjectRayDirection, symbolTable); + BuiltInVariable("gl_RayTminNV", EbvRayTmin, symbolTable); + BuiltInVariable("gl_RayTminEXT", EbvRayTmin, symbolTable); + BuiltInVariable("gl_RayTmaxNV", EbvRayTmax, symbolTable); + BuiltInVariable("gl_RayTmaxEXT", EbvRayTmax, symbolTable); + BuiltInVariable("gl_HitTNV", EbvHitT, symbolTable); + BuiltInVariable("gl_HitTEXT", EbvHitT, symbolTable); + BuiltInVariable("gl_HitKindNV", EbvHitKind, symbolTable); + BuiltInVariable("gl_HitKindEXT", EbvHitKind, symbolTable); + BuiltInVariable("gl_ObjectToWorldNV", EbvObjectToWorld, symbolTable); + BuiltInVariable("gl_ObjectToWorldEXT", EbvObjectToWorld, symbolTable); + BuiltInVariable("gl_ObjectToWorld3x4EXT", EbvObjectToWorld3x4, symbolTable); + BuiltInVariable("gl_WorldToObjectNV", EbvWorldToObject, symbolTable); + BuiltInVariable("gl_WorldToObjectEXT", EbvWorldToObject, symbolTable); + BuiltInVariable("gl_WorldToObject3x4EXT", EbvWorldToObject3x4, symbolTable); + BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlags, symbolTable); + BuiltInVariable("gl_IncomingRayFlagsEXT", EbvIncomingRayFlags, symbolTable); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + BuiltInVariable("gl_CurrentRayTimeNV", EbvCurrentRayTimeNV, symbolTable); + + // GL_ARB_shader_ballot + symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupEqMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGtMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLtMaskARB", 1, &E_GL_ARB_shader_ballot); + + BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); + BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); + BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); + BuiltInVariable("gl_SubGroupGtMaskARB", EbvSubGroupGtMask, symbolTable); + BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); + BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); + + if (spvVersion.vulkan > 0) + // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan + SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + else + BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); + + // GL_KHR_shader_subgroup + symbolTable.setVariableExtensions("gl_NumSubgroups", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupID", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupInvocationID", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupEqMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + + BuiltInVariable("gl_NumSubgroups", EbvNumSubgroups, symbolTable); + BuiltInVariable("gl_SubgroupID", EbvSubgroupID, symbolTable); + BuiltInVariable("gl_SubgroupSize", EbvSubgroupSize2, symbolTable); + BuiltInVariable("gl_SubgroupInvocationID", EbvSubgroupInvocation2, symbolTable); + BuiltInVariable("gl_SubgroupEqMask", EbvSubgroupEqMask2, symbolTable); + BuiltInVariable("gl_SubgroupGeMask", EbvSubgroupGeMask2, symbolTable); + BuiltInVariable("gl_SubgroupGtMask", EbvSubgroupGtMask2, symbolTable); + BuiltInVariable("gl_SubgroupLeMask", EbvSubgroupLeMask2, symbolTable); + BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); + + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + } + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 450)) { + symbolTable.setVariableExtensions("gl_ShadingRateFlag2VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + } break; + case EShLangMeshNV: if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { // per-vertex builtins @@ -8813,7 +9046,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { symbolTable.setVariableExtensions("gl_NumSubgroups", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupID", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); @@ -8835,6 +9069,24 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic); + + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + } + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 450)) { + symbolTable.setVariableExtensions("gl_ShadingRateFlag2VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); } break; @@ -8902,7 +9154,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { symbolTable.setVariableExtensions("gl_NumSubgroups", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupID", 1, &E_GL_KHR_shader_subgroup_basic); symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); @@ -8924,6 +9177,23 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic); + + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + } + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 450)) { + symbolTable.setVariableExtensions("gl_ShadingRateFlag2VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4VerticalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); + symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); } break; #endif @@ -8939,74 +9209,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion // expected to be resolved through a library of functions, versus as // operations. // - symbolTable.relateToOperator("not", EOpVectorLogicalNot); - symbolTable.relateToOperator("matrixCompMult", EOpMul); - // 120 and 150 are correct for both ES and desktop - if (version >= 120) { - symbolTable.relateToOperator("outerProduct", EOpOuterProduct); - symbolTable.relateToOperator("transpose", EOpTranspose); - if (version >= 150) { - symbolTable.relateToOperator("determinant", EOpDeterminant); - symbolTable.relateToOperator("inverse", EOpMatrixInverse); - } - } + relateTabledBuiltins(version, profile, spvVersion, language, symbolTable); - symbolTable.relateToOperator("mod", EOpMod); - symbolTable.relateToOperator("modf", EOpModf); - - symbolTable.relateToOperator("equal", EOpVectorEqual); - symbolTable.relateToOperator("notEqual", EOpVectorNotEqual); - symbolTable.relateToOperator("lessThan", EOpLessThan); - symbolTable.relateToOperator("greaterThan", EOpGreaterThan); - symbolTable.relateToOperator("lessThanEqual", EOpLessThanEqual); - symbolTable.relateToOperator("greaterThanEqual", EOpGreaterThanEqual); - - symbolTable.relateToOperator("radians", EOpRadians); - symbolTable.relateToOperator("degrees", EOpDegrees); - symbolTable.relateToOperator("sin", EOpSin); - symbolTable.relateToOperator("cos", EOpCos); - symbolTable.relateToOperator("tan", EOpTan); - symbolTable.relateToOperator("asin", EOpAsin); - symbolTable.relateToOperator("acos", EOpAcos); - symbolTable.relateToOperator("atan", EOpAtan); - symbolTable.relateToOperator("sinh", EOpSinh); - symbolTable.relateToOperator("cosh", EOpCosh); - symbolTable.relateToOperator("tanh", EOpTanh); - symbolTable.relateToOperator("asinh", EOpAsinh); - symbolTable.relateToOperator("acosh", EOpAcosh); - symbolTable.relateToOperator("atanh", EOpAtanh); - - symbolTable.relateToOperator("pow", EOpPow); - symbolTable.relateToOperator("exp2", EOpExp2); - symbolTable.relateToOperator("log", EOpLog); - symbolTable.relateToOperator("exp", EOpExp); - symbolTable.relateToOperator("log2", EOpLog2); - symbolTable.relateToOperator("sqrt", EOpSqrt); - symbolTable.relateToOperator("inversesqrt", EOpInverseSqrt); - - symbolTable.relateToOperator("abs", EOpAbs); - symbolTable.relateToOperator("sign", EOpSign); - symbolTable.relateToOperator("floor", EOpFloor); - symbolTable.relateToOperator("trunc", EOpTrunc); - symbolTable.relateToOperator("round", EOpRound); - symbolTable.relateToOperator("roundEven", EOpRoundEven); - symbolTable.relateToOperator("ceil", EOpCeil); - symbolTable.relateToOperator("fract", EOpFract); - symbolTable.relateToOperator("min", EOpMin); - symbolTable.relateToOperator("max", EOpMax); - symbolTable.relateToOperator("clamp", EOpClamp); - symbolTable.relateToOperator("mix", EOpMix); - symbolTable.relateToOperator("step", EOpStep); - symbolTable.relateToOperator("smoothstep", EOpSmoothStep); - - symbolTable.relateToOperator("isnan", EOpIsNan); - symbolTable.relateToOperator("isinf", EOpIsInf); - - symbolTable.relateToOperator("floatBitsToInt", EOpFloatBitsToInt); - symbolTable.relateToOperator("floatBitsToUint", EOpFloatBitsToUint); - symbolTable.relateToOperator("intBitsToFloat", EOpIntBitsToFloat); - symbolTable.relateToOperator("uintBitsToFloat", EOpUintBitsToFloat); +#ifndef GLSLANG_WEB symbolTable.relateToOperator("doubleBitsToInt64", EOpDoubleBitsToInt64); symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64); symbolTable.relateToOperator("int64BitsToDouble", EOpInt64BitsToDouble); @@ -9021,11 +9227,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("int16BitsToHalf", EOpInt16BitsToFloat16); symbolTable.relateToOperator("uint16BitsToHalf", EOpUint16BitsToFloat16); - symbolTable.relateToOperator("packSnorm2x16", EOpPackSnorm2x16); - symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16); - symbolTable.relateToOperator("packUnorm2x16", EOpPackUnorm2x16); - symbolTable.relateToOperator("unpackUnorm2x16", EOpUnpackUnorm2x16); - symbolTable.relateToOperator("packSnorm4x8", EOpPackSnorm4x8); symbolTable.relateToOperator("unpackSnorm4x8", EOpUnpackSnorm4x8); symbolTable.relateToOperator("packUnorm4x8", EOpPackUnorm4x8); @@ -9034,9 +9235,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("packDouble2x32", EOpPackDouble2x32); symbolTable.relateToOperator("unpackDouble2x32", EOpUnpackDouble2x32); - symbolTable.relateToOperator("packHalf2x16", EOpPackHalf2x16); - symbolTable.relateToOperator("unpackHalf2x16", EOpUnpackHalf2x16); - symbolTable.relateToOperator("packInt2x32", EOpPackInt2x32); symbolTable.relateToOperator("unpackInt2x32", EOpUnpackInt2x32); symbolTable.relateToOperator("packUint2x32", EOpPackUint2x32); @@ -9062,33 +9260,18 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("unpack16", EOpUnpack16); symbolTable.relateToOperator("unpack8", EOpUnpack8); - symbolTable.relateToOperator("length", EOpLength); - symbolTable.relateToOperator("distance", EOpDistance); - symbolTable.relateToOperator("dot", EOpDot); - symbolTable.relateToOperator("cross", EOpCross); - symbolTable.relateToOperator("normalize", EOpNormalize); - symbolTable.relateToOperator("faceforward", EOpFaceForward); - symbolTable.relateToOperator("reflect", EOpReflect); - symbolTable.relateToOperator("refract", EOpRefract); - - symbolTable.relateToOperator("any", EOpAny); - symbolTable.relateToOperator("all", EOpAll); - - symbolTable.relateToOperator("barrier", EOpBarrier); symbolTable.relateToOperator("controlBarrier", EOpBarrier); - symbolTable.relateToOperator("memoryBarrier", EOpMemoryBarrier); symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter); - symbolTable.relateToOperator("memoryBarrierBuffer", EOpMemoryBarrierBuffer); symbolTable.relateToOperator("memoryBarrierImage", EOpMemoryBarrierImage); - symbolTable.relateToOperator("atomicAdd", EOpAtomicAdd); - symbolTable.relateToOperator("atomicMin", EOpAtomicMin); - symbolTable.relateToOperator("atomicMax", EOpAtomicMax); - symbolTable.relateToOperator("atomicAnd", EOpAtomicAnd); - symbolTable.relateToOperator("atomicOr", EOpAtomicOr); - symbolTable.relateToOperator("atomicXor", EOpAtomicXor); - symbolTable.relateToOperator("atomicExchange", EOpAtomicExchange); - symbolTable.relateToOperator("atomicCompSwap", EOpAtomicCompSwap); + if (spvVersion.vulkanRelaxed) { + // + // functions signature have been replaced to take uint operations on buffer variables + // remap atomic counter functions to atomic operations + // + symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierBuffer); + } + symbolTable.relateToOperator("atomicLoad", EOpAtomicLoad); symbolTable.relateToOperator("atomicStore", EOpAtomicStore); @@ -9096,6 +9279,38 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement); symbolTable.relateToOperator("atomicCounter", EOpAtomicCounter); + if (spvVersion.vulkanRelaxed) { + // + // functions signature have been replaced to take uint operations + // remap atomic counter functions to atomic operations + // + // these atomic counter functions do not match signatures of glsl + // atomic functions, so they will be remapped to semantically + // equivalent functions in the parser + // + symbolTable.relateToOperator("atomicCounterIncrement", EOpNull); + symbolTable.relateToOperator("atomicCounterDecrement", EOpNull); + symbolTable.relateToOperator("atomicCounter", EOpNull); + } + + symbolTable.relateToOperator("clockARB", EOpReadClockSubgroupKHR); + symbolTable.relateToOperator("clock2x32ARB", EOpReadClockSubgroupKHR); + + symbolTable.relateToOperator("clockRealtimeEXT", EOpReadClockDeviceKHR); + symbolTable.relateToOperator("clockRealtime2x32EXT", EOpReadClockDeviceKHR); + + if (profile != EEsProfile && version == 450) { + symbolTable.relateToOperator("atomicCounterAddARB", EOpAtomicCounterAdd); + symbolTable.relateToOperator("atomicCounterSubtractARB", EOpAtomicCounterSubtract); + symbolTable.relateToOperator("atomicCounterMinARB", EOpAtomicCounterMin); + symbolTable.relateToOperator("atomicCounterMaxARB", EOpAtomicCounterMax); + symbolTable.relateToOperator("atomicCounterAndARB", EOpAtomicCounterAnd); + symbolTable.relateToOperator("atomicCounterOrARB", EOpAtomicCounterOr); + symbolTable.relateToOperator("atomicCounterXorARB", EOpAtomicCounterXor); + symbolTable.relateToOperator("atomicCounterExchangeARB", EOpAtomicCounterExchange); + symbolTable.relateToOperator("atomicCounterCompSwapARB", EOpAtomicCounterCompSwap); + } + if (profile != EEsProfile && version >= 460) { symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicCounterAdd); symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract); @@ -9108,6 +9323,23 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCounterCompSwap); } + if (spvVersion.vulkanRelaxed) { + // + // functions signature have been replaced to take 'uint' instead of 'atomic_uint' + // remap atomic counter functions to non-counter atomic ops so + // functions act as aliases to non-counter atomic ops + // + symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicAdd); + symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicSubtract); + symbolTable.relateToOperator("atomicCounterMin", EOpAtomicMin); + symbolTable.relateToOperator("atomicCounterMax", EOpAtomicMax); + symbolTable.relateToOperator("atomicCounterAnd", EOpAtomicAnd); + symbolTable.relateToOperator("atomicCounterOr", EOpAtomicOr); + symbolTable.relateToOperator("atomicCounterXor", EOpAtomicXor); + symbolTable.relateToOperator("atomicCounterExchange", EOpAtomicExchange); + symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCompSwap); + } + symbolTable.relateToOperator("fma", EOpFma); symbolTable.relateToOperator("frexp", EOpFrexp); symbolTable.relateToOperator("ldexp", EOpLdexp); @@ -9122,6 +9354,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("findLSB", EOpFindLSB); symbolTable.relateToOperator("findMSB", EOpFindMSB); + symbolTable.relateToOperator("helperInvocationEXT", EOpIsHelperInvocation); + + symbolTable.relateToOperator("countLeadingZeros", EOpCountLeadingZeros); + symbolTable.relateToOperator("countTrailingZeros", EOpCountTrailingZeros); + symbolTable.relateToOperator("absoluteDifference", EOpAbsDifference); + symbolTable.relateToOperator("addSaturate", EOpAddSaturate); + symbolTable.relateToOperator("subtractSaturate", EOpSubSaturate); + symbolTable.relateToOperator("average", EOpAverage); + symbolTable.relateToOperator("averageRounded", EOpAverageRounded); + symbolTable.relateToOperator("multiply32x16", EOpMul32x16); + symbolTable.relateToOperator("debugPrintfEXT", EOpDebugPrintf); + + if (PureOperatorBuiltins) { symbolTable.relateToOperator("imageSize", EOpImageQuerySize); symbolTable.relateToOperator("imageSamples", EOpImageQuerySamples); @@ -9141,24 +9386,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("subpassLoad", EOpSubpassLoad); symbolTable.relateToOperator("subpassLoadMS", EOpSubpassLoadMS); - symbolTable.relateToOperator("textureSize", EOpTextureQuerySize); - symbolTable.relateToOperator("textureQueryLod", EOpTextureQueryLod); - symbolTable.relateToOperator("textureQueryLevels", EOpTextureQueryLevels); - symbolTable.relateToOperator("textureSamples", EOpTextureQuerySamples); - symbolTable.relateToOperator("texture", EOpTexture); - symbolTable.relateToOperator("textureProj", EOpTextureProj); - symbolTable.relateToOperator("textureLod", EOpTextureLod); - symbolTable.relateToOperator("textureOffset", EOpTextureOffset); - symbolTable.relateToOperator("texelFetch", EOpTextureFetch); - symbolTable.relateToOperator("texelFetchOffset", EOpTextureFetchOffset); - symbolTable.relateToOperator("textureProjOffset", EOpTextureProjOffset); - symbolTable.relateToOperator("textureLodOffset", EOpTextureLodOffset); - symbolTable.relateToOperator("textureProjLod", EOpTextureProjLod); - symbolTable.relateToOperator("textureProjLodOffset", EOpTextureProjLodOffset); - symbolTable.relateToOperator("textureGrad", EOpTextureGrad); - symbolTable.relateToOperator("textureGradOffset", EOpTextureGradOffset); - symbolTable.relateToOperator("textureProjGrad", EOpTextureProjGrad); - symbolTable.relateToOperator("textureProjGradOffset", EOpTextureProjGradOffset); symbolTable.relateToOperator("textureGather", EOpTextureGather); symbolTable.relateToOperator("textureGatherOffset", EOpTextureGatherOffset); symbolTable.relateToOperator("textureGatherOffsets", EOpTextureGatherOffsets); @@ -9168,17 +9395,17 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("noise3", EOpNoise); symbolTable.relateToOperator("noise4", EOpNoise); -#ifdef NV_EXTENSIONS symbolTable.relateToOperator("textureFootprintNV", EOpImageSampleFootprintNV); symbolTable.relateToOperator("textureFootprintClampNV", EOpImageSampleFootprintClampNV); symbolTable.relateToOperator("textureFootprintLodNV", EOpImageSampleFootprintLodNV); symbolTable.relateToOperator("textureFootprintGradNV", EOpImageSampleFootprintGradNV); symbolTable.relateToOperator("textureFootprintGradClampNV", EOpImageSampleFootprintGradClampNV); -#endif + + if (spvVersion.spv == 0 && IncludeLegacy(version, profile, spvVersion)) + symbolTable.relateToOperator("ftransform", EOpFtransform); if (spvVersion.spv == 0 && (IncludeLegacy(version, profile, spvVersion) || (profile == EEsProfile && version == 100))) { - symbolTable.relateToOperator("ftransform", EOpFtransform); symbolTable.relateToOperator("texture1D", EOpTexture); symbolTable.relateToOperator("texture1DGradARB", EOpTextureGrad); @@ -9270,7 +9497,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("allInvocations", EOpAllInvocations); symbolTable.relateToOperator("allInvocationsEqual", EOpAllInvocationsEqual); } -#ifdef AMD_EXTENSIONS symbolTable.relateToOperator("minInvocationsAMD", EOpMinInvocations); symbolTable.relateToOperator("maxInvocationsAMD", EOpMaxInvocations); symbolTable.relateToOperator("addInvocationsAMD", EOpAddInvocations); @@ -9315,11 +9541,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("fragmentMaskFetchAMD", EOpFragmentMaskFetch); symbolTable.relateToOperator("fragmentFetchAMD", EOpFragmentFetch); -#endif } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { symbolTable.relateToOperator("subgroupBarrier", EOpSubgroupBarrier); symbolTable.relateToOperator("subgroupMemoryBarrier", EOpSubgroupMemoryBarrier); symbolTable.relateToOperator("subgroupMemoryBarrierBuffer", EOpSubgroupMemoryBarrierBuffer); @@ -9375,7 +9601,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("subgroupQuadSwapVertical", EOpSubgroupQuadSwapVertical); symbolTable.relateToOperator("subgroupQuadSwapDiagonal", EOpSubgroupQuadSwapDiagonal); -#ifdef NV_EXTENSIONS symbolTable.relateToOperator("subgroupPartitionNV", EOpSubgroupPartition); symbolTable.relateToOperator("subgroupPartitionedAddNV", EOpSubgroupPartitionedAdd); symbolTable.relateToOperator("subgroupPartitionedMulNV", EOpSubgroupPartitionedMul); @@ -9398,7 +9623,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("subgroupPartitionedExclusiveAndNV", EOpSubgroupPartitionedExclusiveAnd); symbolTable.relateToOperator("subgroupPartitionedExclusiveOrNV", EOpSubgroupPartitionedExclusiveOr); symbolTable.relateToOperator("subgroupPartitionedExclusiveXorNV", EOpSubgroupPartitionedExclusiveXor); -#endif } if (profile == EEsProfile) { @@ -9423,9 +9647,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion break; case EShLangFragment: - symbolTable.relateToOperator("dFdx", EOpDPdx); - symbolTable.relateToOperator("dFdy", EOpDPdy); - symbolTable.relateToOperator("fwidth", EOpFwidth); if (profile != EEsProfile && version >= 400) { symbolTable.relateToOperator("dFdxFine", EOpDPdxFine); symbolTable.relateToOperator("dFdyFine", EOpDPdyFine); @@ -9434,21 +9655,47 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("dFdyCoarse", EOpDPdyCoarse); symbolTable.relateToOperator("fwidthCoarse", EOpFwidthCoarse); } + + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("rayQueryInitializeEXT", EOpRayQueryInitialize); + symbolTable.relateToOperator("rayQueryTerminateEXT", EOpRayQueryTerminate); + symbolTable.relateToOperator("rayQueryGenerateIntersectionEXT", EOpRayQueryGenerateIntersection); + symbolTable.relateToOperator("rayQueryConfirmIntersectionEXT", EOpRayQueryConfirmIntersection); + symbolTable.relateToOperator("rayQueryProceedEXT", EOpRayQueryProceed); + symbolTable.relateToOperator("rayQueryGetIntersectionTypeEXT", EOpRayQueryGetIntersectionType); + symbolTable.relateToOperator("rayQueryGetRayTMinEXT", EOpRayQueryGetRayTMin); + symbolTable.relateToOperator("rayQueryGetRayFlagsEXT", EOpRayQueryGetRayFlags); + symbolTable.relateToOperator("rayQueryGetIntersectionTEXT", EOpRayQueryGetIntersectionT); + symbolTable.relateToOperator("rayQueryGetIntersectionInstanceCustomIndexEXT", EOpRayQueryGetIntersectionInstanceCustomIndex); + symbolTable.relateToOperator("rayQueryGetIntersectionInstanceIdEXT", EOpRayQueryGetIntersectionInstanceId); + symbolTable.relateToOperator("rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT", EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset); + symbolTable.relateToOperator("rayQueryGetIntersectionGeometryIndexEXT", EOpRayQueryGetIntersectionGeometryIndex); + symbolTable.relateToOperator("rayQueryGetIntersectionPrimitiveIndexEXT", EOpRayQueryGetIntersectionPrimitiveIndex); + symbolTable.relateToOperator("rayQueryGetIntersectionBarycentricsEXT", EOpRayQueryGetIntersectionBarycentrics); + symbolTable.relateToOperator("rayQueryGetIntersectionFrontFaceEXT", EOpRayQueryGetIntersectionFrontFace); + symbolTable.relateToOperator("rayQueryGetIntersectionCandidateAABBOpaqueEXT", EOpRayQueryGetIntersectionCandidateAABBOpaque); + symbolTable.relateToOperator("rayQueryGetIntersectionObjectRayDirectionEXT", EOpRayQueryGetIntersectionObjectRayDirection); + symbolTable.relateToOperator("rayQueryGetIntersectionObjectRayOriginEXT", EOpRayQueryGetIntersectionObjectRayOrigin); + symbolTable.relateToOperator("rayQueryGetWorldRayDirectionEXT", EOpRayQueryGetWorldRayDirection); + symbolTable.relateToOperator("rayQueryGetWorldRayOriginEXT", EOpRayQueryGetWorldRayOrigin); + symbolTable.relateToOperator("rayQueryGetIntersectionObjectToWorldEXT", EOpRayQueryGetIntersectionObjectToWorld); + symbolTable.relateToOperator("rayQueryGetIntersectionWorldToObjectEXT", EOpRayQueryGetIntersectionWorldToObject); + } + symbolTable.relateToOperator("interpolateAtCentroid", EOpInterpolateAtCentroid); symbolTable.relateToOperator("interpolateAtSample", EOpInterpolateAtSample); symbolTable.relateToOperator("interpolateAtOffset", EOpInterpolateAtOffset); -#ifdef AMD_EXTENSIONS if (profile != EEsProfile) symbolTable.relateToOperator("interpolateAtVertexAMD", EOpInterpolateAtVertex); -#endif + + symbolTable.relateToOperator("beginInvocationInterlockARB", EOpBeginInvocationInterlock); + symbolTable.relateToOperator("endInvocationInterlockARB", EOpEndInvocationInterlock); + break; case EShLangCompute: - symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); - symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); symbolTable.relateToOperator("subgroupMemoryBarrierShared", EOpSubgroupMemoryBarrierShared); -#ifdef NV_EXTENSIONS if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { symbolTable.relateToOperator("dFdx", EOpDPdx); @@ -9461,31 +9708,38 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("dFdyCoarse", EOpDPdyCoarse); symbolTable.relateToOperator("fwidthCoarse",EOpFwidthCoarse); } -#endif + symbolTable.relateToOperator("coopMatLoadNV", EOpCooperativeMatrixLoad); + symbolTable.relateToOperator("coopMatStoreNV", EOpCooperativeMatrixStore); + symbolTable.relateToOperator("coopMatMulAddNV", EOpCooperativeMatrixMulAdd); break; -#ifdef NV_EXTENSIONS - case EShLangRayGenNV: - case EShLangClosestHitNV: - case EShLangMissNV: + case EShLangRayGen: + case EShLangClosestHit: + case EShLangMiss: if (profile != EEsProfile && version >= 460) { symbolTable.relateToOperator("traceNV", EOpTraceNV); + symbolTable.relateToOperator("traceRayMotionNV", EOpTraceRayMotionNV); + symbolTable.relateToOperator("traceRayEXT", EOpTraceKHR); symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV); + symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR); } break; - case EShLangIntersectNV: - if (profile != EEsProfile && version >= 460) - symbolTable.relateToOperator("reportIntersectionNV", EOpReportIntersectionNV); + case EShLangIntersect: + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("reportIntersectionNV", EOpReportIntersection); + symbolTable.relateToOperator("reportIntersectionEXT", EOpReportIntersection); + } break; - case EShLangAnyHitNV: + case EShLangAnyHit: if (profile != EEsProfile && version >= 460) { symbolTable.relateToOperator("ignoreIntersectionNV", EOpIgnoreIntersectionNV); symbolTable.relateToOperator("terminateRayNV", EOpTerminateRayNV); } break; - case EShLangCallableNV: + case EShLangCallable: if (profile != EEsProfile && version >= 460) { symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV); + symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR); } break; case EShLangMeshNV: @@ -9497,13 +9751,14 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); + symbolTable.relateToOperator("subgroupMemoryBarrierShared", EOpSubgroupMemoryBarrierShared); } break; -#endif default: assert(false && "Language not supported"); } +#endif // !GLSLANG_WEB } // @@ -9517,6 +9772,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion // void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) { +#ifndef GLSLANG_WEB +#if defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; +#endif if (profile != EEsProfile && version >= 430 && version < 440) { symbolTable.setVariableExtensions("gl_MaxTransformFeedbackBuffers", 1, &E_GL_ARB_enhanced_layouts); symbolTable.setVariableExtensions("gl_MaxTransformFeedbackInterleavedComponents", 1, &E_GL_ARB_enhanced_layouts); @@ -9540,6 +9800,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable); } + + // GL_EXT_blend_func_extended + if (profile == EEsProfile && version >= 100) { + symbolTable.setVariableExtensions("gl_MaxDualSourceDrawBuffersEXT", 1, &E_GL_EXT_blend_func_extended); + symbolTable.setVariableExtensions("gl_SecondaryFragColorEXT", 1, &E_GL_EXT_blend_func_extended); + symbolTable.setVariableExtensions("gl_SecondaryFragDataEXT", 1, &E_GL_EXT_blend_func_extended); + SpecialQualifier("gl_SecondaryFragColorEXT", EvqVaryingOut, EbvSecondaryFragColorEXT, symbolTable); + SpecialQualifier("gl_SecondaryFragDataEXT", EvqVaryingOut, EbvSecondaryFragDataEXT, symbolTable); + } + break; case EShLangTessControl: @@ -9562,6 +9832,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable); BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); + symbolTable.setVariableExtensions("gl_in", "gl_SecondaryPositionNV", 1, &E_GL_NV_stereo_view_rendering); + symbolTable.setVariableExtensions("gl_in", "gl_PositionPerViewNV", 1, &E_GL_NVX_multiview_per_view_attributes); + + BuiltInVariable("gl_in", "gl_SecondaryPositionNV", EbvSecondaryPositionNV, symbolTable); + BuiltInVariable("gl_in", "gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); + // extension requirements if (profile == EEsProfile) { symbolTable.setVariableExtensions("gl_in", "gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size); @@ -9572,6 +9848,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion default: break; } +#endif } } // end namespace glslang diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Initialize.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Initialize.h index b5de324..ac8ec33 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Initialize.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Initialize.h @@ -91,6 +91,8 @@ public: void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources); protected: + void addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion); + void relateTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage, TSymbolTable&); void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion); void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile); void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile); diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/IntermTraverse.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/IntermTraverse.cpp index f46010b..553b1b5 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/IntermTraverse.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/IntermTraverse.cpp @@ -71,6 +71,13 @@ void TIntermConstantUnion::traverse(TIntermTraverser *it) it->visitConstantUnion(this); } +const TString& TIntermSymbol::getAccessName() const { + if (getBasicType() == EbtBlock) + return getType().getTypeName(); + else + return getName(); +} + // // Traverse a binary node. // diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Intermediate.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Intermediate.cpp index 32b38a0..0278445 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Intermediate.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Intermediate.cpp @@ -1,7 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2015 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // Copyright (C) 2017 ARM Limited. // // All rights reserved. @@ -65,7 +65,7 @@ namespace glslang { // Returns the added node. // -TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray, +TIntermSymbol* TIntermediate::addSymbol(long long id, const TString& name, const TType& type, const TConstUnionArray& constArray, TIntermTyped* constSubtree, const TSourceLoc& loc) { TIntermSymbol* node = new TIntermSymbol(id, name, type); @@ -113,14 +113,71 @@ TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc // // Returns nullptr if the working conversions and promotions could not be found. // -TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) +TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc) { // No operations work on blocks if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) return nullptr; + // Convert "reference +/- int" and "reference - reference" to integer math + if (op == EOpAdd || op == EOpSub) { + + // No addressing math on struct with unsized array. + if ((left->isReference() && left->getType().getReferentType()->containsUnsizedArray()) || + (right->isReference() && right->getType().getReferentType()->containsUnsizedArray())) { + return nullptr; + } + + if (left->isReference() && isTypeInt(right->getBasicType())) { + const TType& referenceType = left->getType(); + TIntermConstantUnion* size = addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(left->getType()), loc, true); + left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64)); + + right = createConversion(EbtInt64, right); + right = addBinaryMath(EOpMul, right, size, loc); + + TIntermTyped *node = addBinaryMath(op, left, right, loc); + node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType); + return node; + } + } + + if (op == EOpAdd && right->isReference() && isTypeInt(left->getBasicType())) { + const TType& referenceType = right->getType(); + TIntermConstantUnion* size = + addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true); + right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64)); + + left = createConversion(EbtInt64, left); + left = addBinaryMath(EOpMul, left, size, loc); + + TIntermTyped *node = addBinaryMath(op, left, right, loc); + node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType); + return node; + } + + if (op == EOpSub && left->isReference() && right->isReference()) { + TIntermConstantUnion* size = + addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true); + + left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64)); + right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64)); + + left = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, left, TType(EbtInt64)); + right = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, right, TType(EbtInt64)); + + left = addBinaryMath(EOpSub, left, right, loc); + + TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc); + return node; + } + + // No other math operators supported on references + if (left->isReference() || right->isReference()) + return nullptr; + // Try converting the children's base types to compatible types. - auto children = addConversion(op, left, right); + auto children = addPairConversion(op, left, right); left = std::get<0>(children); right = std::get<1>(children); @@ -160,7 +217,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn node->getWritableType().getQualifier().makeSpecConstant(); // If must propagate nonuniform, make a nonuniform. - if ((node->getLeft()->getQualifier().nonUniform || node->getRight()->getQualifier().nonUniform) && + if ((node->getLeft()->getQualifier().isNonUniform() || node->getRight()->getQualifier().isNonUniform()) && isNonuniformPropagating(node->getOp())) node->getWritableType().getQualifier().nonUniform = true; @@ -170,13 +227,12 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn // // Low level: add binary node (no promotions or other argument modifications) // -TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) const +TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, + const TSourceLoc& loc) const { // build the node TIntermBinary* node = new TIntermBinary(op); - if (loc.line == 0) - loc = left->getLoc(); - node->setLoc(loc); + node->setLoc(loc.line != 0 ? loc : left->getLoc()); node->setLeft(left); node->setRight(right); @@ -186,7 +242,8 @@ TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TI // // like non-type form, but sets node's type. // -TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc, const TType& type) const +TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, + const TSourceLoc& loc, const TType& type) const { TIntermBinary* node = addBinaryNode(op, left, right, loc); node->setType(type); @@ -196,12 +253,10 @@ TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TI // // Low level: add unary node (no promotions or other argument modifications) // -TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc) const +TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc& loc) const { TIntermUnary* node = new TIntermUnary(op); - if (loc.line == 0) - loc = child->getLoc(); - node->setLoc(loc); + node->setLoc(loc.line != 0 ? loc : child->getLoc()); node->setOperand(child); return node; @@ -210,7 +265,8 @@ TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSo // // like non-type form, but sets node's type. // -TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc, const TType& type) const +TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc& loc, const TType& type) + const { TIntermUnary* node = addUnaryNode(op, child, loc); node->setType(type); @@ -225,12 +281,31 @@ TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSo // Returns nullptr if the 'right' type could not be converted to match the 'left' type, // or the resulting operation cannot be properly promoted. // -TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) +TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, + const TSourceLoc& loc) { // No block assignment if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) return nullptr; + // Convert "reference += int" to "reference = reference + int". We need this because the + // "reference + int" calculation involves a cast back to the original type, which makes it + // not an lvalue. + if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference()) { + if (!(right->getType().isScalar() && right->getType().isIntegerDomain())) + return nullptr; + + TIntermTyped* node = addBinaryMath(op == EOpAddAssign ? EOpAdd : EOpSub, left, right, loc); + if (!node) + return nullptr; + + TIntermSymbol* symbol = left->getAsSymbolNode(); + left = addSymbol(*symbol); + + node = addAssign(EOpAssign, left, node, loc); + return node; + } + // // Like adding binary math, except the conversion can only go // from right to left. @@ -262,7 +337,8 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm // Returns the added node. // The caller should set the type of the returned node. // -TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc) +TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, + const TSourceLoc& loc) { // caller should set the type return addBinaryNode(op, base, index, loc); @@ -273,7 +349,8 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT // // Returns the added node. // -TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc) +TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, + const TSourceLoc& loc) { if (child == 0) return nullptr; @@ -283,7 +360,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo switch (op) { case EOpLogicalNot: - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { break; // HLSL can promote logical not } @@ -307,18 +384,20 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo // TBasicType newType = EbtVoid; switch (op) { - case EOpConstructInt8: newType = EbtInt8; break; - case EOpConstructUint8: newType = EbtUint8; break; - case EOpConstructInt16: newType = EbtInt16; break; - case EOpConstructUint16: newType = EbtUint16; break; - case EOpConstructInt: newType = EbtInt; break; - case EOpConstructUint: newType = EbtUint; break; - case EOpConstructInt64: newType = EbtInt64; break; - case EOpConstructUint64: newType = EbtUint64; break; case EOpConstructBool: newType = EbtBool; break; case EOpConstructFloat: newType = EbtFloat; break; + case EOpConstructInt: newType = EbtInt; break; + case EOpConstructUint: newType = EbtUint; break; +#ifndef GLSLANG_WEB + case EOpConstructInt8: newType = EbtInt8; break; + case EOpConstructUint8: newType = EbtUint8; break; + case EOpConstructInt16: newType = EbtInt16; break; + case EOpConstructUint16: newType = EbtUint16; break; + case EOpConstructInt64: newType = EbtInt64; break; + case EOpConstructUint64: newType = EbtUint64; break; case EOpConstructDouble: newType = EbtDouble; break; case EOpConstructFloat16: newType = EbtFloat16; break; +#endif default: break; // some compilers want this } @@ -373,7 +452,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo node->getWritableType().getQualifier().makeSpecConstant(); // If must propagate nonuniform, make a nonuniform. - if (node->getOperand()->getQualifier().nonUniform && isNonuniformPropagating(node->getOp())) + if (node->getOperand()->getQualifier().isNonUniform() && isNonuniformPropagating(node->getOp())) node->getWritableType().getQualifier().nonUniform = true; return node; @@ -410,14 +489,15 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOper // // This is the safe way to change the operator on an aggregate, as it // does lots of error checking and fixing. Especially for establishing -// a function call's operation on it's set of parameters. Sequences +// a function call's operation on its set of parameters. Sequences // of instructions are also aggregates, but they just directly set // their operator to EOpSequence. // // Returns an aggregate node, which could be the one passed in if // it was already an aggregate. // -TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc) +TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, + const TSourceLoc& loc) { TIntermAggregate* aggNode; @@ -432,8 +512,6 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o // aggNode = new TIntermAggregate(); aggNode->getSequence().push_back(node); - if (loc.line == 0) - loc = node->getLoc(); } } else aggNode = new TIntermAggregate(); @@ -442,8 +520,8 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o // Set the operator. // aggNode->setOperator(op); - if (loc.line != 0) - aggNode->setLoc(loc); + if (loc.line != 0 || node != nullptr) + aggNode->setLoc(loc.line != 0 ? loc : node->getLoc()); aggNode->setType(type); @@ -460,15 +538,13 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const return false; case EbtAtomicUint: case EbtSampler: -#ifdef NV_EXTENSIONS - case EbtAccStructNV: -#endif + case EbtAccStruct: // opaque types can be passed to functions if (op == EOpFunction) break; // HLSL can assign samplers directly (no constructor) - if (source == EShSourceHlsl && node->getBasicType() == EbtSampler) + if (getSource() == EShSourceHlsl && node->getBasicType() == EbtSampler) break; // samplers can get assigned via a sampler constructor @@ -486,55 +562,50 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const return true; } -// This is 'mechanism' here, it does any conversion told. -// It is about basic type, not about shape. -// The policy comes from the shader or the calling code. -TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped* node) const +bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& newOp) const { - // - // Add a new newNode for the conversion. - // - TIntermUnary* newNode = nullptr; - - TOperator newOp = EOpNull; - - switch (convertTo) { + switch (dst) { +#ifndef GLSLANG_WEB case EbtDouble: - switch (node->getBasicType()) { + switch (src) { + case EbtUint: newOp = EOpConvUintToDouble; break; + case EbtBool: newOp = EOpConvBoolToDouble; break; + case EbtFloat: newOp = EOpConvFloatToDouble; break; + case EbtInt: newOp = EOpConvIntToDouble; break; case EbtInt8: newOp = EOpConvInt8ToDouble; break; case EbtUint8: newOp = EOpConvUint8ToDouble; break; case EbtInt16: newOp = EOpConvInt16ToDouble; break; case EbtUint16: newOp = EOpConvUint16ToDouble; break; - case EbtInt: newOp = EOpConvIntToDouble; break; - case EbtUint: newOp = EOpConvUintToDouble; break; - case EbtBool: newOp = EOpConvBoolToDouble; break; - case EbtFloat: newOp = EOpConvFloatToDouble; break; case EbtFloat16: newOp = EOpConvFloat16ToDouble; break; case EbtInt64: newOp = EOpConvInt64ToDouble; break; case EbtUint64: newOp = EOpConvUint64ToDouble; break; default: - return nullptr; + return false; } break; +#endif case EbtFloat: - switch (node->getBasicType()) { + switch (src) { + case EbtInt: newOp = EOpConvIntToFloat; break; + case EbtUint: newOp = EOpConvUintToFloat; break; + case EbtBool: newOp = EOpConvBoolToFloat; break; +#ifndef GLSLANG_WEB + case EbtDouble: newOp = EOpConvDoubleToFloat; break; case EbtInt8: newOp = EOpConvInt8ToFloat; break; case EbtUint8: newOp = EOpConvUint8ToFloat; break; case EbtInt16: newOp = EOpConvInt16ToFloat; break; case EbtUint16: newOp = EOpConvUint16ToFloat; break; - case EbtInt: newOp = EOpConvIntToFloat; break; - case EbtUint: newOp = EOpConvUintToFloat; break; - case EbtBool: newOp = EOpConvBoolToFloat; break; - case EbtDouble: newOp = EOpConvDoubleToFloat; break; case EbtFloat16: newOp = EOpConvFloat16ToFloat; break; case EbtInt64: newOp = EOpConvInt64ToFloat; break; case EbtUint64: newOp = EOpConvUint64ToFloat; break; +#endif default: - return nullptr; + return false; } break; +#ifndef GLSLANG_WEB case EbtFloat16: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToFloat16; break; case EbtUint8: newOp = EOpConvUint8ToFloat16; break; case EbtInt16: newOp = EOpConvInt16ToFloat16; break; @@ -547,28 +618,32 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtInt64: newOp = EOpConvInt64ToFloat16; break; case EbtUint64: newOp = EOpConvUint64ToFloat16; break; default: - return nullptr; + return false; } break; +#endif case EbtBool: - switch (node->getBasicType()) { + switch (src) { + case EbtInt: newOp = EOpConvIntToBool; break; + case EbtUint: newOp = EOpConvUintToBool; break; + case EbtFloat: newOp = EOpConvFloatToBool; break; +#ifndef GLSLANG_WEB + case EbtDouble: newOp = EOpConvDoubleToBool; break; case EbtInt8: newOp = EOpConvInt8ToBool; break; case EbtUint8: newOp = EOpConvUint8ToBool; break; case EbtInt16: newOp = EOpConvInt16ToBool; break; case EbtUint16: newOp = EOpConvUint16ToBool; break; - case EbtInt: newOp = EOpConvIntToBool; break; - case EbtUint: newOp = EOpConvUintToBool; break; - case EbtFloat: newOp = EOpConvFloatToBool; break; - case EbtDouble: newOp = EOpConvDoubleToBool; break; case EbtFloat16: newOp = EOpConvFloat16ToBool; break; case EbtInt64: newOp = EOpConvInt64ToBool; break; case EbtUint64: newOp = EOpConvUint64ToBool; break; +#endif default: - return nullptr; + return false; } break; +#ifndef GLSLANG_WEB case EbtInt8: - switch (node->getBasicType()) { + switch (src) { case EbtUint8: newOp = EOpConvUint8ToInt8; break; case EbtInt16: newOp = EOpConvInt16ToInt8; break; case EbtUint16: newOp = EOpConvUint16ToInt8; break; @@ -581,11 +656,11 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtDouble: newOp = EOpConvDoubleToInt8; break; case EbtFloat16: newOp = EOpConvFloat16ToInt8; break; default: - return nullptr; + return false; } break; case EbtUint8: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToUint8; break; case EbtInt16: newOp = EOpConvInt16ToUint8; break; case EbtUint16: newOp = EOpConvUint16ToUint8; break; @@ -598,12 +673,12 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtDouble: newOp = EOpConvDoubleToUint8; break; case EbtFloat16: newOp = EOpConvFloat16ToUint8; break; default: - return nullptr; + return false; } break; case EbtInt16: - switch (node->getBasicType()) { + switch (src) { case EbtUint8: newOp = EOpConvUint8ToInt16; break; case EbtInt8: newOp = EOpConvInt8ToInt16; break; case EbtUint16: newOp = EOpConvUint16ToInt16; break; @@ -616,11 +691,11 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtDouble: newOp = EOpConvDoubleToInt16; break; case EbtFloat16: newOp = EOpConvFloat16ToInt16; break; default: - return nullptr; + return false; } break; case EbtUint16: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToUint16; break; case EbtUint8: newOp = EOpConvUint8ToUint16; break; case EbtInt16: newOp = EOpConvInt16ToUint16; break; @@ -633,46 +708,52 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtDouble: newOp = EOpConvDoubleToUint16; break; case EbtFloat16: newOp = EOpConvFloat16ToUint16; break; default: - return nullptr; + return false; } break; +#endif case EbtInt: - switch (node->getBasicType()) { + switch (src) { + case EbtUint: newOp = EOpConvUintToInt; break; + case EbtBool: newOp = EOpConvBoolToInt; break; + case EbtFloat: newOp = EOpConvFloatToInt; break; +#ifndef GLSLANG_WEB case EbtInt8: newOp = EOpConvInt8ToInt; break; case EbtUint8: newOp = EOpConvUint8ToInt; break; case EbtInt16: newOp = EOpConvInt16ToInt; break; case EbtUint16: newOp = EOpConvUint16ToInt; break; - case EbtUint: newOp = EOpConvUintToInt; break; - case EbtBool: newOp = EOpConvBoolToInt; break; - case EbtFloat: newOp = EOpConvFloatToInt; break; case EbtDouble: newOp = EOpConvDoubleToInt; break; case EbtFloat16: newOp = EOpConvFloat16ToInt; break; case EbtInt64: newOp = EOpConvInt64ToInt; break; case EbtUint64: newOp = EOpConvUint64ToInt; break; +#endif default: - return nullptr; + return false; } break; case EbtUint: - switch (node->getBasicType()) { + switch (src) { + case EbtInt: newOp = EOpConvIntToUint; break; + case EbtBool: newOp = EOpConvBoolToUint; break; + case EbtFloat: newOp = EOpConvFloatToUint; break; +#ifndef GLSLANG_WEB case EbtInt8: newOp = EOpConvInt8ToUint; break; case EbtUint8: newOp = EOpConvUint8ToUint; break; case EbtInt16: newOp = EOpConvInt16ToUint; break; case EbtUint16: newOp = EOpConvUint16ToUint; break; - case EbtInt: newOp = EOpConvIntToUint; break; - case EbtBool: newOp = EOpConvBoolToUint; break; - case EbtFloat: newOp = EOpConvFloatToUint; break; case EbtDouble: newOp = EOpConvDoubleToUint; break; case EbtFloat16: newOp = EOpConvFloat16ToUint; break; case EbtInt64: newOp = EOpConvInt64ToUint; break; case EbtUint64: newOp = EOpConvUint64ToUint; break; +#endif default: - return nullptr; + return false; } break; +#ifndef GLSLANG_WEB case EbtInt64: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToInt64; break; case EbtUint8: newOp = EOpConvUint8ToInt64; break; case EbtInt16: newOp = EOpConvInt16ToInt64; break; @@ -685,11 +766,11 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtFloat16: newOp = EOpConvFloat16ToInt64; break; case EbtUint64: newOp = EOpConvUint64ToInt64; break; default: - return nullptr; + return false; } break; case EbtUint64: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToUint64; break; case EbtUint8: newOp = EOpConvUint8ToUint64; break; case EbtInt16: newOp = EOpConvInt16ToUint64; break; @@ -702,10 +783,67 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtFloat16: newOp = EOpConvFloat16ToUint64; break; case EbtInt64: newOp = EOpConvInt64ToUint64; break; default: - return nullptr; + return false; } break; +#endif default: + return false; + } + return true; +} + +// This is 'mechanism' here, it does any conversion told. +// It is about basic type, not about shape. +// The policy comes from the shader or the calling code. +TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped* node) const +{ + // + // Add a new newNode for the conversion. + // + +#ifndef GLSLANG_WEB + bool convertToIntTypes = (convertTo == EbtInt8 || convertTo == EbtUint8 || + convertTo == EbtInt16 || convertTo == EbtUint16 || + convertTo == EbtInt || convertTo == EbtUint || + convertTo == EbtInt64 || convertTo == EbtUint64); + + bool convertFromIntTypes = (node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8 || + node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16 || + node->getBasicType() == EbtInt || node->getBasicType() == EbtUint || + node->getBasicType() == EbtInt64 || node->getBasicType() == EbtUint64); + + bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtFloat || convertTo == EbtDouble); + + bool convertFromFloatTypes = (node->getBasicType() == EbtFloat16 || + node->getBasicType() == EbtFloat || + node->getBasicType() == EbtDouble); + + if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes)) { + if (! getArithemeticInt8Enabled()) { + return nullptr; + } + } + + if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes)) { + if (! getArithemeticInt16Enabled()) { + return nullptr; + } + } + + if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) || + (node->getBasicType() == EbtFloat16 && ! convertToFloatTypes)) { + if (! getArithemeticFloat16Enabled()) { + return nullptr; + } + } +#endif + + TIntermUnary* newNode = nullptr; + TOperator newOp = EOpNull; + if (!buildConvertOp(convertTo, node->getBasicType(), newOp)) { return nullptr; } @@ -713,9 +851,18 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped newNode = addUnaryNode(newOp, node, node->getLoc(), newType); if (node->getAsConstantUnion()) { - TIntermTyped* folded = node->getAsConstantUnion()->fold(newOp, newType); - if (folded) - return folded; +#ifndef GLSLANG_WEB + // 8/16-bit storage extensions don't support 8/16-bit constants, so don't fold conversions + // to those types + if ((getArithemeticInt8Enabled() || !(convertTo == EbtInt8 || convertTo == EbtUint8)) && + (getArithemeticInt16Enabled() || !(convertTo == EbtInt16 || convertTo == EbtUint16)) && + (getArithemeticFloat16Enabled() || !(convertTo == EbtFloat16))) +#endif + { + TIntermTyped* folded = node->getAsConstantUnion()->fold(newOp, newType); + if (folded) + return folded; + } } // Propagate specialization-constant-ness, if allowed @@ -725,6 +872,11 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped return newNode; } +TIntermTyped* TIntermediate::addConversion(TBasicType convertTo, TIntermTyped* node) const +{ + return createConversion(convertTo, node); +} + // For converting a pair of operands to a binary operation to compatible // types with each other, relative to the operation in 'op'. // This does not cover assignment operations, which is asymmetric in that the @@ -738,7 +890,7 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped // Returns the converted pair of nodes. // Returns when there is no conversion. std::tuple -TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) const +TIntermediate::addPairConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) { if (!isConversionAllowed(op, node0) || !isConversionAllowed(op, node1)) return std::make_tuple(nullptr, nullptr); @@ -751,6 +903,10 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no // If differing arrays, then no conversions. if (node0->getType().isArray() || node1->getType().isArray()) return std::make_tuple(nullptr, nullptr); + + // No implicit conversions for operations involving cooperative matrices + if (node0->getType().isCoopMat() || node1->getType().isCoopMat()) + return std::make_tuple(node0, node1); } auto promoteTo = std::make_tuple(EbtNumTypes, EbtNumTypes); @@ -787,7 +943,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no if (node0->getBasicType() == node1->getBasicType()) return std::make_tuple(node0, node1); - promoteTo = getConversionDestinatonType(node0->getBasicType(), node1->getBasicType(), op); + promoteTo = getConversionDestinationType(node0->getBasicType(), node1->getBasicType(), op); if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes) return std::make_tuple(nullptr, nullptr); @@ -796,7 +952,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no case EOpLogicalAnd: case EOpLogicalOr: case EOpLogicalXor: - if (source == EShSourceHlsl) + if (getSource() == EShSourceHlsl) promoteTo = std::make_tuple(EbtBool, EbtBool); else return std::make_tuple(node0, node1); @@ -807,7 +963,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no // HLSL can promote bools to ints to make this work. case EOpLeftShift: case EOpRightShift: - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { TBasicType node0BasicType = node0->getBasicType(); if (node0BasicType == EbtBool) node0BasicType = EbtInt; @@ -867,7 +1023,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no // // Return nullptr if a conversion can't be done. // -TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const +TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) { if (!isConversionAllowed(op, node)) return nullptr; @@ -887,62 +1043,30 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt // Note: callers are responsible for other aspects of shape, // like vector and matrix sizes. - TBasicType promoteTo; - // GL_EXT_shader_16bit_storage can't do OpConstantComposite with - // 16-bit types, so disable promotion for those types. - bool canPromoteConstant = true; - switch (op) { // // Explicit conversions (unary operations) // case EOpConstructBool: - promoteTo = EbtBool; - break; case EOpConstructFloat: - promoteTo = EbtFloat; - break; - case EOpConstructDouble: - promoteTo = EbtDouble; - break; - case EOpConstructFloat16: - promoteTo = EbtFloat16; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16); - break; - case EOpConstructInt8: - promoteTo = EbtInt8; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); - break; - case EOpConstructUint8: - promoteTo = EbtUint8; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); - break; - case EOpConstructInt16: - promoteTo = EbtInt16; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); - break; - case EOpConstructUint16: - promoteTo = EbtUint16; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); - break; case EOpConstructInt: - promoteTo = EbtInt; - break; case EOpConstructUint: - promoteTo = EbtUint; - break; +#ifndef GLSLANG_WEB + case EOpConstructDouble: + case EOpConstructFloat16: + case EOpConstructInt8: + case EOpConstructUint8: + case EOpConstructInt16: + case EOpConstructUint16: case EOpConstructInt64: - promoteTo = EbtInt64; - break; case EOpConstructUint64: - promoteTo = EbtUint64; break; +#endif + + // + // Implicit conversions + // case EOpLogicalNot: case EOpFunctionCall: @@ -974,6 +1098,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpLit: case EOpMax: case EOpMin: + case EOpMod: case EOpModf: case EOpPow: case EOpReflect: @@ -983,8 +1108,9 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpSequence: case EOpConstructStruct: + case EOpConstructCooperativeMatrix: - if (type.getBasicType() == EbtReference || node->getType().getBasicType() == EbtReference) { + if (type.isReference() || node->getType().isReference()) { // types must match to assign a reference if (type == node->getType()) return node; @@ -995,10 +1121,8 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt if (type.getBasicType() == node->getType().getBasicType()) return node; - if (canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op)) - promoteTo = type.getBasicType(); - else - return nullptr; + if (! canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op)) + return nullptr; break; // For GLSL, there are no conversions needed; the shift amount just needs to be an @@ -1007,9 +1131,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpLeftShiftAssign: case EOpRightShiftAssign: { - if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) - promoteTo = type.getBasicType(); - else { + if (!(getSource() == EShSourceHlsl && node->getType().getBasicType() == EbtBool)) { if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType())) return node; else @@ -1027,13 +1149,44 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt return nullptr; } + bool canPromoteConstant = true; +#ifndef GLSLANG_WEB + // GL_EXT_shader_16bit_storage can't do OpConstantComposite with + // 16-bit types, so disable promotion for those types. + // Many issues with this, from JohnK: + // - this isn't really right to discuss SPIR-V here + // - this could easily be entirely about scalars, so is overstepping + // - we should be looking at what the shader asked for, and saying whether or + // not it can be done, in the parser, by calling requireExtensions(), not + // changing language sementics on the fly by asking what extensions are in use + // - at the time of this writing (14-Aug-2020), no test results are changed by this. + switch (op) { + case EOpConstructFloat16: + canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16); + break; + case EOpConstructInt8: + case EOpConstructUint8: + canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8); + break; + case EOpConstructInt16: + case EOpConstructUint16: + canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16); + break; + default: + break; + } +#endif + if (canPromoteConstant && node->getAsConstantUnion()) - return promoteConstantUnion(promoteTo, node->getAsConstantUnion()); + return promoteConstantUnion(type.getBasicType(), node->getAsConstantUnion()); // // Add a new newNode for the conversion. // - TIntermTyped* newNode = createConversion(promoteTo, node); + TIntermTyped* newNode = createConversion(type.getBasicType(), node); return newNode; } @@ -1053,7 +1206,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node) { // some source languages don't do this - switch (source) { + switch (getSource()) { case EShSourceHlsl: break; case EShSourceGlsl: @@ -1106,7 +1259,7 @@ TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& ty void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode) { // some source languages don't do this - switch (source) { + switch (getSource()) { case EShSourceHlsl: break; case EShSourceGlsl: @@ -1209,7 +1362,7 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* // The new node that handles the conversion TOperator constructorOp = mapTypeToConstructorOp(type); - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { // HLSL rules for scalar, vector and matrix conversions: // 1) scalar can become anything, initializing every component with its value // 2) vector and matrix can become scalar, first element is used (warning: truncation) @@ -1322,7 +1475,31 @@ bool TIntermediate::isFPPromotion(TBasicType from, TBasicType to) const bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const { +#ifdef GLSLANG_WEB + return false; +#endif + switch (from) { + case EbtInt: + switch(to) { + case EbtUint: + return version >= 400 || getSource() == EShSourceHlsl; + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; + case EbtUint: + switch(to) { + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; case EbtInt8: switch (to) { case EbtUint8: @@ -1369,26 +1546,6 @@ bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const break; } break; - case EbtInt: - switch(to) { - case EbtUint: - return version >= 400 || (source == EShSourceHlsl); - case EbtInt64: - case EbtUint64: - return true; - default: - break; - } - break; - case EbtUint: - switch(to) { - case EbtInt64: - case EbtUint64: - return true; - default: - break; - } - break; case EbtInt64: if (to == EbtUint64) { return true; @@ -1402,6 +1559,10 @@ bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const { +#ifdef GLSLANG_WEB + return false; +#endif + if (to == EbtFloat && from == EbtFloat16) { return true; } else { @@ -1412,6 +1573,17 @@ bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const { switch (from) { + case EbtInt: + case EbtUint: + switch(to) { + case EbtFloat: + case EbtDouble: + return true; + default: + break; + } + break; +#ifndef GLSLANG_WEB case EbtInt8: case EbtUint8: case EbtInt16: @@ -1425,23 +1597,13 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const break; } break; - case EbtInt: - case EbtUint: - switch(to) { - case EbtFloat: - case EbtDouble: - return true; - default: - break; - } - break; case EbtInt64: case EbtUint64: if (to == EbtDouble) { return true; } break; - +#endif default: break; } @@ -1454,7 +1616,7 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const // bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const { - if (profile == EEsProfile || version == 110) + if ((isEsProfile() && version < 310 ) || version == 110) return false; if (from == to) @@ -1462,7 +1624,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat // TODO: Move more policies into language-specific handlers. // Some languages allow more general (or potentially, more specific) conversions under some conditions. - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { const bool fromConvertable = (from == EbtFloat || from == EbtDouble || from == EbtInt || from == EbtUint || from == EbtBool); const bool toConvertable = (to == EbtFloat || to == EbtDouble || to == EbtInt || to == EbtUint || to == EbtBool); @@ -1493,46 +1655,51 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat } } - bool explicitTypesEnabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int32) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int64) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float32) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float64); - - if (explicitTypesEnabled) { - // integral promotions - if (isIntegralPromotion(from, to)) { + if (getSource() == EShSourceHlsl) { + // HLSL + if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat)) return true; - } + } else { + // GLSL + if (isIntegralPromotion(from, to) || + isFPPromotion(from, to) || + isIntegralConversion(from, to) || + isFPConversion(from, to) || + isFPIntegralConversion(from, to)) { - // floating-point promotions - if (isFPPromotion(from, to)) { - return true; - } - - // integral conversions - if (isIntegralConversion(from, to)) { - return true; - } - - // floating-point conversions - if (isFPConversion(from, to)) { - return true; - } - - // floating-integral conversions - if (isFPIntegralConversion(from, to)) { - return true; - } - - // hlsl supported conversions - if (source == EShSourceHlsl) { - if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat)) + if (numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int32) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int64) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float32) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float64)) { return true; + } } + } + + if (isEsProfile()) { + switch (to) { + case EbtFloat: + switch (from) { + case EbtInt: + case EbtUint: + return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions); + default: + return false; + } + case EbtUint: + switch (from) { + case EbtInt: + return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions); + default: + return false; + } + default: + return false; + } } else { switch (to) { case EbtDouble: @@ -1542,15 +1709,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtInt64: case EbtUint64: case EbtFloat: - case EbtDouble: - return true; -#ifdef AMD_EXTENSIONS + return version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64); case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); + return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) && + numericFeatures.contains(TNumericFeatures::gpu_shader_int16); case EbtFloat16: - return extensionRequested(E_GL_AMD_gpu_shader_half_float); -#endif + return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) && + numericFeatures.contains(TNumericFeatures::gpu_shader_half_float); default: return false; } @@ -1558,50 +1724,36 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat switch (from) { case EbtInt: case EbtUint: - case EbtFloat: return true; case EbtBool: - return (source == EShSourceHlsl); -#ifdef AMD_EXTENSIONS + return getSource() == EShSourceHlsl; case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); -#endif + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); case EbtFloat16: - return -#ifdef AMD_EXTENSIONS - extensionRequested(E_GL_AMD_gpu_shader_half_float) || -#endif - (source == EShSourceHlsl); + return numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) || + getSource() == EShSourceHlsl; default: return false; } case EbtUint: switch (from) { case EbtInt: - return version >= 400 || (source == EShSourceHlsl); - case EbtUint: - return true; + return version >= 400 || getSource() == EShSourceHlsl || IsRequestedExtension(E_GL_ARB_gpu_shader5); case EbtBool: - return (source == EShSourceHlsl); -#ifdef AMD_EXTENSIONS + return getSource() == EShSourceHlsl; case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); -#endif + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: return false; } case EbtInt: switch (from) { - case EbtInt: - return true; case EbtBool: - return (source == EShSourceHlsl); -#ifdef AMD_EXTENSIONS + return getSource() == EShSourceHlsl; case EbtInt16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); -#endif + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: return false; } @@ -1610,51 +1762,38 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtInt: case EbtUint: case EbtInt64: - case EbtUint64: return true; -#ifdef AMD_EXTENSIONS case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); -#endif + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: return false; } case EbtInt64: switch (from) { case EbtInt: - case EbtInt64: return true; -#ifdef AMD_EXTENSIONS case EbtInt16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); -#endif + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: return false; } case EbtFloat16: -#ifdef AMD_EXTENSIONS switch (from) { case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); - case EbtFloat16: - return extensionRequested(E_GL_AMD_gpu_shader_half_float); + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: break; } -#endif return false; case EbtUint16: -#ifdef AMD_EXTENSIONS switch (from) { case EbtInt16: - case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: break; } -#endif return false; default: return false; @@ -1664,7 +1803,12 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat return false; } -static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBasicType uintType) { +static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBasicType uintType) +{ +#ifdef GLSLANG_WEB + return false; +#endif + switch(sintType) { case EbtInt8: switch(uintType) { @@ -1723,7 +1867,13 @@ static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBas } -static TBasicType getCorrespondingUnsignedType(TBasicType type) { +static TBasicType getCorrespondingUnsignedType(TBasicType type) +{ +#ifdef GLSLANG_WEB + assert(type == EbtInt); + return EbtUint; +#endif + switch(type) { case EbtInt8: return EbtUint8; @@ -1767,15 +1917,17 @@ static TBasicType getCorrespondingUnsignedType(TBasicType type) { // integer type corresponding to the type of the operand with signed // integer type. -std::tuple TIntermediate::getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const +std::tuple TIntermediate::getConversionDestinationType(TBasicType type0, TBasicType type1, TOperator op) const { TBasicType res0 = EbtNumTypes; TBasicType res1 = EbtNumTypes; - if (profile == EEsProfile || version == 110) - return std::make_tuple(res0, res1);; + if ((isEsProfile() && + (version < 310 || !numericFeatures.contains(TNumericFeatures::shader_implicit_conversions))) || + version == 110) + return std::make_tuple(res0, res1); - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { if (canImplicitlyPromote(type1, type0, op)) { res0 = type0; res1 = type0; @@ -1844,15 +1996,18 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const { TOperator op = EOpNull; - if (type.getQualifier().nonUniform) + if (type.getQualifier().isNonUniform()) return EOpConstructNonuniform; + if (type.isCoopMat()) + return EOpConstructCooperativeMatrix; + switch (type.getBasicType()) { case EbtStruct: op = EOpConstructStruct; break; case EbtSampler: - if (type.getSampler().combined) + if (type.getSampler().isCombined()) op = EOpConstructTextureSampler; break; case EbtFloat: @@ -1894,6 +2049,121 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const } } break; + case EbtInt: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructIMat2x2; break; + case 3: op = EOpConstructIMat2x3; break; + case 4: op = EOpConstructIMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructIMat3x2; break; + case 3: op = EOpConstructIMat3x3; break; + case 4: op = EOpConstructIMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructIMat4x2; break; + case 3: op = EOpConstructIMat4x3; break; + case 4: op = EOpConstructIMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructInt; break; + case 2: op = EOpConstructIVec2; break; + case 3: op = EOpConstructIVec3; break; + case 4: op = EOpConstructIVec4; break; + default: break; // some compilers want this + } + } + break; + case EbtUint: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructUMat2x2; break; + case 3: op = EOpConstructUMat2x3; break; + case 4: op = EOpConstructUMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructUMat3x2; break; + case 3: op = EOpConstructUMat3x3; break; + case 4: op = EOpConstructUMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructUMat4x2; break; + case 3: op = EOpConstructUMat4x3; break; + case 4: op = EOpConstructUMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructUint; break; + case 2: op = EOpConstructUVec2; break; + case 3: op = EOpConstructUVec3; break; + case 4: op = EOpConstructUVec4; break; + default: break; // some compilers want this + } + } + break; + case EbtBool: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructBMat2x2; break; + case 3: op = EOpConstructBMat2x3; break; + case 4: op = EOpConstructBMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructBMat3x2; break; + case 3: op = EOpConstructBMat3x3; break; + case 4: op = EOpConstructBMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructBMat4x2; break; + case 3: op = EOpConstructBMat4x3; break; + case 4: op = EOpConstructBMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructBool; break; + case 2: op = EOpConstructBVec2; break; + case 3: op = EOpConstructBVec3; break; + case 4: op = EOpConstructBVec4; break; + default: break; // some compilers want this + } + } + break; +#ifndef GLSLANG_WEB case EbtDouble: if (type.getMatrixCols()) { switch (type.getMatrixCols()) { @@ -2007,82 +2277,6 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const default: break; // some compilers want this } break; - case EbtInt: - if (type.getMatrixCols()) { - switch (type.getMatrixCols()) { - case 2: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructIMat2x2; break; - case 3: op = EOpConstructIMat2x3; break; - case 4: op = EOpConstructIMat2x4; break; - default: break; // some compilers want this - } - break; - case 3: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructIMat3x2; break; - case 3: op = EOpConstructIMat3x3; break; - case 4: op = EOpConstructIMat3x4; break; - default: break; // some compilers want this - } - break; - case 4: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructIMat4x2; break; - case 3: op = EOpConstructIMat4x3; break; - case 4: op = EOpConstructIMat4x4; break; - default: break; // some compilers want this - } - break; - } - } else { - switch(type.getVectorSize()) { - case 1: op = EOpConstructInt; break; - case 2: op = EOpConstructIVec2; break; - case 3: op = EOpConstructIVec3; break; - case 4: op = EOpConstructIVec4; break; - default: break; // some compilers want this - } - } - break; - case EbtUint: - if (type.getMatrixCols()) { - switch (type.getMatrixCols()) { - case 2: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructUMat2x2; break; - case 3: op = EOpConstructUMat2x3; break; - case 4: op = EOpConstructUMat2x4; break; - default: break; // some compilers want this - } - break; - case 3: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructUMat3x2; break; - case 3: op = EOpConstructUMat3x3; break; - case 4: op = EOpConstructUMat3x4; break; - default: break; // some compilers want this - } - break; - case 4: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructUMat4x2; break; - case 3: op = EOpConstructUMat4x3; break; - case 4: op = EOpConstructUMat4x4; break; - default: break; // some compilers want this - } - break; - } - } else { - switch(type.getVectorSize()) { - case 1: op = EOpConstructUint; break; - case 2: op = EOpConstructUVec2; break; - case 3: op = EOpConstructUVec3; break; - case 4: op = EOpConstructUVec4; break; - default: break; // some compilers want this - } - } - break; case EbtInt64: switch(type.getVectorSize()) { case 1: op = EOpConstructInt64; break; @@ -2101,47 +2295,14 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const default: break; // some compilers want this } break; - case EbtBool: - if (type.getMatrixCols()) { - switch (type.getMatrixCols()) { - case 2: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructBMat2x2; break; - case 3: op = EOpConstructBMat2x3; break; - case 4: op = EOpConstructBMat2x4; break; - default: break; // some compilers want this - } - break; - case 3: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructBMat3x2; break; - case 3: op = EOpConstructBMat3x3; break; - case 4: op = EOpConstructBMat3x4; break; - default: break; // some compilers want this - } - break; - case 4: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructBMat4x2; break; - case 3: op = EOpConstructBMat4x3; break; - case 4: op = EOpConstructBMat4x4; break; - default: break; // some compilers want this - } - break; - } - } else { - switch(type.getVectorSize()) { - case 1: op = EOpConstructBool; break; - case 2: op = EOpConstructBVec2; break; - case 3: op = EOpConstructBVec3; break; - case 4: op = EOpConstructBVec4; break; - default: break; // some compilers want this - } - } - break; case EbtReference: op = EOpConstructReference; break; + + case EbtAccStruct: + op = EOpConstructAccStruct; + break; +#endif default: break; } @@ -2299,7 +2460,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true // // Get compatible types. // - auto children = addConversion(EOpSequence, trueBlock, falseBlock); + auto children = addPairConversion(EOpSequence, trueBlock, falseBlock); trueBlock = std::get<0>(children); falseBlock = std::get<1>(children); @@ -2515,7 +2676,11 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors& selecto // 'swizzleOkay' says whether or not it is okay to consider a swizzle // a valid part of the dereference chain. // -const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay) +// 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node. +// +// + +const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk) { do { const TIntermBinary* binary = node->getAsBinaryNode(); @@ -2533,6 +2698,8 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool return nullptr; } node = node->getAsBinaryNode()->getLeft(); + if (bufferReferenceOk && node->isReference()) + return node; } while (true); } @@ -2586,6 +2753,22 @@ TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expres return node; } +// Propagate precision from formal function return type to actual return type, +// and on to its subtree. +void TIntermBranch::updatePrecision(TPrecisionQualifier parentPrecision) +{ + TIntermTyped* exp = getExpression(); + if (exp == nullptr) + return; + + if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint || + exp->getBasicType() == EbtFloat || exp->getBasicType() == EbtFloat16) { + if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) { + exp->propagatePrecision(parentPrecision); + } + } +} + // // This is to be executed after the final root is put on top by the parsing // process. @@ -2600,6 +2783,7 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) if (aggRoot && aggRoot->getOp() == EOpNull) aggRoot->setOperator(EOpSequence); +#ifndef GLSLANG_WEB // Propagate 'noContraction' label in backward from 'precise' variables. glslang::PropagateNoContraction(*this); @@ -2609,7 +2793,11 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) case EShTexSampTransUpgradeTextureRemoveSampler: performTextureUpgradeAndSamplerRemovalTransformation(root); break; + case EShTexSampTransCount: + assert(0); + break; } +#endif return true; } @@ -2688,7 +2876,7 @@ void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& calle return; } - callGraph.push_front(TCall(caller, callee)); + callGraph.emplace_front(caller, callee); } // @@ -3068,10 +3256,17 @@ bool TIntermediate::promoteUnary(TIntermUnary& node) return false; break; - default: - if (operand->getBasicType() != EbtFloat) + // HLSL uses this path for initial function signature finding for built-ins + // taking a single argument, which generally don't participate in + // operator-based type promotion (type conversion will occur later). + // For now, scalar argument cases are relying on the setType() call below. + if (getSource() == EShSourceHlsl) + break; + // GLSL only allows integer arguments for the cases identified above in the + // case statements. + if (operand->getBasicType() != EbtFloat) return false; } @@ -3081,9 +3276,11 @@ bool TIntermediate::promoteUnary(TIntermUnary& node) return true; } +// Propagate precision qualifiers *up* from children to parent. void TIntermUnary::updatePrecision() { - if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { + if (getBasicType() == EbtInt || getBasicType() == EbtUint || + getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { if (operand->getQualifier().precision > getQualifier().precision) getQualifier().precision = operand->getQualifier().precision; } @@ -3319,6 +3516,40 @@ bool TIntermediate::promoteBinary(TIntermBinary& node) break; } + if (left->getType().isCoopMat() || right->getType().isCoopMat()) { + if (left->getType().isCoopMat() && right->getType().isCoopMat() && + *left->getType().getTypeParameters() != *right->getType().getTypeParameters()) { + return false; + } + switch (op) { + case EOpMul: + case EOpMulAssign: + if (left->getType().isCoopMat() && right->getType().isCoopMat()) { + return false; + } + if (op == EOpMulAssign && right->getType().isCoopMat()) { + return false; + } + node.setOp(op == EOpMulAssign ? EOpMatrixTimesScalarAssign : EOpMatrixTimesScalar); + if (right->getType().isCoopMat()) { + node.setType(right->getType()); + } + return true; + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpAssign: + // These require both to be cooperative matrices + if (!left->getType().isCoopMat() || !right->getType().isCoopMat()) { + return false; + } + return true; + default: + break; + } + return false; + } + // Finish handling the case, for all ops, where both operands are scalars. if (left->isScalar() && right->isScalar()) return true; @@ -3545,20 +3776,33 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node) return false; } +// Propagate precision qualifiers *up* from children to parent, and then +// back *down* again to the children's subtrees. void TIntermBinary::updatePrecision() { - if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { - getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision); - if (getQualifier().precision != EpqNone) { - left->propagatePrecision(getQualifier().precision); - right->propagatePrecision(getQualifier().precision); - } + if (getBasicType() == EbtInt || getBasicType() == EbtUint || + getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { + if (op == EOpRightShift || op == EOpLeftShift) { + // For shifts get precision from left side only and thus no need to propagate + getQualifier().precision = left->getQualifier().precision; + } else { + getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision); + if (getQualifier().precision != EpqNone) { + left->propagatePrecision(getQualifier().precision); + right->propagatePrecision(getQualifier().precision); + } + } } } +// Recursively propagate precision qualifiers *down* the subtree of the current node, +// until reaching a node that already has a precision qualifier or otherwise does +// not participate in precision propagation. void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision) { - if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat && getBasicType() != EbtFloat16)) + if (getQualifier().precision != EpqNone || + (getBasicType() != EbtInt && getBasicType() != EbtUint && + getBasicType() != EbtFloat && getBasicType() != EbtFloat16)) return; getQualifier().precision = newPrecision; @@ -3613,217 +3857,54 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC TConstUnionArray leftUnionArray(size); for (int i=0; i < size; i++) { - switch (promoteTo) { - case EbtFloat: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i] = rightUnionArray[i]; - break; - default: - return node; - } - break; - case EbtDouble: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i] = rightUnionArray[i]; - break; - default: - return node; - } - break; - case EbtFloat16: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i] = rightUnionArray[i]; - break; - default: - return node; - } - break; - case EbtInt: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtUint: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getDConst())); - break; - default: - return node; - } - break; - case EbtUint: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtInt64: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getDConst())); - break; - default: - return node; - } - break; - case EbtBool: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0); - break; - case EbtUint: - leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0); - break; - case EbtInt64: - leftUnionArray[i].setBConst(rightUnionArray[i].getI64Const() != 0); - break; - case EbtUint64: - leftUnionArray[i].setBConst(rightUnionArray[i].getU64Const() != 0); - break; - case EbtBool: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0); - break; - default: - return node; - } - break; - case EbtInt64: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtUint64: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getDConst())); - break; - default: - return node; - } - break; - case EbtUint64: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtBool: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getDConst())); - break; - default: - return node; - } - break; - default: - return node; + +#define PROMOTE(Set, CType, Get) leftUnionArray[i].Set(static_cast(rightUnionArray[i].Get())) +#define PROMOTE_TO_BOOL(Get) leftUnionArray[i].setBConst(rightUnionArray[i].Get() != 0) + +#ifdef GLSLANG_WEB +#define TO_ALL(Get) \ + switch (promoteTo) { \ + case EbtFloat: PROMOTE(setDConst, double, Get); break; \ + case EbtInt: PROMOTE(setIConst, int, Get); break; \ + case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \ + case EbtBool: PROMOTE_TO_BOOL(Get); break; \ + default: return node; \ + } +#else +#define TO_ALL(Get) \ + switch (promoteTo) { \ + case EbtFloat16: PROMOTE(setDConst, double, Get); break; \ + case EbtFloat: PROMOTE(setDConst, double, Get); break; \ + case EbtDouble: PROMOTE(setDConst, double, Get); break; \ + case EbtInt8: PROMOTE(setI8Const, char, Get); break; \ + case EbtInt16: PROMOTE(setI16Const, short, Get); break; \ + case EbtInt: PROMOTE(setIConst, int, Get); break; \ + case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \ + case EbtUint8: PROMOTE(setU8Const, unsigned char, Get); break; \ + case EbtUint16: PROMOTE(setU16Const, unsigned short, Get); break; \ + case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \ + case EbtUint64: PROMOTE(setU64Const, unsigned long long, Get); break; \ + case EbtBool: PROMOTE_TO_BOOL(Get); break; \ + default: return node; \ + } +#endif + + switch (node->getType().getBasicType()) { + case EbtFloat: TO_ALL(getDConst); break; + case EbtInt: TO_ALL(getIConst); break; + case EbtUint: TO_ALL(getUConst); break; + case EbtBool: TO_ALL(getBConst); break; +#ifndef GLSLANG_WEB + case EbtFloat16: TO_ALL(getDConst); break; + case EbtDouble: TO_ALL(getDConst); break; + case EbtInt8: TO_ALL(getI8Const); break; + case EbtInt16: TO_ALL(getI16Const); break; + case EbtInt64: TO_ALL(getI64Const); break; + case EbtUint8: TO_ALL(getU8Const); break; + case EbtUint16: TO_ALL(getU16Const); break; + case EbtUint64: TO_ALL(getU64Const); break; +#endif + default: return node; } } @@ -3852,7 +3933,7 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser { void visitSymbol(TIntermSymbol* symbol) override { if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) { - symbol->getWritableType().getSampler().combined = true; + symbol->getWritableType().getSampler().setCombined(true); } } bool visitAggregate(TVisit, TIntermAggregate* ag) override { diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/LiveTraverser.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/LiveTraverser.h index 7333bc9..9b39b59 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/LiveTraverser.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/LiveTraverser.h @@ -74,14 +74,33 @@ public: for (unsigned int f = 0; f < globals.size(); ++f) { TIntermAggregate* candidate = globals[f]->getAsAggregate(); if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) { - functions.push_back(candidate); + destinations.push_back(candidate); break; } } } - typedef std::list TFunctionStack; - TFunctionStack functions; + void pushGlobalReference(const TString& name) + { + TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence(); + for (unsigned int f = 0; f < globals.size(); ++f) { + TIntermAggregate* candidate = globals[f]->getAsAggregate(); + if (candidate && candidate->getOp() == EOpSequence && + candidate->getSequence().size() == 1 && + candidate->getSequence()[0]->getAsBinaryNode()) { + TIntermBinary* binary = candidate->getSequence()[0]->getAsBinaryNode(); + TIntermSymbol* symbol = binary->getLeft()->getAsSymbolNode(); + if (symbol && symbol->getQualifier().storage == EvqGlobal && + symbol->getName() == name) { + destinations.push_back(candidate); + break; + } + } + } + } + + typedef std::list TDestinationStack; + TDestinationStack destinations; protected: // To catch which function calls are not dead, and hence which functions must be visited. @@ -117,16 +136,27 @@ protected: // and only visit each function once. void addFunctionCall(TIntermAggregate* call) { - // // just use the map to ensure we process each function at most once + // just use the map to ensure we process each function at most once if (liveFunctions.find(call->getName()) == liveFunctions.end()) { liveFunctions.insert(call->getName()); pushFunction(call->getName()); } } + void addGlobalReference(const TString& name) + { + // just use the map to ensure we process each global at most once + if (liveGlobals.find(name) == liveGlobals.end()) { + liveGlobals.insert(name); + pushGlobalReference(name); + } + } + const TIntermediate& intermediate; typedef std::unordered_set TLiveFunctions; TLiveFunctions liveFunctions; + typedef std::unordered_set TLiveGlobals; + TLiveGlobals liveGlobals; bool traverseAll; private: diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseContextBase.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseContextBase.cpp index 7a968ce..02cca40 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseContextBase.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseContextBase.cpp @@ -67,6 +67,8 @@ void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReaso } } +#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL) + void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...) { @@ -113,6 +115,8 @@ void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReaso va_end(args); } +#endif + // // Both test and if necessary, spit out an error, to see if the node is really // an l-value that can be operated on this way. @@ -123,22 +127,6 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, { TIntermBinary* binaryNode = node->getAsBinaryNode(); - if (binaryNode) { - switch(binaryNode->getOp()) { - case EOpIndexDirect: - case EOpIndexIndirect: // fall through - case EOpIndexDirectStruct: // fall through - case EOpVectorSwizzle: - case EOpMatrixSwizzle: - return lValueErrorCheck(loc, op, binaryNode->getLeft()); - default: - break; - } - error(loc, " l-value required", op, "", ""); - - return true; - } - const char* symbol = nullptr; TIntermSymbol* symNode = node->getAsSymbolNode(); if (symNode != nullptr) @@ -149,13 +137,15 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, case EvqConst: message = "can't modify a const"; break; case EvqConstReadOnly: message = "can't modify a const"; break; case EvqUniform: message = "can't modify a uniform"; break; +#ifndef GLSLANG_WEB case EvqBuffer: - if (node->getQualifier().readonly) + if (node->getQualifier().isReadOnly()) message = "can't modify a readonly buffer"; + if (node->getQualifier().isShaderRecord()) + message = "can't modify a shaderrecordnv qualified buffer"; break; -#ifdef NV_EXTENSIONS - case EvqHitAttrNV: - if (language != EShLangIntersectNV) + case EvqHitAttr: + if (language != EShLangIntersect) message = "cannot modify hitAttributeNV in this stage"; break; #endif @@ -168,16 +158,19 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, case EbtSampler: message = "can't modify a sampler"; break; - case EbtAtomicUint: - message = "can't modify an atomic_uint"; - break; case EbtVoid: message = "can't modify void"; break; -#ifdef NV_EXTENSIONS - case EbtAccStructNV: +#ifndef GLSLANG_WEB + case EbtAtomicUint: + message = "can't modify an atomic_uint"; + break; + case EbtAccStruct: message = "can't modify accelerationStructureNV"; break; + case EbtRayQuery: + message = "can't modify rayQueryEXT"; + break; #endif default: break; @@ -194,15 +187,40 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, // Everything else is okay, no error. // if (message == nullptr) + { + if (binaryNode) { + switch (binaryNode->getOp()) { + case EOpIndexDirect: + case EOpIndexIndirect: // fall through + case EOpIndexDirectStruct: // fall through + case EOpVectorSwizzle: + case EOpMatrixSwizzle: + return lValueErrorCheck(loc, op, binaryNode->getLeft()); + default: + break; + } + error(loc, " l-value required", op, "", ""); + + return true; + } return false; + } // // If we get here, we have an error and a message. // + const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true); + if (symNode) error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message); else - error(loc, " l-value required", op, "(%s)", message); + if (binaryNode && binaryNode->getAsOperator()->getOp() == EOpIndexDirectStruct) + if(IsAnonymous(leftMostTypeNode->getAsSymbolNode()->getName())) + error(loc, " l-value required", op, "\"%s\" (%s)", leftMostTypeNode->getAsSymbolNode()->getAccessName().c_str(), message); + else + error(loc, " l-value required", op, "\"%s\" (%s)", leftMostTypeNode->getAsSymbolNode()->getName().c_str(), message); + else + error(loc, " l-value required", op, "(%s)", message); return true; } @@ -210,28 +228,41 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, // Test for and give an error if the node can't be read from. void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node) { + TIntermBinary* binaryNode = node->getAsBinaryNode(); + const TIntermSymbol* symNode = node->getAsSymbolNode(); + if (! node) return; - TIntermBinary* binaryNode = node->getAsBinaryNode(); - if (binaryNode) { - switch(binaryNode->getOp()) { - case EOpIndexDirect: - case EOpIndexIndirect: - case EOpIndexDirectStruct: - case EOpVectorSwizzle: - case EOpMatrixSwizzle: - rValueErrorCheck(loc, op, binaryNode->getLeft()); - default: - break; + if (node->getQualifier().isWriteOnly()) { + const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true); + + if (symNode != nullptr) + error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str()); + else if (binaryNode && + (binaryNode->getAsOperator()->getOp() == EOpIndexDirectStruct || + binaryNode->getAsOperator()->getOp() == EOpIndexDirect)) + if(IsAnonymous(leftMostTypeNode->getAsSymbolNode()->getName())) + error(loc, "can't read from writeonly object: ", op, leftMostTypeNode->getAsSymbolNode()->getAccessName().c_str()); + else + error(loc, "can't read from writeonly object: ", op, leftMostTypeNode->getAsSymbolNode()->getName().c_str()); + else + error(loc, "can't read from writeonly object: ", op, ""); + + } else { + if (binaryNode) { + switch (binaryNode->getOp()) { + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectStruct: + case EOpVectorSwizzle: + case EOpMatrixSwizzle: + rValueErrorCheck(loc, op, binaryNode->getLeft()); + default: + break; + } } - - return; } - - TIntermSymbol* symNode = node->getAsSymbolNode(); - if (symNode && symNode->getQualifier().writeonly) - error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str()); } // Add 'symbol' to the list of deferred linkage symbols, which @@ -250,11 +281,17 @@ void TParseContextBase::trackLinkage(TSymbol& symbol) // Give an error if not. void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index) { + const auto sizeIsSpecializationExpression = [&type]() { + return type.containsSpecializationSize() && + type.getArraySizes()->getOuterNode() != nullptr && + type.getArraySizes()->getOuterNode()->getAsSymbolNode() == nullptr; }; + if (index < 0) { error(loc, "", "[", "index out of range '%d'", index); index = 0; } else if (type.isArray()) { - if (type.isSizedArray() && index >= type.getOuterArraySize()) { + if (type.isSizedArray() && !sizeIsSpecializationExpression() && + index >= type.getOuterArraySize()) { error(loc, "", "[", "array index out of range '%d'", index); index = type.getOuterArraySize() - 1; } @@ -609,6 +646,67 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem ++firstNewMember; } +void TParseContextBase::growAtomicCounterBlock(int binding, const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) { + // Make the atomic counter block, if not yet made. + const auto &at = atomicCounterBuffers.find(binding); + if (at == atomicCounterBuffers.end()) { + atomicCounterBuffers.insert({binding, (TVariable*)nullptr }); + atomicCounterBlockFirstNewMember.insert({binding, 0}); + } + + TVariable*& atomicCounterBuffer = atomicCounterBuffers[binding]; + int& bufferNewMember = atomicCounterBlockFirstNewMember[binding]; + + if (atomicCounterBuffer == nullptr) { + TQualifier blockQualifier; + blockQualifier.clear(); + blockQualifier.storage = EvqBuffer; + + char charBuffer[512]; + if (binding != TQualifier::layoutBindingEnd) { + snprintf(charBuffer, 512, "%s_%d", getAtomicCounterBlockName(), binding); + } else { + snprintf(charBuffer, 512, "%s_0", getAtomicCounterBlockName()); + } + + TType blockType(new TTypeList, *NewPoolTString(charBuffer), blockQualifier); + setUniformBlockDefaults(blockType); + blockType.getQualifier().layoutPacking = ElpStd430; + atomicCounterBuffer = new TVariable(NewPoolTString(""), blockType, true); + // If we arn't auto mapping bindings then set the block to use the same + // binding as what the atomic was set to use + if (!intermediate.getAutoMapBindings()) { + atomicCounterBuffer->getWritableType().getQualifier().layoutBinding = binding; + } + bufferNewMember = 0; + + atomicCounterBuffer->getWritableType().getQualifier().layoutSet = atomicCounterBlockSet; + } + + // Add the requested member as a member to the global block. + TType* type = new TType; + type->shallowCopy(memberType); + type->setFieldName(memberName); + if (typeList) + type->setStruct(typeList); + TTypeLoc typeLoc = {type, loc}; + atomicCounterBuffer->getType().getWritableStruct()->push_back(typeLoc); + + // Insert into the symbol table. + if (bufferNewMember == 0) { + // This is the first request; we need a normal symbol table insert + if (symbolTable.insert(*atomicCounterBuffer)) + trackLinkage(*atomicCounterBuffer); + else + error(loc, "failed to insert the global constant buffer", "buffer", ""); + } else { + // This is a follow-on request; we need to amend the first insert + symbolTable.amend(*atomicCounterBuffer, bufferNewMember); + } + + ++bufferNewMember; +} + void TParseContextBase::finish() { if (parsingBuiltins) diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseHelper.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseHelper.cpp index 6e38658..b957bb8 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseHelper.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseHelper.cpp @@ -2,7 +2,8 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2015 LunarG, Inc. // Copyright (C) 2015-2018 Google, Inc. -// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2017, 2019 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -56,13 +57,16 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b infoSink, forwardCompatible, messages, entryPoint), inMain(false), blockName(nullptr), - limits(resources.limits), + limits(resources.limits) +#ifndef GLSLANG_WEB + , atomicUintOffsets(nullptr), anyIndexLimits(false) +#endif { // decide whether precision qualifiers should be ignored or respected - if (profile == EEsProfile || spvVersion.vulkan > 0) { + if (isEsProfile() || spvVersion.vulkan > 0) { precisionManager.respectPrecisionQualifiers(); - if (! parsingBuiltins && language == EShLangFragment && profile != EEsProfile && spvVersion.vulkan > 0) + if (! parsingBuiltins && language == EShLangFragment && !isEsProfile() && spvVersion.vulkan > 0) precisionManager.warnAboutDefaults(); } @@ -83,6 +87,11 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b globalInputDefaults.clear(); globalOutputDefaults.clear(); + globalSharedDefaults.clear(); + globalSharedDefaults.layoutMatrix = ElmColumnMajor; + globalSharedDefaults.layoutPacking = ElpStd430; + +#ifndef GLSLANG_WEB // "Shaders in the transform // feedback capturing mode have an initial global default of // layout(xfb_buffer = 0) out;" @@ -94,6 +103,7 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b if (language == EShLangGeometry) globalOutputDefaults.layoutStream = 0; +#endif if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main") infoSink.info.message(EPrefixError, "Source entry point must be \"main\""); @@ -101,7 +111,9 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b TParseContext::~TParseContext() { +#ifndef GLSLANG_WEB delete [] atomicUintOffsets; +#endif } // Set up all default precisions as needed by the current environment. @@ -121,7 +133,7 @@ void TParseContext::setPrecisionDefaults() // replace with real precision defaults for those that have them if (obeyPrecisionQualifiers()) { - if (profile == EEsProfile) { + if (isEsProfile()) { // Most don't have defaults, a few default to lowp. TSampler sampler; sampler.set(EbtFloat, Esd2D); @@ -129,7 +141,7 @@ void TParseContext::setPrecisionDefaults() sampler.set(EbtFloat, EsdCube); defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; sampler.set(EbtFloat, Esd2D); - sampler.external = true; + sampler.setExternal(true); defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; } @@ -138,7 +150,7 @@ void TParseContext::setPrecisionDefaults() // is used to resolve the precision from the supplied arguments/operands instead. // So, we don't actually want to replace EpqNone with a default precision for built-ins. if (! parsingBuiltins) { - if (profile == EEsProfile && language == EShLangFragment) { + if (isEsProfile() && language == EShLangFragment) { defaultPrecision[EbtInt] = EpqMedium; defaultPrecision[EbtUint] = EpqMedium; } else { @@ -147,7 +159,7 @@ void TParseContext::setPrecisionDefaults() defaultPrecision[EbtFloat] = EpqHigh; } - if (profile != EEsProfile) { + if (!isEsProfile()) { // Non-ES profile // All sampler precisions default to highp. for (int type = 0; type < maxSamplerIndex; ++type) @@ -163,7 +175,9 @@ void TParseContext::setPrecisionDefaults() void TParseContext::setLimits(const TBuiltInResource& r) { resources = r; + intermediate.setLimits(r); +#ifndef GLSLANG_WEB anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing || ! limits.generalConstantMatrixVectorIndexing || ! limits.generalSamplerIndexing || @@ -171,7 +185,6 @@ void TParseContext::setLimits(const TBuiltInResource& r) ! limits.generalVariableIndexing || ! limits.generalVaryingIndexing; - intermediate.setLimits(resources); // "Each binding point tracks its own current default offset for // inheritance of subsequent variables using the same binding. The initial state of compilation is that all @@ -179,6 +192,7 @@ void TParseContext::setLimits(const TBuiltInResource& r) atomicUintOffsets = new int[resources.maxAtomicCounterBindings]; for (int b = 0; b < resources.maxAtomicCounterBindings; ++b) atomicUintOffsets[b] = 0; +#endif } // @@ -211,8 +225,121 @@ void TParseContext::parserError(const char* s) error(getCurrentLoc(), "compilation terminated", "", ""); } +void TParseContext::growGlobalUniformBlock(const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) +{ + bool createBlock = globalUniformBlock == nullptr; + + if (createBlock) { + globalUniformBinding = intermediate.getGlobalUniformBinding(); + globalUniformSet = intermediate.getGlobalUniformSet(); + } + + // use base class function to create/expand block + TParseContextBase::growGlobalUniformBlock(loc, memberType, memberName, typeList); + + if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) { + // check for a block storage override + TBlockStorageClass storageOverride = intermediate.getBlockStorageOverride(getGlobalUniformBlockName()); + TQualifier& qualifier = globalUniformBlock->getWritableType().getQualifier(); + qualifier.defaultBlock = true; + + if (storageOverride != EbsNone) { + if (createBlock) { + // Remap block storage + qualifier.setBlockStorage(storageOverride); + + // check that the change didn't create errors + blockQualifierCheck(loc, qualifier, false); + } + + // remap meber storage as well + memberType.getQualifier().setBlockStorage(storageOverride); + } + } +} + +void TParseContext::growAtomicCounterBlock(int binding, const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) +{ + bool createBlock = atomicCounterBuffers.find(binding) == atomicCounterBuffers.end(); + + if (createBlock) { + atomicCounterBlockSet = intermediate.getAtomicCounterBlockSet(); + } + + // use base class function to create/expand block + TParseContextBase::growAtomicCounterBlock(binding, loc, memberType, memberName, typeList); + TQualifier& qualifier = atomicCounterBuffers[binding]->getWritableType().getQualifier(); + qualifier.defaultBlock = true; + + if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) { + // check for a Block storage override + TBlockStorageClass storageOverride = intermediate.getBlockStorageOverride(getAtomicCounterBlockName()); + + if (storageOverride != EbsNone) { + if (createBlock) { + // Remap block storage + + qualifier.setBlockStorage(storageOverride); + + // check that the change didn't create errors + blockQualifierCheck(loc, qualifier, false); + } + + // remap meber storage as well + memberType.getQualifier().setBlockStorage(storageOverride); + } + } +} + +const char* TParseContext::getGlobalUniformBlockName() const +{ + const char* name = intermediate.getGlobalUniformBlockName(); + if (std::string(name) == "") + return "gl_DefaultUniformBlock"; + else + return name; +} +void TParseContext::finalizeGlobalUniformBlockLayout(TVariable&) +{ +} +void TParseContext::setUniformBlockDefaults(TType& block) const +{ + block.getQualifier().layoutPacking = ElpStd140; + block.getQualifier().layoutMatrix = ElmColumnMajor; +} + + +const char* TParseContext::getAtomicCounterBlockName() const +{ + const char* name = intermediate.getAtomicCounterBlockName(); + if (std::string(name) == "") + return "gl_AtomicCounterBlock"; + else + return name; +} +void TParseContext::finalizeAtomicCounterBlockLayout(TVariable&) +{ +} + +void TParseContext::setAtomicCounterBlockDefaults(TType& block) const +{ + block.getQualifier().layoutPacking = ElpStd430; + block.getQualifier().layoutMatrix = ElmRowMajor; +} + +void TParseContext::setInvariant(const TSourceLoc& loc, const char* builtin) { + TSymbol* symbol = symbolTable.find(builtin); + if (symbol && symbol->getType().getQualifier().isPipeOutput()) { + if (intermediate.inIoAccessed(builtin)) + warn(loc, "changing qualification after use", "invariant", builtin); + TSymbol* csymbol = symbolTable.copyUp(symbol); + csymbol->getWritableType().getQualifier().invariant = true; + } +} + void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& tokens) { +#ifndef GLSLANG_WEB if (pragmaCallback) pragmaCallback(loc.line, tokens); @@ -235,7 +362,9 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& else if (tokens[2].compare("off") == 0) contextPragma.optimize = false; else { - error(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", ""); + if(relaxedErrors()) + // If an implementation does not recognize the tokens following #pragma, then it will ignore that pragma. + warn(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", ""); return; } @@ -259,7 +388,9 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& else if (tokens[2].compare("off") == 0) contextPragma.debug = false; else { - error(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", ""); + if(relaxedErrors()) + // If an implementation does not recognize the tokens following #pragma, then it will ignore that pragma. + warn(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", ""); return; } @@ -275,10 +406,42 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& if (tokens.size() != 1) error(loc, "extra tokens", "#pragma", ""); intermediate.setUseVulkanMemoryModel(); + } else if (spvVersion.spv > 0 && tokens[0].compare("use_variable_pointers") == 0) { + if (tokens.size() != 1) + error(loc, "extra tokens", "#pragma", ""); + if (spvVersion.spv < glslang::EShTargetSpv_1_3) + error(loc, "requires SPIR-V 1.3", "#pragma use_variable_pointers", ""); + intermediate.setUseVariablePointers(); } else if (tokens[0].compare("once") == 0) { warn(loc, "not implemented", "#pragma once", ""); - } else if (tokens[0].compare("glslang_binary_double_output") == 0) + } else if (tokens[0].compare("glslang_binary_double_output") == 0) { intermediate.setBinaryDoubleOutput(); + } else if (spvVersion.spv > 0 && tokens[0].compare("STDGL") == 0 && + tokens[1].compare("invariant") == 0 && tokens[3].compare("all") == 0) { + intermediate.setInvariantAll(); + // Set all builtin out variables invariant if declared + setInvariant(loc, "gl_Position"); + setInvariant(loc, "gl_PointSize"); + setInvariant(loc, "gl_ClipDistance"); + setInvariant(loc, "gl_CullDistance"); + setInvariant(loc, "gl_TessLevelOuter"); + setInvariant(loc, "gl_TessLevelInner"); + setInvariant(loc, "gl_PrimitiveID"); + setInvariant(loc, "gl_Layer"); + setInvariant(loc, "gl_ViewportIndex"); + setInvariant(loc, "gl_FragDepth"); + setInvariant(loc, "gl_SampleMask"); + setInvariant(loc, "gl_ClipVertex"); + setInvariant(loc, "gl_FrontColor"); + setInvariant(loc, "gl_BackColor"); + setInvariant(loc, "gl_FrontSecondaryColor"); + setInvariant(loc, "gl_BackSecondaryColor"); + setInvariant(loc, "gl_TexCoord"); + setInvariant(loc, "gl_FogFragCoord"); + setInvariant(loc, "gl_FragColor"); + setInvariant(loc, "gl_FragData"); + } +#endif } // @@ -292,6 +455,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb if (symbol && symbol->getNumExtensions()) requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str()); +#ifndef GLSLANG_WEB if (symbol && symbol->isReadOnly()) { // All shared things containing an unsized array must be copied up // on first use, so that all future references will share its array structure, @@ -301,11 +465,17 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb // If this is a variable or a block, check it and all it contains, but if this // is a member of an anonymous block, check the whole block, as the whole block // will need to be copied up if it contains an unsized array. - if (symbol->getType().containsUnsizedArray() || - (symbol->getAsAnonMember() && - symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray())) - makeEditable(symbol); + // + // This check is being done before the block-name check further down, so guard + // for that too. + if (!symbol->getType().isUnusableName()) { + if (symbol->getType().containsUnsizedArray() || + (symbol->getAsAnonMember() && + symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray())) + makeEditable(symbol); + } } +#endif const TVariable* variable; const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr; @@ -328,8 +498,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb // See if it was a variable. variable = symbol ? symbol->getAsVariable() : nullptr; if (variable) { - if ((variable->getType().getBasicType() == EbtBlock || - variable->getType().getBasicType() == EbtStruct) && variable->getType().getStruct() == nullptr) { + if (variable->getType().isUnusableName()) { error(loc, "cannot be used (maybe an instance name is needed)", string->c_str(), ""); variable = nullptr; } @@ -351,7 +520,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb if (variable->getType().getQualifier().isIo()) intermediate.addIoAccessed(*string); - if (variable->getType().getBasicType() == EbtReference && + if (variable->getType().isReference() && variable->getType().getQualifier().bufferReferenceNeedsVulkanMemoryModel()) { intermediate.setUseVulkanMemoryModel(); } @@ -371,7 +540,8 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn // basic type checks... variableCheck(base); - if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) { + if (! base->isArray() && ! base->isMatrix() && ! base->isVector() && ! base->getType().isCoopMat() && + ! base->isReference()) { if (base->getAsSymbolNode()) error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), ""); else @@ -382,7 +552,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn } if (!base->isArray() && base->isVector()) { - if (base->getType().containsBasicType(EbtFloat16)) + if (base->getType().contains16BitFloat()) requireFloat16Arithmetic(loc, "[", "does not operate on types containing float16"); if (base->getType().contains16BitInt()) requireInt16Arithmetic(loc, "[", "does not operate on types containing (u)int16"); @@ -399,16 +569,35 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn // at least one of base and index is not a front-end constant variable... TIntermTyped* result = nullptr; + +#ifndef GLSLANG_WEB + if (base->isReference() && ! base->isArray()) { + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference indexing"); + if (base->getType().getReferentType()->containsUnsizedArray()) { + error(loc, "cannot index reference to buffer containing an unsized array", "", ""); + result = nullptr; + } else { + result = intermediate.addBinaryMath(EOpAdd, base, index, loc); + if (result != nullptr) + result->setType(base->getType()); + } + if (result == nullptr) { + error(loc, "cannot index buffer reference", "", ""); + result = intermediate.addConstantUnion(0.0, EbtFloat, loc); + } + return result; + } + if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) + handleIoResizeArrayAccess(loc, base); +#endif + if (index->getQualifier().isFrontEndConstant()) checkIndex(loc, base->getType(), indexValue); - if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) - handleIoResizeArrayAccess(loc, base); - if (index->getQualifier().isFrontEndConstant()) { +#ifndef GLSLANG_WEB if (base->getType().isUnsizedArray()) { base->getWritableType().updateImplicitArraySize(indexValue + 1); -#ifdef NV_EXTENSIONS // For 2D per-view builtin arrays, update the inner dimension size in parent type if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) { TIntermBinary* binaryNode = base->getAsBinaryNode(); @@ -419,11 +608,12 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn arraySizes.setDimSize(1, std::max(arraySizes.getDimSize(1), indexValue + 1)); } } -#endif } else +#endif checkIndex(loc, base->getType(), indexValue); result = intermediate.addIndex(EOpIndexDirect, base, index, loc); } else { +#ifndef GLSLANG_WEB if (base->getType().isUnsizedArray()) { // we have a variable index into an unsized array, which is okay, // depending on the situation @@ -435,6 +625,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn } base->getWritableType().setArrayVariablyIndexed(); } +#endif if (base->getBasicType() == EbtBlock) { if (base->getQualifier().storage == EvqBuffer) requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array"); @@ -442,7 +633,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "variable indexing uniform block array"); else { - // input/output blocks either don't exist or can be variable indexed + // input/output blocks either don't exist or can't be variably indexed } } else if (language == EShLangFragment && base->getQualifier().isPipeOutput()) requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array"); @@ -456,8 +647,8 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn result = intermediate.addIndex(EOpIndexIndirect, base, index, loc); } - // Insert valid dereferenced result - TType newType(base->getType(), 0); // dereferenced type + // Insert valid dereferenced result type + TType newType(base->getType(), 0); if (base->getType().getQualifier().isConstant() && index->getQualifier().isConstant()) { newType.getQualifier().storage = EvqConst; // If base or index is a specialization constant, the result should also be a specialization constant. @@ -465,20 +656,27 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn newType.getQualifier().makeSpecConstant(); } } else { - newType.getQualifier().makePartialTemporary(); + newType.getQualifier().storage = EvqTemporary; + newType.getQualifier().specConstant = false; } result->setType(newType); +#ifndef GLSLANG_WEB + inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier()); + // Propagate nonuniform if (base->getQualifier().isNonUniform() || index->getQualifier().isNonUniform()) result->getWritableType().getQualifier().nonUniform = true; if (anyIndexLimits) handleIndexLimits(loc, base, index); +#endif return result; } +#ifndef GLSLANG_WEB + // for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* base, TIntermTyped* index) { @@ -515,14 +713,12 @@ bool TParseContext::isIoResizeArray(const TType& type) const { return type.isArray() && ((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) || - (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch) -#ifdef NV_EXTENSIONS - || - (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn && type.getQualifier().pervertexNV) || - (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut && !type.getQualifier().perTaskNV) - -#endif - ); + (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && + ! type.getQualifier().patch) || + (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn && + type.getQualifier().pervertexNV) || + (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut && + !type.getQualifier().perTaskNV)); } // If an array is not isIoResizeArray() but is an io array, make sure it has the right size @@ -551,11 +747,7 @@ void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type) void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (! type.isArray() && ! symbolTable.atBuiltInLevel()) { - if (type.getQualifier().isArrayedIo(language) -#ifdef NV_EXTENSIONS - && !type.getQualifier().layoutPassthrough -#endif - ) + if (type.getQualifier().isArrayedIo(language) && !type.getQualifier().layoutPassthrough) error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str()); } } @@ -572,7 +764,7 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing) if (symbolNode->getType().isUnsizedArray()) { - int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier().isPerPrimitive()); + int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier()); if (newSize > 0) symbolNode->getWritableType().changeOuterArraySize(newSize); } @@ -586,59 +778,71 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm // Types without an array size will be given one. // Types already having a size that is wrong will get an error. // -void TParseContext::checkIoArraysConsistency(const TSourceLoc& loc, bool tailOnly, bool isPerPrimitive) +void TParseContext::checkIoArraysConsistency(const TSourceLoc &loc, bool tailOnly) { - int requiredSize = getIoArrayImplicitSize(isPerPrimitive); - if (requiredSize == 0) - return; - - const char* feature; - if (language == EShLangGeometry) - feature = TQualifier::getGeometryString(intermediate.getInputPrimitive()); - else if (language == EShLangTessControl -#ifdef NV_EXTENSIONS - || language == EShLangFragment -#endif - ) - - feature = "vertices"; -#ifdef NV_EXTENSIONS - else if (language == EShLangMeshNV) { - feature = isPerPrimitive ? "max_primitives" : "max_vertices"; - } -#endif - else - feature = "unknown"; + int requiredSize = 0; + TString featureString; + size_t listSize = ioArraySymbolResizeList.size(); + size_t i = 0; + // If tailOnly = true, only check the last array symbol in the list. if (tailOnly) { - checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList.back()->getWritableType(), ioArraySymbolResizeList.back()->getName()); - return; + i = listSize - 1; } + for (bool firstIteration = true; i < listSize; ++i) { + TType &type = ioArraySymbolResizeList[i]->getWritableType(); - for (size_t i = 0; i < ioArraySymbolResizeList.size(); ++i) - checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList[i]->getWritableType(), ioArraySymbolResizeList[i]->getName()); + // As I/O array sizes don't change, fetch requiredSize only once, + // except for mesh shaders which could have different I/O array sizes based on type qualifiers. + if (firstIteration || (language == EShLangMeshNV)) { + requiredSize = getIoArrayImplicitSize(type.getQualifier(), &featureString); + if (requiredSize == 0) + break; + firstIteration = false; + } + + checkIoArrayConsistency(loc, requiredSize, featureString.c_str(), type, + ioArraySymbolResizeList[i]->getName()); + } } -int TParseContext::getIoArrayImplicitSize(bool isPerPrimitive) const +int TParseContext::getIoArrayImplicitSize(const TQualifier &qualifier, TString *featureString) const { - if (language == EShLangGeometry) - return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive()); - else if (language == EShLangTessControl) - return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0; -#ifdef NV_EXTENSIONS - else if (language == EShLangFragment) - return 3; //Number of vertices for Fragment shader is always three. - else if (language == EShLangMeshNV) { - if (isPerPrimitive) { - return intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0; - } else { - return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0; + int expectedSize = 0; + TString str = "unknown"; + unsigned int maxVertices = intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0; + + if (language == EShLangGeometry) { + expectedSize = TQualifier::mapGeometryToSize(intermediate.getInputPrimitive()); + str = TQualifier::getGeometryString(intermediate.getInputPrimitive()); + } + else if (language == EShLangTessControl) { + expectedSize = maxVertices; + str = "vertices"; + } else if (language == EShLangFragment) { + // Number of vertices for Fragment shader is always three. + expectedSize = 3; + str = "vertices"; + } else if (language == EShLangMeshNV) { + unsigned int maxPrimitives = + intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0; + if (qualifier.builtIn == EbvPrimitiveIndicesNV) { + expectedSize = maxPrimitives * TQualifier::mapGeometryToSize(intermediate.getOutputPrimitive()); + str = "max_primitives*"; + str += TQualifier::getGeometryString(intermediate.getOutputPrimitive()); + } + else if (qualifier.isPerPrimitive()) { + expectedSize = maxPrimitives; + str = "max_primitives"; + } + else { + expectedSize = maxVertices; + str = "max_vertices"; } } -#endif - - else - return 0; + if (featureString) + *featureString = str; + return expectedSize; } void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name) @@ -650,19 +854,19 @@ void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredS error(loc, "inconsistent input primitive for array size of", feature, name.c_str()); else if (language == EShLangTessControl) error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str()); -#ifdef NV_EXTENSIONS else if (language == EShLangFragment) { if (type.getOuterArraySize() > requiredSize) error(loc, " cannot be greater than 3 for pervertexNV", feature, name.c_str()); } else if (language == EShLangMeshNV) error(loc, "inconsistent output array size of", feature, name.c_str()); -#endif else assert(0); } } +#endif // GLSLANG_WEB + // Handle seeing a binary node with a math operation. // Returns nullptr if not semantically allowed. TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right) @@ -685,15 +889,18 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* break; } - if (((left->getType().containsBasicType(EbtFloat16) || right->getType().containsBasicType(EbtFloat16)) && !float16Arithmetic()) || + if (((left->getType().contains16BitFloat() || right->getType().contains16BitFloat()) && !float16Arithmetic()) || ((left->getType().contains16BitInt() || right->getType().contains16BitInt()) && !int16Arithmetic()) || ((left->getType().contains8BitInt() || right->getType().contains8BitInt()) && !int8Arithmetic())) { allowed = false; } TIntermTyped* result = nullptr; - if (allowed) + if (allowed) { + if ((left->isReference() || right->isReference())) + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference math"); result = intermediate.addBinaryMath(op, left, right, loc); + } if (result == nullptr) binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString()); @@ -707,14 +914,13 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char* rValueErrorCheck(loc, str, childNode); bool allowed = true; - if ((childNode->getType().containsBasicType(EbtFloat16) && !float16Arithmetic()) || + if ((childNode->getType().contains16BitFloat() && !float16Arithmetic()) || (childNode->getType().contains16BitInt() && !int16Arithmetic()) || (childNode->getType().contains8BitInt() && !int8Arithmetic())) { allowed = false; } TIntermTyped* result = nullptr; - if (allowed) result = intermediate.addUnaryMath(op, childNode, loc); @@ -746,7 +952,7 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm const char* feature = ".length() on vectors and matrices"; requireProfile(loc, ~EEsProfile, feature); profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature); - } else { + } else if (!base->getType().isCoopMat()) { error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str()); return base; @@ -763,62 +969,22 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm return base; } + if (base->getType().isCoopMat()) { + error(loc, "cannot apply to a cooperative matrix type:", ".", field.c_str()); + return base; + } + // It's neither an array nor .length() if we get here, // leaving swizzles and struct/block dereferences. TIntermTyped* result = base; if ((base->isVector() || base->isScalar()) && (base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) { - if (base->isScalar()) { - const char* dotFeature = "scalar swizzle"; - requireProfile(loc, ~EEsProfile, dotFeature); - profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature); - } - - TSwizzleSelectors selectors; - parseSwizzleSelector(loc, field, base->getVectorSize(), selectors); - - if (base->isVector() && selectors.size() != 1 && base->getType().containsBasicType(EbtFloat16)) - requireFloat16Arithmetic(loc, ".", "can't swizzle types containing float16"); - if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt()) - requireInt16Arithmetic(loc, ".", "can't swizzle types containing (u)int16"); - if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt()) - requireInt8Arithmetic(loc, ".", "can't swizzle types containing (u)int8"); - - if (base->isScalar()) { - if (selectors.size() == 1) - return result; - else { - TType type(base->getBasicType(), EvqTemporary, selectors.size()); - // Swizzle operations propagate specialization-constantness - if (base->getQualifier().isSpecConstant()) - type.getQualifier().makeSpecConstant(); - return addConstructor(loc, base, type); - } - } - - if (base->getType().getQualifier().isFrontEndConstant()) - result = intermediate.foldSwizzle(base, selectors, loc); - else { - if (selectors.size() == 1) { - TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc); - result = intermediate.addIndex(EOpIndexDirect, base, index, loc); - result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision)); - } else { - TIntermTyped* index = intermediate.addSwizzle(selectors, loc); - result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc); - result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size())); - } - // Swizzle operations propagate specialization-constantness - if (base->getType().getQualifier().isSpecConstant()) - result->getWritableType().getQualifier().makeSpecConstant(); - } - } else if (base->getBasicType() == EbtStruct || - base->getBasicType() == EbtBlock || - base->getBasicType() == EbtReference) { - const TTypeList* fields = base->getBasicType() == EbtReference ? - base->getType().getReferentType()->getStruct() : - base->getType().getStruct(); + result = handleDotSwizzle(loc, base, field); + } else if (base->isStruct() || base->isReference()) { + const TTypeList* fields = base->isReference() ? + base->getType().getReferentType()->getStruct() : + base->getType().getStruct(); bool fieldFound = false; int member; for (member = 0; member < (int)fields->size(); ++member) { @@ -838,14 +1004,15 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm if ((*fields)[member].type->getQualifier().isIo()) intermediate.addIoAccessed(field); } + inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier()); } else error(loc, "no such field in structure", field.c_str(), ""); } else error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str()); // Propagate noContraction up the dereference chain - if (base->getQualifier().noContraction) - result->getWritableType().getQualifier().noContraction = true; + if (base->getQualifier().isNoContraction()) + result->getWritableType().getQualifier().setNoContraction(); // Propagate nonuniform if (base->getQualifier().isNonUniform()) @@ -854,6 +1021,60 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm return result; } +// +// Handle seeing a base.swizzle, a subset of base.identifier in the grammar. +// +TIntermTyped* TParseContext::handleDotSwizzle(const TSourceLoc& loc, TIntermTyped* base, const TString& field) +{ + TIntermTyped* result = base; + if (base->isScalar()) { + const char* dotFeature = "scalar swizzle"; + requireProfile(loc, ~EEsProfile, dotFeature); + profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature); + } + + TSwizzleSelectors selectors; + parseSwizzleSelector(loc, field, base->getVectorSize(), selectors); + + if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitFloat()) + requireFloat16Arithmetic(loc, ".", "can't swizzle types containing float16"); + if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt()) + requireInt16Arithmetic(loc, ".", "can't swizzle types containing (u)int16"); + if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt()) + requireInt8Arithmetic(loc, ".", "can't swizzle types containing (u)int8"); + + if (base->isScalar()) { + if (selectors.size() == 1) + return result; + else { + TType type(base->getBasicType(), EvqTemporary, selectors.size()); + // Swizzle operations propagate specialization-constantness + if (base->getQualifier().isSpecConstant()) + type.getQualifier().makeSpecConstant(); + return addConstructor(loc, base, type); + } + } + + if (base->getType().getQualifier().isFrontEndConstant()) + result = intermediate.foldSwizzle(base, selectors, loc); + else { + if (selectors.size() == 1) { + TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc); + result = intermediate.addIndex(EOpIndexDirect, base, index, loc); + result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision)); + } else { + TIntermTyped* index = intermediate.addSwizzle(selectors, loc); + result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc); + result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size())); + } + // Swizzle operations propagate specialization-constantness + if (base->getType().getQualifier().isSpecConstant()) + result->getWritableType().getQualifier().makeSpecConstant(); + } + + return result; +} + void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* base, int member, const TString& memberName) { // a block that needs extension checking is either 'base', or if arrayed, @@ -906,12 +1127,31 @@ TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunct TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn); if (symbol && symbol->getAsFunction() && builtIn) requireProfile(loc, ~EEsProfile, "redefinition of built-in function"); +#ifndef GLSLANG_WEB + // Check the validity of using spirv_literal qualifier + for (int i = 0; i < function.getParamCount(); ++i) { + if (function[i].type->getQualifier().isSpirvLiteral() && function.getBuiltInOp() != EOpSpirvInst) + error(loc, "'spirv_literal' can only be used on functions defined with 'spirv_instruction' for argument", + function.getName().c_str(), "%d", i + 1); + } + + // For function declaration with SPIR-V instruction qualifier, always ignore the built-in function and + // respect this redeclared one. + if (symbol && builtIn && function.getBuiltInOp() == EOpSpirvInst) + symbol = nullptr; +#endif const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0; if (prevDec) { if (prevDec->isPrototyped() && prototype) profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function"); if (prevDec->getType() != function.getType()) error(loc, "overloaded functions must have the same return type", function.getName().c_str(), ""); +#ifndef GLSLANG_WEB + if (prevDec->getSpirvInstruction() != function.getSpirvInstruction()) { + error(loc, "overloaded functions must have the same qualifiers", function.getName().c_str(), + "spirv_instruction"); + } +#endif for (int i = 0; i < prevDec->getParamCount(); ++i) { if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage) error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1); @@ -1051,6 +1291,14 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction { TIntermTyped* result = nullptr; + if (spvVersion.vulkan != 0 && spvVersion.vulkanRelaxed) { + // allow calls that are invalid in Vulkan Semantics to be invisibily + // remapped to equivalent valid functions + result = vkRelaxedRemapFunctionCall(loc, function, arguments); + if (result) + return result; + } + if (function->getBuiltInOp() == EOpArrayLength) result = handleLengthMethod(loc, function, arguments); else if (function->getBuiltInOp() != EOpNull) { @@ -1085,7 +1333,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction if (builtIn && fnCandidate->getNumExtensions()) requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str()); - if (builtIn && fnCandidate->getType().containsBasicType(EbtFloat16)) + if (builtIn && fnCandidate->getType().contains16BitFloat()) requireFloat16Arithmetic(loc, "built-in function", "float16 types can only be in uniform block or buffer storage"); if (builtIn && fnCandidate->getType().contains16BitInt()) requireInt16Arithmetic(loc, "built-in function", "(u)int16 types can only be in uniform block or buffer storage"); @@ -1105,9 +1353,20 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped())) error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", ""); } - TQualifier& argQualifier = arg->getAsTyped()->getQualifier(); - if (argQualifier.isMemory()) { +#ifndef GLSLANG_WEB + if (formalQualifier.isSpirvLiteral()) { + if (!arg->getAsTyped()->getQualifier().isFrontEndConstant()) { + error(arguments->getLoc(), + "Non front-end constant expressions cannot be passed for 'spirv_literal' parameters.", + "spirv_literal", ""); + } + } +#endif + const TType& argType = arg->getAsTyped()->getType(); + const TQualifier& argQualifier = argType.getQualifier(); + if (argQualifier.isMemory() && (argType.containsOpaque() || argType.isReference())) { const char* message = "argument cannot drop memory qualifier when passed to formal parameter"; +#ifndef GLSLANG_WEB if (argQualifier.volatil && ! formalQualifier.volatil) error(arguments->getLoc(), message, "volatile", ""); if (argQualifier.coherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent)) @@ -1124,9 +1383,19 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction error(arguments->getLoc(), message, "readonly", ""); if (argQualifier.writeonly && ! formalQualifier.writeonly) error(arguments->getLoc(), message, "writeonly", ""); + // Don't check 'restrict', it is different than the rest: + // "...but only restrict can be taken away from a calling argument, by a formal parameter that + // lacks the restrict qualifier..." +#endif } - - if (builtIn && arg->getAsTyped()->getType().containsBasicType(EbtFloat16)) + if (!builtIn && argQualifier.getFormat() != formalQualifier.getFormat()) { + // we have mismatched formats, which should only be allowed if writeonly + // and at least one format is unknown + if (!formalQualifier.isWriteOnly() || (formalQualifier.getFormat() != ElfNone && + argQualifier.getFormat() != ElfNone)) + error(arguments->getLoc(), "image formats must match", "format", ""); + } + if (builtIn && arg->getAsTyped()->getType().contains16BitFloat()) requireFloat16Arithmetic(arguments->getLoc(), "built-in function", "float16 types can only be in uniform block or buffer storage"); if (builtIn && arg->getAsTyped()->getType().contains16BitInt()) requireInt16Arithmetic(arguments->getLoc(), "built-in function", "(u)int16 types can only be in uniform block or buffer storage"); @@ -1147,6 +1416,11 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) { // A function call mapped to a built-in operation. result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate); +#ifndef GLSLANG_WEB + } else if (fnCandidate->getBuiltInOp() == EOpSpirvInst) { + // When SPIR-V instruction qualifier is specified, the function call is still mapped to a built-in operation. + result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate); +#endif } else { // This is a function call not mapped to built-in operator. // It could still be a built-in function, but only if PureOperatorBuiltins == false. @@ -1166,9 +1440,11 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName()); } +#ifndef GLSLANG_WEB if (builtIn) nonOpBuiltInCheck(loc, *fnCandidate, *call); else +#endif userFunctionCallCheck(loc, *call); } @@ -1183,6 +1459,13 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction } result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate()); } + + if (result->getAsTyped()->getType().isCoopMat() && + !result->getAsTyped()->getType().isParameterized()) { + assert(fnCandidate->getBuiltInOp() == EOpCooperativeMatrixMulAdd); + + result->setType(result->getAsAggregate()->getSequence()[2]->getAsTyped()->getType()); + } } } @@ -1201,7 +1484,7 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(), function.getParamCount() == 1, arguments, function.getType()); - if (obeyPrecisionQualifiers()) + if (result != nullptr && obeyPrecisionQualifiers()) computeBuiltinPrecisions(*result, function); if (result == nullptr) { @@ -1215,6 +1498,35 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo } else if (result->getAsOperator()) builtInOpCheck(loc, function, *result->getAsOperator()); +#ifndef GLSLANG_WEB + // Special handling for function call with SPIR-V instruction qualifier specified + if (function.getBuiltInOp() == EOpSpirvInst) { + if (auto agg = result->getAsAggregate()) { + // Propogate spirv_by_reference/spirv_literal from parameters to arguments + auto& sequence = agg->getSequence(); + for (unsigned i = 0; i < sequence.size(); ++i) { + if (function[i].type->getQualifier().isSpirvByReference()) + sequence[i]->getAsTyped()->getQualifier().setSpirvByReference(); + if (function[i].type->getQualifier().isSpirvLiteral()) + sequence[i]->getAsTyped()->getQualifier().setSpirvLiteral(); + } + + // Attach the function call to SPIR-V intruction + agg->setSpirvInstruction(function.getSpirvInstruction()); + } else if (auto unaryNode = result->getAsUnaryNode()) { + // Propogate spirv_by_reference/spirv_literal from parameters to arguments + if (function[0].type->getQualifier().isSpirvByReference()) + unaryNode->getOperand()->getQualifier().setSpirvByReference(); + if (function[0].type->getQualifier().isSpirvLiteral()) + unaryNode->getOperand()->getQualifier().setSpirvLiteral(); + + // Attach the function call to SPIR-V intruction + unaryNode->setSpirvInstruction(function.getSpirvInstruction()); + } else + assert(0); + } +#endif + return result; } @@ -1281,6 +1593,9 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction case EOpInterpolateAtSample: numArgs = 1; break; + case EOpDebugPrintf: + numArgs = 0; + break; default: break; } @@ -1290,13 +1605,9 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction operationPrecision = std::max(operationPrecision, function[arg].type->getQualifier().precision); } // compute the result precision -#ifdef AMD_EXTENSIONS if (agg->isSampling() || agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore || agg->getOp() == EOpImageLoadLod || agg->getOp() == EOpImageStoreLod) -#else - if (agg->isSampling() || agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore) -#endif resultPrecision = sequence[0]->getAsTyped()->getQualifier().precision; else if (function.getType().getBasicType() != EbtBool) resultPrecision = function.getType().getQualifier().precision == EpqNone ? @@ -1317,31 +1628,39 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value) { +#ifndef GLSLANG_WEB storage16BitAssignmentCheck(loc, value->getType(), "return"); +#endif functionReturnsValue = true; + TIntermBranch* branch = nullptr; if (currentFunctionType->getBasicType() == EbtVoid) { error(loc, "void function cannot return a value", "return", ""); - return intermediate.addBranch(EOpReturn, loc); + branch = intermediate.addBranch(EOpReturn, loc); } else if (*currentFunctionType != value->getType()) { TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value); if (converted) { if (*currentFunctionType != converted->getType()) error(loc, "cannot convert return value to function return type", "return", ""); if (version < 420) - warn(loc, "type conversion on return values was not explicitly allowed until version 420", "return", ""); - return intermediate.addBranch(EOpReturn, converted, loc); + warn(loc, "type conversion on return values was not explicitly allowed until version 420", + "return", ""); + branch = intermediate.addBranch(EOpReturn, converted, loc); } else { error(loc, "type does not match, or is not convertible to, the function's return type", "return", ""); - return intermediate.addBranch(EOpReturn, value, loc); + branch = intermediate.addBranch(EOpReturn, value, loc); } } else - return intermediate.addBranch(EOpReturn, value, loc); + branch = intermediate.addBranch(EOpReturn, value, loc); + + branch->updatePrecision(currentFunctionType->getQualifier().precision); + return branch; } // See if the operation is being done in an illegal location. void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) { +#ifndef GLSLANG_WEB switch (op) { case EOpBarrier: if (language == EShLangTessControl) { @@ -1353,9 +1672,48 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", ""); } break; + case EOpBeginInvocationInterlock: + if (language != EShLangFragment) + error(loc, "beginInvocationInterlockARB() must be in a fragment shader", "", ""); + if (! inMain) + error(loc, "beginInvocationInterlockARB() must be in main()", "", ""); + else if (postEntryPointReturn) + error(loc, "beginInvocationInterlockARB() cannot be placed after a return from main()", "", ""); + if (controlFlowNestingLevel > 0) + error(loc, "beginInvocationInterlockARB() cannot be placed within flow control", "", ""); + + if (beginInvocationInterlockCount > 0) + error(loc, "beginInvocationInterlockARB() must only be called once", "", ""); + if (endInvocationInterlockCount > 0) + error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", ""); + + beginInvocationInterlockCount++; + + // default to pixel_interlock_ordered + if (intermediate.getInterlockOrdering() == EioNone) + intermediate.setInterlockOrdering(EioPixelInterlockOrdered); + break; + case EOpEndInvocationInterlock: + if (language != EShLangFragment) + error(loc, "endInvocationInterlockARB() must be in a fragment shader", "", ""); + if (! inMain) + error(loc, "endInvocationInterlockARB() must be in main()", "", ""); + else if (postEntryPointReturn) + error(loc, "endInvocationInterlockARB() cannot be placed after a return from main()", "", ""); + if (controlFlowNestingLevel > 0) + error(loc, "endInvocationInterlockARB() cannot be placed within flow control", "", ""); + + if (endInvocationInterlockCount > 0) + error(loc, "endInvocationInterlockARB() must only be called once", "", ""); + if (beginInvocationInterlockCount == 0) + error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", ""); + + endInvocationInterlockCount++; + break; default: break; } +#endif } // Finish processing object.length(). This started earlier in handleDotDereference(), where @@ -1373,29 +1731,28 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction const TType& type = intermNode->getAsTyped()->getType(); if (type.isArray()) { if (type.isUnsizedArray()) { +#ifndef GLSLANG_WEB if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) { // We could be between a layout declaration that gives a built-in io array implicit size and // a user redeclaration of that array, meaning we have to substitute its implicit size here // without actually redeclaring the array. (It is an error to use a member before the // redeclaration, but not an error to use the array name itself.) const TString& name = intermNode->getAsSymbolNode()->getName(); - if (name == "gl_in" || name == "gl_out" -#ifdef NV_EXTENSIONS - || name == "gl_MeshVerticesNV" - || name == "gl_MeshPrimitivesNV" -#endif - ) - { - length = getIoArrayImplicitSize(type.getQualifier().isPerPrimitive()); + if (name == "gl_in" || name == "gl_out" || name == "gl_MeshVerticesNV" || + name == "gl_MeshPrimitivesNV") { + length = getIoArrayImplicitSize(type.getQualifier()); } } +#endif if (length == 0) { +#ifndef GLSLANG_WEB if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier"); else if (isRuntimeLength(*intermNode->getAsTyped())) { // Create a unary op and let the back end handle it return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt)); } else +#endif error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method"); } } else if (type.getOuterArrayNode()) { @@ -1409,6 +1766,8 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction length = type.getMatrixCols(); else if (type.isVector()) length = type.getVectorSize(); + else if (type.isCoopMat()) + return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt)); else { // we should not get here, because earlier semantic checking should have prevented this path error(loc, ".length()", "unexpected use of .length()", ""); @@ -1426,6 +1785,7 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction // void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const { +#ifndef GLSLANG_WEB TIntermAggregate* aggregate = arguments->getAsAggregate(); // Process each argument's conversion @@ -1435,7 +1795,8 @@ void TParseContext::addInputArgumentConversions(const TFunction& function, TInte // means take 'arguments' itself as the one argument. TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped()); if (*function[i].type != arg->getType()) { - if (function[i].type->getQualifier().isParamInput()) { + if (function[i].type->getQualifier().isParamInput() && + !function[i].type->isCoopMat()) { // In-qualified arguments just need an extra node added above the argument to // convert to the correct type. arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg); @@ -1452,6 +1813,7 @@ void TParseContext::addInputArgumentConversions(const TFunction& function, TInte } } } +#endif } // @@ -1463,6 +1825,9 @@ void TParseContext::addInputArgumentConversions(const TFunction& function, TInte // TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const { +#ifdef GLSLANG_WEB + return &intermNode; +#else TIntermSequence& arguments = intermNode.getSequence(); // Will there be any output conversions? @@ -1503,7 +1868,14 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct if (function[i].type->getQualifier().isParamOutput()) { // Out-qualified arguments need to use the topology set up above. // do the " ...(tempArg, ...), arg = tempArg" bit from above - TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type); + TType paramType; + paramType.shallowCopy(*function[i].type); + if (arguments[i]->getAsTyped()->getType().isParameterized() && + !paramType.isParameterized()) { + paramType.shallowCopy(arguments[i]->getAsTyped()->getType()); + paramType.copyTypeParameters(*arguments[i]->getAsTyped()->getType().getTypeParameters()); + } + TVariable* tempArg = makeInternalVariable("tempArg", paramType); tempArg->getWritableType().getQualifier().makeTemporary(); TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc()); TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc()); @@ -1523,6 +1895,15 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc()); return conversionTree; +#endif +} + +TIntermTyped* TParseContext::addAssign(const TSourceLoc& loc, TOperator op, TIntermTyped* left, TIntermTyped* right) +{ + if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference()) + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "+= and -= on a buffer reference"); + + return intermediate.addAssign(op, left, right, loc); } void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& fnCandidate, const TIntermOperator& callNode) @@ -1535,6 +1916,7 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& const int gl_SemanticsAcquireRelease = 0x8; const int gl_SemanticsMakeAvailable = 0x2000; const int gl_SemanticsMakeVisible = 0x4000; + const int gl_SemanticsVolatile = 0x8000; //const int gl_StorageSemanticsNone = 0x0; const int gl_StorageSemanticsBuffer = 0x40; @@ -1546,9 +1928,13 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& unsigned int semantics = 0, storageClassSemantics = 0; unsigned int semantics2 = 0, storageClassSemantics2 = 0; + const TIntermTyped* arg0 = (*argp)[0]->getAsTyped(); + const bool isMS = arg0->getBasicType() == EbtSampler && arg0->getType().getSampler().isMultiSample(); + // Grab the semantics and storage class semantics from the operands, based on opcode switch (callNode.getOp()) { case EOpAtomicAdd: + case EOpAtomicSubtract: case EOpAtomicMin: case EOpAtomicMax: case EOpAtomicAnd: @@ -1578,18 +1964,18 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& case EOpImageAtomicXor: case EOpImageAtomicExchange: case EOpImageAtomicStore: - storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst(); - semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst(); break; case EOpImageAtomicLoad: - storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst(); - semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics = (*argp)[isMS ? 4 : 3]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst(); break; case EOpImageAtomicCompSwap: - storageClassSemantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst(); - semantics = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst(); - storageClassSemantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst(); - semantics2 = (*argp)[8]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[isMS ? 7 : 6]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics2 = (*argp)[isMS ? 8 : 7]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics2 = (*argp)[isMS ? 9 : 8]->getAsConstantUnion()->getConstArray()[0].getIConst(); break; case EOpBarrier: @@ -1624,7 +2010,8 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& gl_SemanticsRelease | gl_SemanticsAcquireRelease | gl_SemanticsMakeAvailable | - gl_SemanticsMakeVisible))) { + gl_SemanticsMakeVisible | + gl_SemanticsVolatile))) { error(loc, "Invalid semantics value", fnCandidate.getName().c_str(), ""); } if (((storageClassSemantics | storageClassSemantics2) & ~(gl_StorageSemanticsBuffer | @@ -1676,10 +2063,18 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& error(loc, "gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), ""); } - + if ((semantics & gl_SemanticsVolatile) && + (callNode.getOp() == EOpMemoryBarrier || callNode.getOp() == EOpBarrier)) { + error(loc, "gl_SemanticsVolatile must not be used with memoryBarrier or controlBarrier", + fnCandidate.getName().c_str(), ""); + } + if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) && + ((semantics ^ semantics2) & gl_SemanticsVolatile)) { + error(loc, "semEqual and semUnequal must either both include gl_SemanticsVolatile or neither", + fnCandidate.getName().c_str(), ""); + } } - // // Do additional checking of built-in function calls that is not caught // by normal semantic checks on argument type, extension tagging, etc. @@ -1707,6 +2102,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan TString featureString; const char* feature = nullptr; switch (callNode.getOp()) { +#ifndef GLSLANG_WEB case EOpTextureGather: case EOpTextureGatherOffset: case EOpTextureGatherOffsets: @@ -1763,7 +2159,6 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan error(loc, "must be a compile-time constant:", feature, "component argument"); } -#ifdef AMD_EXTENSIONS bool bias = false; if (callNode.getOp() == EOpTextureGather) bias = fnCandidate.getParamCount() > 3; @@ -1778,12 +2173,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan profileRequires(loc, ~EEsProfile, 450, nullptr, feature); requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature); } -#endif - break; } - -#ifdef AMD_EXTENSIONS case EOpSparseTextureGather: case EOpSparseTextureGatherOffset: case EOpSparseTextureGatherOffsets: @@ -1802,7 +2193,13 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan profileRequires(loc, ~EEsProfile, 450, nullptr, feature); requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature); } - + // As per GL_ARB_sparse_texture2 extension "Offsets" parameter must be constant integral expression + // for sparseTextureGatherOffsetsARB just as textureGatherOffsets + if (callNode.getOp() == EOpSparseTextureGatherOffsets) { + int offsetsArg = arg0->getType().getSampler().shadow ? 3 : 2; + if (!(*argp)[offsetsArg]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "offsets", ""); + } break; } @@ -1861,7 +2258,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan int arg = -1; switch (callNode.getOp()) { case EOpTextureOffset: arg = 2; break; - case EOpTextureFetchOffset: arg = (arg0->getType().getSampler().dim != EsdRect) ? 3 : 2; break; + case EOpTextureFetchOffset: arg = (arg0->getType().getSampler().isRect()) ? 2 : 3; break; case EOpTextureProjOffset: arg = 2; break; case EOpTextureLodOffset: arg = 3; break; case EOpTextureProjLodOffset: arg = 3; break; @@ -1874,19 +2271,31 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan if (arg > 0) { -#ifdef AMD_EXTENSIONS - bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 && arg0->getType().getSampler().shadow; +#ifndef GLSLANG_WEB + bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 && + arg0->getType().getSampler().shadow; if (f16ShadowCompare) ++arg; #endif - if (! (*argp)[arg]->getAsConstantUnion()) + if (! (*argp)[arg]->getAsTyped()->getQualifier().isConstant()) error(loc, "argument must be compile-time constant", "texel offset", ""); - else { + else if ((*argp)[arg]->getAsConstantUnion()) { const TType& type = (*argp)[arg]->getAsTyped()->getType(); for (int c = 0; c < type.getVectorSize(); ++c) { int offset = (*argp)[arg]->getAsConstantUnion()->getConstArray()[c].getIConst(); if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset) - error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]"); + error(loc, "value is out of range:", "texel offset", + "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]"); + } + } + + if (callNode.getOp() == EOpTextureOffset) { + TSampler s = arg0->getType().getSampler(); + if (s.is2D() && s.isArrayed() && s.isShadow()) { + if (isEsProfile()) + error(loc, "TextureOffset does not support sampler2DArrayShadow : ", "sampler", "ES Profile"); + else if (version <= 420) + error(loc, "TextureOffset does not support sampler2DArrayShadow : ", "sampler", "version <= 420"); } } } @@ -1894,16 +2303,54 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan break; } -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB case EOpTraceNV: if (!(*argp)[10]->getAsConstantUnion()) - error(loc, "argument must be compile-time constant", "payload number", ""); + error(loc, "argument must be compile-time constant", "payload number", "a"); + break; + case EOpTraceRayMotionNV: + if (!(*argp)[11]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "payload number", "a"); + break; + case EOpTraceKHR: + if (!(*argp)[10]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "payload number", "a"); + else { + unsigned int location = (*argp)[10]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (intermediate.checkLocationRT(0, location) < 0) + error(loc, "with layout(location =", "no rayPayloadEXT/rayPayloadInEXT declared", "%d)", location); + } break; case EOpExecuteCallableNV: if (!(*argp)[1]->getAsConstantUnion()) error(loc, "argument must be compile-time constant", "callable data number", ""); break; -#endif + case EOpExecuteCallableKHR: + if (!(*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "callable data number", ""); + else { + unsigned int location = (*argp)[1]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (intermediate.checkLocationRT(1, location) < 0) + error(loc, "with layout(location =", "no callableDataEXT/callableDataInEXT declared", "%d)", location); + } + break; + + case EOpRayQueryGetIntersectionType: + case EOpRayQueryGetIntersectionT: + case EOpRayQueryGetIntersectionInstanceCustomIndex: + case EOpRayQueryGetIntersectionInstanceId: + case EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: + case EOpRayQueryGetIntersectionGeometryIndex: + case EOpRayQueryGetIntersectionPrimitiveIndex: + case EOpRayQueryGetIntersectionBarycentrics: + case EOpRayQueryGetIntersectionFrontFace: + case EOpRayQueryGetIntersectionObjectRayDirection: + case EOpRayQueryGetIntersectionObjectRayOrigin: + case EOpRayQueryGetIntersectionObjectToWorld: + case EOpRayQueryGetIntersectionWorldToObject: + if (!(*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "committed", ""); + break; case EOpTextureQuerySamples: case EOpImageQuerySamples: @@ -1924,14 +2371,32 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan { // Make sure the image types have the correct layout() format and correct argument types const TType& imageType = arg0->getType(); - if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) { - if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui) + if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint || + imageType.getSampler().type == EbtInt64 || imageType.getSampler().type == EbtUint64) { + if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui && + imageType.getQualifier().getFormat() != ElfR64i && imageType.getQualifier().getFormat() != ElfR64ui) error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), ""); - } else { - if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0) + if (callNode.getType().getBasicType() == EbtInt64 && imageType.getQualifier().getFormat() != ElfR64i) + error(loc, "only supported on image with format r64i", fnCandidate.getName().c_str(), ""); + else if (callNode.getType().getBasicType() == EbtUint64 && imageType.getQualifier().getFormat() != ElfR64ui) + error(loc, "only supported on image with format r64ui", fnCandidate.getName().c_str(), ""); + } else if (imageType.getSampler().type == EbtFloat) { + if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") == 0) { + // imageAtomicExchange doesn't require an extension + } else if ((fnCandidate.getName().compare(0, 14, "imageAtomicAdd") == 0) || + (fnCandidate.getName().compare(0, 15, "imageAtomicLoad") == 0) || + (fnCandidate.getName().compare(0, 16, "imageAtomicStore") == 0)) { + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str()); + } else if ((fnCandidate.getName().compare(0, 14, "imageAtomicMin") == 0) || + (fnCandidate.getName().compare(0, 14, "imageAtomicMax") == 0)) { + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str()); + } else { error(loc, "only supported on integer images", fnCandidate.getName().c_str(), ""); - else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile) + } + if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile()) error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), ""); + } else { + error(loc, "not supported on this image type", fnCandidate.getName().c_str(), ""); } const size_t maxArgs = imageType.getSampler().isMultiSample() ? 5 : 4; @@ -1944,6 +2409,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } case EOpAtomicAdd: + case EOpAtomicSubtract: case EOpAtomicMin: case EOpAtomicMax: case EOpAtomicAnd: @@ -1957,24 +2423,46 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan if (argp->size() > 3) { requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str()); memorySemanticsCheck(loc, fnCandidate, callNode); + if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange || + callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore) && + (arg0->getType().getBasicType() == EbtFloat || + arg0->getType().getBasicType() == EbtDouble)) { + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str()); + } else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange || + callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore || + callNode.getOp() == EOpAtomicMin || callNode.getOp() == EOpAtomicMax) && + arg0->getType().isFloatingDomain()) { + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str()); + } } else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) { -#ifdef NV_EXTENSIONS const char* const extensions[2] = { E_GL_NV_shader_atomic_int64, E_GL_EXT_shader_atomic_int64 }; requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str()); -#else - requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_int64, fnCandidate.getName().c_str()); -#endif + } else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange) && + (arg0->getType().getBasicType() == EbtFloat || + arg0->getType().getBasicType() == EbtDouble)) { + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str()); + } else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange || + callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore || + callNode.getOp() == EOpAtomicMin || callNode.getOp() == EOpAtomicMax) && + arg0->getType().isFloatingDomain()) { + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str()); } + + const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true); + const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr; + const TQualifier& qualifier = (refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier(); + if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer) + error(loc,"Atomic memory function can only be used for shader storage block member or shared variable.", + fnCandidate.getName().c_str(), ""); + break; } case EOpInterpolateAtCentroid: case EOpInterpolateAtSample: case EOpInterpolateAtOffset: -#ifdef AMD_EXTENSIONS case EOpInterpolateAtVertex: -#endif // Make sure the first argument is an interpolant, or an array element of an interpolant if (arg0->getType().getQualifier().storage != EvqVaryingIn) { // It might still be an array element. @@ -1984,13 +2472,12 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan // // ES and desktop 4.3 and earlier: swizzles may not be used // desktop 4.4 and later: swizzles may be used - bool swizzleOkay = (profile != EEsProfile) && (version >= 440); + bool swizzleOkay = (!isEsProfile()) && (version >= 440); const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay); if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn) error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), ""); } -#ifdef AMD_EXTENSIONS if (callNode.getOp() == EOpInterpolateAtVertex) { if (!arg0->getType().getQualifier().isExplicitInterpolation()) error(loc, "argument must be qualified as __explicitInterpAMD in", "interpolant", ""); @@ -2004,8 +2491,6 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } } } -#endif - break; case EOpEmitStreamVertex: @@ -2036,9 +2521,12 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan break; case EOpSubgroupBroadcast: - // must be an integral constant expression. - if ((*argp)[1]->getAsConstantUnion() == nullptr) - error(loc, "argument must be compile-time constant", "id", ""); + case EOpSubgroupQuadBroadcast: + if (spvVersion.spv < EShTargetSpv_1_5) { + // must be an integral constant expression. + if ((*argp)[1]->getAsConstantUnion() == nullptr) + error(loc, "argument must be compile-time constant", "id", ""); + } break; case EOpBarrier: @@ -2049,6 +2537,29 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } break; + case EOpMix: + if (profile == EEsProfile && version < 310) { + // Look for specific signatures + if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat && + (*argp)[1]->getAsTyped()->getBasicType() != EbtFloat && + (*argp)[2]->getAsTyped()->getBasicType() == EbtBool) { + requireExtensions(loc, 1, &E_GL_EXT_shader_integer_mix, "specific signature of builtin mix"); + } + } + + if (profile != EEsProfile && version < 450) { + if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat && + (*argp)[0]->getAsTyped()->getBasicType() != EbtDouble && + (*argp)[1]->getAsTyped()->getBasicType() != EbtFloat && + (*argp)[1]->getAsTyped()->getBasicType() != EbtDouble && + (*argp)[2]->getAsTyped()->getBasicType() == EbtBool) { + requireExtensions(loc, 1, &E_GL_EXT_shader_integer_mix, fnCandidate.getName().c_str()); + } + } + + break; +#endif + default: break; } @@ -2065,7 +2576,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan const TSampler& sampler = fnCandidate[0].type->getSampler(); const bool isTexture = sampler.isTexture() && !sampler.isCombined(); - const bool isBuffer = sampler.dim == EsdBuffer; + const bool isBuffer = sampler.isBuffer(); const bool isFetch = callNode.getOp() == EOpTextureFetch || callNode.getOp() == EOpTextureFetchOffset; if (isTexture && (!isBuffer || !isFetch)) @@ -2078,13 +2589,39 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan break; } - if (callNode.getOp() > EOpSubgroupGuardStart && callNode.getOp() < EOpSubgroupGuardStop) { + if (callNode.isSubgroup()) { // these require SPIR-V 1.3 if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_3) error(loc, "requires SPIR-V 1.3", "subgroup op", ""); + + // Check that if extended types are being used that the correct extensions are enabled. + if (arg0 != nullptr) { + const TType& type = arg0->getType(); + switch (type.getBasicType()) { + default: + break; + case EbtInt8: + case EbtUint8: + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString().c_str()); + break; + case EbtInt16: + case EbtUint16: + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString().c_str()); + break; + case EbtInt64: + case EbtUint64: + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString().c_str()); + break; + case EbtFloat16: + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString().c_str()); + break; + } + } } } +#ifndef GLSLANG_WEB + extern bool PureOperatorBuiltins; // Deprecated! Use PureOperatorBuiltins == true instead, in which case this @@ -2200,17 +2737,19 @@ void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fn if (fnCandidate.getName().compare(0, 11, "imageAtomic") == 0) { const TType& imageType = callNode.getSequence()[0]->getAsTyped()->getType(); if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) { - if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui) + if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui) error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), ""); } else { if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0) error(loc, "only supported on integer images", fnCandidate.getName().c_str(), ""); - else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile) + else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile()) error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), ""); } } } +#endif + // // Do any extra checking for a user function call. // @@ -2358,6 +2897,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt bool errorReturn = false; switch(binaryNode->getOp()) { +#ifndef GLSLANG_WEB case EOpIndexDirect: case EOpIndexIndirect: // ... tessellation control shader ... @@ -2373,10 +2913,8 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", ""); } } - - break; // left node is checked by base class - case EOpIndexDirectStruct: break; // left node is checked by base class +#endif case EOpVectorSwizzle: errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft()); if (!errorReturn) { @@ -2408,8 +2946,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt } } - if (binaryNode && binaryNode->getOp() == EOpIndexDirectStruct && - binaryNode->getLeft()->getBasicType() == EbtReference) + if (binaryNode && binaryNode->getOp() == EOpIndexDirectStruct && binaryNode->getLeft()->isReference()) return false; // Let the base class check errors @@ -2432,7 +2969,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt case EvqFragDepth: intermediate.setDepthReplacing(); // "In addition, it is an error to statically write to gl_FragDepth in the fragment shader." - if (profile == EEsProfile && intermediate.getEarlyFragmentTests()) + if (isEsProfile() && intermediate.getEarlyFragmentTests()) message = "can't modify gl_FragDepth if using early_fragment_tests"; break; @@ -2469,12 +3006,15 @@ void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TInt // Let the base class check errors TParseContextBase::rValueErrorCheck(loc, op, node); -#ifdef AMD_EXTENSIONS TIntermSymbol* symNode = node->getAsSymbolNode(); - if (!(symNode && symNode->getQualifier().writeonly)) // base class checks - if (symNode && symNode->getQualifier().explicitInterp) + if (!(symNode && symNode->getQualifier().isWriteOnly())) // base class checks + if (symNode && symNode->getQualifier().isExplicitInterpolation()) error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str()); -#endif + + // local_size_{xyz} must be assigned or specialized before gl_WorkGroupSize can be assigned. + if(node->getQualifier().builtIn == EbvWorkGroupSize && + !(intermediate.isLocalSizeSet() || intermediate.isLocalSizeSpecialized())) + error(loc, "can't read from gl_WorkGroupSize before a fixed workgroup size has been declared", op, ""); } // @@ -2517,17 +3057,19 @@ void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& ide // "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be // declared in a shader; this results in a compile-time error." if (! symbolTable.atBuiltInLevel()) { - if (builtInName(identifier)) + if (builtInName(identifier) && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) + // The extension GL_EXT_spirv_intrinsics allows us to declare identifiers starting with "gl_". error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), ""); - // "__" are not supposed to be an error. ES 310 (and desktop) added the clarification: + // "__" are not supposed to be an error. ES 300 (and desktop) added the clarification: // "In addition, all identifiers containing two consecutive underscores (__) are // reserved; using such a name does not itself result in an error, but may result // in undefined behavior." // however, before that, ES tests required an error. - if (identifier.find("__") != TString::npos) { - if (profile == EEsProfile && version <= 300) - error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version <= 300", identifier.c_str(), ""); + if (identifier.find("__") != TString::npos && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) { + // The extension GL_EXT_spirv_intrinsics allows us to declare identifiers starting with "__". + if (isEsProfile() && version < 300) + error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version < 300", identifier.c_str(), ""); else warn(loc, "identifiers containing consecutive underscores (\"__\") are reserved", identifier.c_str(), ""); } @@ -2539,26 +3081,31 @@ void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& ide // void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* identifier, const char* op) { - // "__" are not supposed to be an error. ES 310 (and desktop) added the clarification: + // "__" are not supposed to be an error. ES 300 (and desktop) added the clarification: // "All macro names containing two consecutive underscores ( __ ) are reserved; // defining such a name does not itself result in an error, but may result in // undefined behavior. All macro names prefixed with "GL_" ("GL" followed by a // single underscore) are also reserved, and defining such a name results in a // compile-time error." // however, before that, ES tests required an error. - if (strncmp(identifier, "GL_", 3) == 0) + if (strncmp(identifier, "GL_", 3) == 0 && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) + // The extension GL_EXT_spirv_intrinsics allows us to declare macros prefixed with "GL_". ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op, identifier); else if (strncmp(identifier, "defined", 8) == 0) - ppError(loc, "\"defined\" can't be (un)defined:", op, identifier); - else if (strstr(identifier, "__") != 0) { - if (profile == EEsProfile && version >= 300 && + if (relaxedErrors()) + ppWarn(loc, "\"defined\" is (un)defined:", op, identifier); + else + ppError(loc, "\"defined\" can't be (un)defined:", op, identifier); + else if (strstr(identifier, "__") != 0 && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) { + // The extension GL_EXT_spirv_intrinsics allows us to declare macros prefixed with "__". + if (isEsProfile() && version >= 300 && (strcmp(identifier, "__LINE__") == 0 || strcmp(identifier, "__FILE__") == 0 || strcmp(identifier, "__VERSION__") == 0)) ppError(loc, "predefined names can't be (un)defined:", op, identifier); else { - if (profile == EEsProfile && version <= 300) - ppError(loc, "names containing consecutive underscores are reserved, and an error if version <= 300:", op, identifier); + if (isEsProfile() && version < 300 && !relaxedErrors()) + ppError(loc, "names containing consecutive underscores are reserved, and an error if version < 300:", op, identifier); else ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier); } @@ -2572,10 +3119,14 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden // bool TParseContext::lineContinuationCheck(const TSourceLoc& loc, bool endOfComment) { +#ifdef GLSLANG_WEB + return true; +#endif + const char* message = "line continuation"; - bool lineContinuationAllowed = (profile == EEsProfile && version >= 300) || - (profile != EEsProfile && (version >= 420 || extensionTurnedOn(E_GL_ARB_shading_language_420pack))); + bool lineContinuationAllowed = (isEsProfile() && version >= 300) || + (!isEsProfile() && (version >= 420 || extensionTurnedOn(E_GL_ARB_shading_language_420pack))); if (endOfComment) { if (lineContinuationAllowed) @@ -2624,10 +3175,27 @@ bool TParseContext::builtInName(const TString& identifier) // bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function, TOperator op, TType& type) { - type.shallowCopy(function.getType()); + // See if the constructor does not establish the main type, only requalifies + // it, in which case the type comes from the argument instead of from the + // constructor function. + switch (op) { +#ifndef GLSLANG_WEB + case EOpConstructNonuniform: + if (node != nullptr && node->getAsTyped() != nullptr) { + type.shallowCopy(node->getAsTyped()->getType()); + type.getQualifier().makeTemporary(); + type.getQualifier().nonUniform = true; + } + break; +#endif + default: + type.shallowCopy(function.getType()); + break; + } + // See if it's a matrix bool constructingMatrix = false; - switch(op) { + switch (op) { case EOpConstructTextureSampler: return constructorTextureSamplerError(loc, function); case EOpConstructMat2x2: @@ -2639,6 +3207,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructMat4x2: case EOpConstructMat4x3: case EOpConstructMat4x4: +#ifndef GLSLANG_WEB case EOpConstructDMat2x2: case EOpConstructDMat2x3: case EOpConstructDMat2x4: @@ -2657,6 +3226,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructF16Mat4x2: case EOpConstructF16Mat4x3: case EOpConstructF16Mat4x4: +#endif constructingMatrix = true; break; default: @@ -2675,6 +3245,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T bool matrixInMatrix = false; bool arrayArg = false; bool floatArgument = false; + bool intArgument = false; for (int arg = 0; arg < function.getParamCount(); ++arg) { if (function[arg].type->isArray()) { if (function[arg].type->isUnsizedArray()) { @@ -2705,21 +3276,24 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T specConstType = true; if (function[arg].type->isFloatingDomain()) floatArgument = true; + if (function[arg].type->isIntegerDomain()) + intArgument = true; if (type.isStruct()) { - if (function[arg].type->containsBasicType(EbtFloat16)) { + if (function[arg].type->contains16BitFloat()) { requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); } - if (function[arg].type->containsBasicType(EbtUint16) || - function[arg].type->containsBasicType(EbtInt16)) { + if (function[arg].type->contains16BitInt()) { requireInt16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); } - if (function[arg].type->containsBasicType(EbtUint8) || - function[arg].type->containsBasicType(EbtInt8)) { + if (function[arg].type->contains8BitInt()) { requireInt8Arithmetic(loc, "constructor", "can't construct structure containing 8-bit type"); } } } + if (op == EOpConstructNonuniform) + constType = false; +#ifndef GLSLANG_WEB switch (op) { case EOpConstructFloat16: case EOpConstructF16Vec2: @@ -2759,6 +3333,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T default: break; } +#endif // inherit constness from children if (constType) { @@ -2767,17 +3342,24 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T if (specConstType) { switch (op) { case EOpConstructInt8: - case EOpConstructUint8: - case EOpConstructInt16: - case EOpConstructUint16: case EOpConstructInt: case EOpConstructUint: - case EOpConstructInt64: - case EOpConstructUint64: case EOpConstructBool: case EOpConstructBVec2: case EOpConstructBVec3: case EOpConstructBVec4: + case EOpConstructIVec2: + case EOpConstructIVec3: + case EOpConstructIVec4: + case EOpConstructUVec2: + case EOpConstructUVec3: + case EOpConstructUVec4: +#ifndef GLSLANG_WEB + case EOpConstructUint8: + case EOpConstructInt16: + case EOpConstructUint16: + case EOpConstructInt64: + case EOpConstructUint64: case EOpConstructI8Vec2: case EOpConstructI8Vec3: case EOpConstructI8Vec4: @@ -2790,22 +3372,26 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructU16Vec2: case EOpConstructU16Vec3: case EOpConstructU16Vec4: - case EOpConstructIVec2: - case EOpConstructIVec3: - case EOpConstructIVec4: - case EOpConstructUVec2: - case EOpConstructUVec3: - case EOpConstructUVec4: case EOpConstructI64Vec2: case EOpConstructI64Vec3: case EOpConstructI64Vec4: case EOpConstructU64Vec2: case EOpConstructU64Vec3: case EOpConstructU64Vec4: +#endif // This was the list of valid ones, if they aren't converting from float // and aren't making an array. makeSpecConst = ! floatArgument && ! type.isArray(); break; + + case EOpConstructVec2: + case EOpConstructVec3: + case EOpConstructVec4: + // This was the list of valid ones, if they aren't converting from int + // and aren't making an array. + makeSpecConst = ! intArgument && !type.isArray(); + break; + default: // anything else wasn't white-listed in the spec as a conversion makeSpecConst = false; @@ -2892,16 +3478,26 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T return true; } + if (type.isCoopMat() && function.getParamCount() != 1) { + error(loc, "wrong number of arguments", "constructor", ""); + return true; + } + if (type.isCoopMat() && + !(function[0].type->isScalar() || function[0].type->isCoopMat())) { + error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", "constructor", ""); + return true; + } + TIntermTyped* typed = node->getAsTyped(); if (typed == nullptr) { error(loc, "constructor argument does not have a type", "constructor", ""); return true; } - if (op != EOpConstructStruct && typed->getBasicType() == EbtSampler) { + if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) { error(loc, "cannot convert a sampler", "constructor", ""); return true; } - if (op != EOpConstructStruct && typed->getBasicType() == EbtAtomicUint) { + if (op != EOpConstructStruct && typed->isAtomic()) { error(loc, "cannot convert an atomic_uint", "constructor", ""); return true; } @@ -2942,15 +3538,16 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const if (function[0].type->getBasicType() != EbtSampler || ! function[0].type->getSampler().isTexture() || function[0].type->isArray()) { - error(loc, "sampler-constructor first argument must be a scalar textureXXX type", token, ""); + error(loc, "sampler-constructor first argument must be a scalar *texture* type", token, ""); return true; } // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=() TSampler texture = function.getType().getSampler(); - texture.combined = false; + texture.setCombined(false); texture.shadow = false; if (texture != function[0].type->getSampler()) { - error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, ""); + error(loc, "sampler-constructor first argument must be a *texture* type" + " matching the dimensionality and sampled type of the constructor", token, ""); return true; } @@ -2960,7 +3557,7 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const if ( function[1].type->getBasicType() != EbtSampler || ! function[1].type->getSampler().isPureSampler() || function[1].type->isArray()) { - error(loc, "sampler-constructor second argument must be a scalar type 'sampler'", token, ""); + error(loc, "sampler-constructor second argument must be a scalar sampler or samplerShadow", token, ""); return true; } @@ -2999,14 +3596,14 @@ void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const { // Check that the appropriate extension is enabled if external sampler is used. // There are two extensions. The correct one must be used based on GLSL version. - if (type.getBasicType() == EbtSampler && type.getSampler().external) { + if (type.getBasicType() == EbtSampler && type.getSampler().isExternal()) { if (version < 300) { requireExtensions(loc, 1, &E_GL_OES_EGL_image_external, "samplerExternalOES"); } else { requireExtensions(loc, 1, &E_GL_OES_EGL_image_external_essl3, "samplerExternalOES"); } } - if (type.getSampler().yuv) { + if (type.getSampler().isYuv()) { requireExtensions(loc, 1, &E_GL_EXT_YUV_target, "__samplerExternal2DY2YEXT"); } @@ -3023,6 +3620,8 @@ void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const } } +#ifndef GLSLANG_WEB + void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (type.getQualifier().storage == EvqUniform) @@ -3033,20 +3632,21 @@ void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, co else if (type.getBasicType() == EbtAtomicUint && type.getQualifier().storage != EvqUniform) error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); } -#ifdef NV_EXTENSIONS -void TParseContext::accStructNVCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) + +void TParseContext::accStructCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (type.getQualifier().storage == EvqUniform) return; - if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStructNV)) + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStruct)) error(loc, "non-uniform struct contains an accelerationStructureNV:", type.getBasicTypeString().c_str(), identifier.c_str()); - else if (type.getBasicType() == EbtAccStructNV && type.getQualifier().storage != EvqUniform) + else if (type.getBasicType() == EbtAccStruct && type.getQualifier().storage != EvqUniform) error(loc, "accelerationStructureNV can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); } -#endif + +#endif // GLSLANG_WEB void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { @@ -3058,7 +3658,7 @@ void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& t if (type.containsNonOpaque()) { // Vulkan doesn't allow transparent uniforms outside of blocks - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0 && !spvVersion.vulkanRelaxed) vulkanRemoved(loc, "non-opaque uniforms outside a block"); // OpenGL wants locations on these (unless they are getting automapped) if (spvVersion.openGl > 0 && !type.getQualifier().hasLocation() && !intermediate.getAutoMapLocations()) @@ -3071,7 +3671,7 @@ void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& t // void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType) { - globalQualifierFixCheck(publicType.loc, publicType.qualifier); + globalQualifierFixCheck(publicType.loc, publicType.qualifier, true); checkNoShaderLayouts(publicType.loc, publicType.shaderQualifiers); if (publicType.qualifier.isNonUniform()) { error(publicType.loc, "not allowed on block or structure members", "nonuniformEXT", ""); @@ -3082,7 +3682,7 @@ void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType) // // Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level. // -void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier) +void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier, bool isMemberCheck) { bool nonuniformOkay = false; @@ -3098,6 +3698,8 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs"); profileRequires(loc, EEsProfile, 300, nullptr, "out for stage outputs"); qualifier.storage = EvqVaryingOut; + if (intermediate.isInvariantAll()) + qualifier.invariant = true; break; case EvqInOut: qualifier.storage = EvqVaryingIn; @@ -3107,14 +3709,34 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q case EvqTemporary: nonuniformOkay = true; break; + case EvqUniform: + // According to GLSL spec: The std430 qualifier is supported only for shader storage blocks; a shader using + // the std430 qualifier on a uniform block will fail to compile. + // Only check the global declaration: layout(std430) uniform; + if (blockName == nullptr && + qualifier.layoutPacking == ElpStd430) + { + requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "default std430 layout for uniform"); + } + break; default: break; } - if (!nonuniformOkay && qualifier.nonUniform) + if (!nonuniformOkay && qualifier.isNonUniform()) error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", ""); - invariantCheck(loc, qualifier); +#ifndef GLSLANG_WEB + if (qualifier.isSpirvByReference()) + error(loc, "can only apply to parameter", "spirv_by_reference", ""); + + if (qualifier.isSpirvLiteral()) + error(loc, "can only apply to parameter", "spirv_literal", ""); +#endif + + // Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it. + if (!isMemberCheck || structNestingLevel > 0) + invariantCheck(loc, qualifier); } // @@ -3125,7 +3747,7 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali if (! symbolTable.atGlobalLevel()) return; - if (!(publicType.userDef && publicType.userDef->getBasicType() == EbtReference)) { + if (!(publicType.userDef && publicType.userDef->isReference()) && !parsingBuiltins) { if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) { error(loc, "memory qualifiers cannot be used on this type", "", ""); } else if (qualifier.isMemory() && (publicType.basicType != EbtSampler) && !publicType.qualifier.isUniformOrBuffer()) { @@ -3135,13 +3757,18 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali if (qualifier.storage == EvqBuffer && publicType.basicType != EbtBlock && - !qualifier.layoutBufferReference) + !qualifier.hasBufferReference()) error(loc, "buffers can be declared only as blocks", "buffer", ""); + if (qualifier.storage != EvqVaryingIn && publicType.basicType == EbtDouble && + extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit) && language == EShLangVertex && + version < 400) { + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, E_GL_ARB_gpu_shader_fp64, "vertex-shader `double` type"); + } if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut) return; - if (publicType.shaderQualifiers.blendEquation) + if (publicType.shaderQualifiers.hasBlendEquation()) error(loc, "can only be applied to a standalone 'out'", "blend equation", ""); // now, knowing it is a shader in/out, do all the in/out semantic checks @@ -3154,25 +3781,15 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble) profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output"); - if (!qualifier.flat -#ifdef AMD_EXTENSIONS - && !qualifier.explicitInterp -#endif -#ifdef NV_EXTENSIONS - && !qualifier.pervertexNV -#endif - ) { + if (!qualifier.flat && !qualifier.isExplicitInterpolation() && !qualifier.isPervertexNV()) { if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble || - (publicType.userDef && (publicType.userDef->containsBasicType(EbtInt8) || - publicType.userDef->containsBasicType(EbtUint8) || - publicType.userDef->containsBasicType(EbtInt16) || - publicType.userDef->containsBasicType(EbtUint16) || - publicType.userDef->containsBasicType(EbtInt) || - publicType.userDef->containsBasicType(EbtUint) || - publicType.userDef->containsBasicType(EbtInt64) || - publicType.userDef->containsBasicType(EbtUint64) || - publicType.userDef->containsBasicType(EbtDouble)))) { + (publicType.userDef && ( publicType.userDef->containsBasicType(EbtInt) + || publicType.userDef->containsBasicType(EbtUint) + || publicType.userDef->contains16BitInt() + || publicType.userDef->contains8BitInt() + || publicType.userDef->contains64BitInt() + || publicType.userDef->containsDouble()))) { if (qualifier.storage == EvqVaryingIn && language == EShLangFragment) error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage)); else if (qualifier.storage == EvqVaryingOut && language == EShLangVertex && version == 300) @@ -3180,13 +3797,11 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali } } - if (qualifier.patch && qualifier.isInterpolation()) + if (qualifier.isPatch() && qualifier.isInterpolation()) error(loc, "cannot use interpolation qualifiers with patch", "patch", ""); -#ifdef NV_EXTENSIONS - if (qualifier.perTaskNV && publicType.basicType != EbtBlock) + if (qualifier.isTaskMemory() && publicType.basicType != EbtBlock) error(loc, "taskNV variables can be declared only as blocks", "taskNV", ""); -#endif if (qualifier.storage == EvqVaryingIn) { switch (language) { @@ -3200,22 +3815,10 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays"); } if (publicType.basicType == EbtDouble) - profileRequires(loc, ~EEsProfile, 410, nullptr, "vertex-shader `double` type input"); + profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_vertex_attrib_64bit, "vertex-shader `double` type input"); if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant) error(loc, "vertex input cannot be further qualified", "", ""); break; - - case EShLangTessControl: - if (qualifier.patch) - error(loc, "can only use on output in tessellation-control shader", "patch", ""); - break; - - case EShLangTessEvaluation: - break; - - case EShLangGeometry: - break; - case EShLangFragment: if (publicType.userDef) { profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input"); @@ -3226,12 +3829,16 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array"); } break; - - case EShLangCompute: + case EShLangCompute: if (! symbolTable.atBuiltInLevel()) error(loc, "global storage input qualifier cannot be used in a compute shader", "in", ""); break; - +#ifndef GLSLANG_WEB + case EShLangTessControl: + if (qualifier.patch) + error(loc, "can only use on output in tessellation-control shader", "patch", ""); + break; +#endif default: break; } @@ -3249,18 +3856,6 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali } break; - - case EShLangTessControl: - break; - - case EShLangTessEvaluation: - if (qualifier.patch) - error(loc, "can only use on input in tessellation-evaluation shader", "patch", ""); - break; - - case EShLangGeometry: - break; - case EShLangFragment: profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output"); if (publicType.basicType == EbtStruct) { @@ -3282,7 +3877,12 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali case EShLangCompute: error(loc, "global storage output qualifier cannot be used in a compute shader", "out", ""); break; - +#ifndef GLSLANG_WEB + case EShLangTessEvaluation: + if (qualifier.patch) + error(loc, "can only use on input in tessellation-evaluation shader", "patch", ""); + break; +#endif default: break; } @@ -3306,18 +3906,14 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons // Multiple interpolation qualifiers (mostly done later by 'individual qualifiers') if (src.isInterpolation() && dst.isInterpolation()) -#ifdef AMD_EXTENSIONS error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective, __explicitInterpAMD)", "", ""); -#else - error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", ""); -#endif // Ordering - if (! force && ((profile != EEsProfile && version < 420) || - (profile == EEsProfile && version < 310)) + if (! force && ((!isEsProfile() && version < 420) || + (isEsProfile() && version < 310)) && ! extensionTurnedOn(E_GL_ARB_shading_language_420pack)) { // non-function parameters - if (src.noContraction && (dst.invariant || dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) + if (src.isNoContraction() && (dst.invariant || dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) error(loc, "precise qualifier must appear first", "", ""); if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) error(loc, "invariant qualifier must appear before interpolation, storage, and precision qualifiers ", "", ""); @@ -3329,7 +3925,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons error(loc, "precision qualifier must appear as last qualifier", "", ""); // function parameters - if (src.noContraction && (dst.storage == EvqConst || dst.storage == EvqIn || dst.storage == EvqOut)) + if (src.isNoContraction() && (dst.storage == EvqConst || dst.storage == EvqIn || dst.storage == EvqOut)) error(loc, "precise qualifier must appear first", "", ""); if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut)) error(loc, "in/out must appear before const", "", ""); @@ -3354,13 +3950,17 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons if (dst.precision == EpqNone || (force && src.precision != EpqNone)) dst.precision = src.precision; - if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) || - (src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) || - (src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent)) || - (src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent)) || - (src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent)))) { - error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent qualifier allowed", GetPrecisionQualifierString(src.precision), ""); +#ifndef GLSLANG_WEB + if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || + (src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || + (src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || + (src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || + (src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.shadercallcoherent)) || + (src.shadercallcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)))) { + error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed", + GetPrecisionQualifierString(src.precision), ""); } +#endif // Layout qualifiers mergeObjectLayoutQualifiers(dst, src, false); @@ -3368,19 +3968,17 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons bool repeated = false; #define MERGE_SINGLETON(field) repeated |= dst.field && src.field; dst.field |= src.field; MERGE_SINGLETON(invariant); - MERGE_SINGLETON(noContraction); MERGE_SINGLETON(centroid); MERGE_SINGLETON(smooth); MERGE_SINGLETON(flat); + MERGE_SINGLETON(specConstant); +#ifndef GLSLANG_WEB + MERGE_SINGLETON(noContraction); MERGE_SINGLETON(nopersp); -#ifdef AMD_EXTENSIONS MERGE_SINGLETON(explicitInterp); -#endif -#ifdef NV_EXTENSIONS MERGE_SINGLETON(perPrimitiveNV); MERGE_SINGLETON(perViewNV); MERGE_SINGLETON(perTaskNV); -#endif MERGE_SINGLETON(patch); MERGE_SINGLETON(sample); MERGE_SINGLETON(coherent); @@ -3388,13 +3986,49 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons MERGE_SINGLETON(queuefamilycoherent); MERGE_SINGLETON(workgroupcoherent); MERGE_SINGLETON(subgroupcoherent); + MERGE_SINGLETON(shadercallcoherent); MERGE_SINGLETON(nonprivate); MERGE_SINGLETON(volatil); MERGE_SINGLETON(restrict); MERGE_SINGLETON(readonly); MERGE_SINGLETON(writeonly); - MERGE_SINGLETON(specConstant); MERGE_SINGLETON(nonUniform); +#endif + +#ifndef GLSLANG_WEB + // SPIR-V storage class qualifier (GL_EXT_spirv_intrinsics) + dst.spirvStorageClass = src.spirvStorageClass; + + // SPIR-V decorate qualifiers (GL_EXT_spirv_intrinsics) + if (src.hasSprivDecorate()) { + if (dst.hasSprivDecorate()) { + const TSpirvDecorate& srcSpirvDecorate = src.getSpirvDecorate(); + TSpirvDecorate& dstSpirvDecorate = dst.getSpirvDecorate(); + for (auto& decorate : srcSpirvDecorate.decorates) { + if (dstSpirvDecorate.decorates.find(decorate.first) != dstSpirvDecorate.decorates.end()) + error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate", "(decoration=%u)", decorate.first); + else + dstSpirvDecorate.decorates.insert(decorate); + } + + for (auto& decorateId : srcSpirvDecorate.decorateIds) { + if (dstSpirvDecorate.decorateIds.find(decorateId.first) != dstSpirvDecorate.decorateIds.end()) + error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate_id", "(decoration=%u)", decorateId.first); + else + dstSpirvDecorate.decorateIds.insert(decorateId); + } + + for (auto& decorateString : srcSpirvDecorate.decorateStrings) { + if (dstSpirvDecorate.decorates.find(decorateString.first) != dstSpirvDecorate.decorates.end()) + error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate_string", "(decoration=%u)", decorateString.first); + else + dstSpirvDecorate.decorates.insert(decorateString); + } + } else { + dst.spirvDecorate = src.spirvDecorate; + } + } +#endif if (repeated) error(loc, "replicated qualifiers", "", ""); @@ -3437,11 +4071,11 @@ void TParseContext::setDefaultPrecision(const TSourceLoc& loc, TPublicType& publ // correlates with the declaration of defaultSamplerPrecision[] int TParseContext::computeSamplerTypeIndex(TSampler& sampler) { - int arrayIndex = sampler.arrayed ? 1 : 0; - int shadowIndex = sampler.shadow ? 1 : 0; - int externalIndex = sampler.external? 1 : 0; - int imageIndex = sampler.image ? 1 : 0; - int msIndex = sampler.ms ? 1 : 0; + int arrayIndex = sampler.arrayed ? 1 : 0; + int shadowIndex = sampler.shadow ? 1 : 0; + int externalIndex = sampler.isExternal() ? 1 : 0; + int imageIndex = sampler.isImageClass() ? 1 : 0; + int msIndex = sampler.isMultiSample() ? 1 : 0; int flattened = EsdNumDims * (EbtNumTypes * (2 * (2 * (2 * (2 * arrayIndex + msIndex) + imageIndex) + shadowIndex) + externalIndex) + sampler.type) + sampler.dim; @@ -3465,8 +4099,10 @@ void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType ba if (! obeyPrecisionQualifiers() || parsingBuiltins) return; +#ifndef GLSLANG_WEB if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh) error(loc, "atomic counters can only be highp", "atomic_uint", ""); +#endif if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) { if (qualifier.precision == EpqNone) { @@ -3485,8 +4121,7 @@ void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier { if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque()) error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), ""); - - if (!parsingBuiltins && type.containsBasicType(EbtFloat16)) + if (!parsingBuiltins && type.contains16BitFloat()) requireFloat16Arithmetic(loc, type.getBasicTypeString().c_str(), "float16 types can only be in uniform block or buffer storage"); if (!parsingBuiltins && type.contains16BitInt()) requireInt16Arithmetic(loc, type.getBasicTypeString().c_str(), "(u)int16 types can only be in uniform block or buffer storage"); @@ -3513,7 +4148,7 @@ bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType bas // // Do size checking for an array type's size. // -void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair) +void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair, const char *sizeType) { bool isConst = false; sizePair.node = nullptr; @@ -3533,18 +4168,24 @@ void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TA TIntermSymbol* symbol = expr->getAsSymbolNode(); if (symbol && symbol->getConstArray().size() > 0) size = symbol->getConstArray()[0].getIConst(); + } else if (expr->getAsUnaryNode() && + expr->getAsUnaryNode()->getOp() == glslang::EOpArrayLength && + expr->getAsUnaryNode()->getOperand()->getType().isCoopMat()) { + isConst = true; + size = 1; + sizePair.node = expr->getAsUnaryNode(); } } sizePair.size = size; if (! isConst || (expr->getBasicType() != EbtInt && expr->getBasicType() != EbtUint)) { - error(loc, "array size must be a constant integer expression", "", ""); + error(loc, sizeType, "", "must be a constant integer expression"); return; } if (size <= 0) { - error(loc, "array size must be a positive integer", "", ""); + error(loc, sizeType, "", "must be a positive integer"); return; } } @@ -3602,7 +4243,7 @@ bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type) // void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes) { - if (arraySizes.hasUnsized()) + if (!parsingBuiltins && arraySizes.hasUnsized()) error(loc, "array size required", "", ""); } @@ -3639,54 +4280,57 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua arraySizes->clearInnerUnsized(); } - if (arraySizes->isInnerSpecialization()) + if (arraySizes->isInnerSpecialization() && + (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal && qualifier.storage != EvqShared && qualifier.storage != EvqConst)) error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", ""); +#ifndef GLSLANG_WEB + // desktop always allows outer-dimension-unsized variable arrays, - if (profile != EEsProfile) + if (!isEsProfile()) return; // for ES, if size isn't coming from an initializer, it has to be explicitly declared now, // with very few exceptions - // last member of ssbo block exception: - if (qualifier.storage == EvqBuffer && lastMember) - return; - // implicitly-sized io exceptions: switch (language) { case EShLangGeometry: if (qualifier.storage == EvqVaryingIn) - if ((profile == EEsProfile && version >= 320) || + if ((isEsProfile() && version >= 320) || extensionsTurnedOn(Num_AEP_geometry_shader, AEP_geometry_shader)) return; break; case EShLangTessControl: if ( qualifier.storage == EvqVaryingIn || - (qualifier.storage == EvqVaryingOut && ! qualifier.patch)) - if ((profile == EEsProfile && version >= 320) || + (qualifier.storage == EvqVaryingOut && ! qualifier.isPatch())) + if ((isEsProfile() && version >= 320) || extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) return; break; case EShLangTessEvaluation: - if ((qualifier.storage == EvqVaryingIn && ! qualifier.patch) || + if ((qualifier.storage == EvqVaryingIn && ! qualifier.isPatch()) || qualifier.storage == EvqVaryingOut) - if ((profile == EEsProfile && version >= 320) || + if ((isEsProfile() && version >= 320) || extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) return; break; -#ifdef NV_EXTENSIONS case EShLangMeshNV: if (qualifier.storage == EvqVaryingOut) - if ((profile == EEsProfile && version >= 320) || + if ((isEsProfile() && version >= 320) || extensionTurnedOn(E_GL_NV_mesh_shader)) return; break; -#endif default: break; } +#endif + + // last member of ssbo block exception: + if (qualifier.storage == EvqBuffer && lastMember) + return; + arraySizeRequiredCheck(loc, *arraySizes); } @@ -3727,13 +4371,15 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie if (symbolTable.atGlobalLevel()) trackLinkage(*symbol); +#ifndef GLSLANG_WEB if (! symbolTable.atBuiltInLevel()) { if (isIoResizeArray(type)) { ioArraySymbolResizeList.push_back(symbol); - checkIoArraysConsistency(loc, true, type.getQualifier().isPerPrimitive()); + checkIoArraysConsistency(loc, true); } else fixIoArraySize(loc, symbol->getWritableType()); } +#endif return; } @@ -3771,6 +4417,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie return; } +#ifndef GLSLANG_WEB if (existingType.isSizedArray()) { // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize())) @@ -3783,9 +4430,12 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie existingType.updateArraySizes(type); if (isIoResizeArray(type)) - checkIoArraysConsistency(loc, false, type.getQualifier().isPerPrimitive()); + checkIoArraysConsistency(loc); +#endif } +#ifndef GLSLANG_WEB + // Policy and error check for needing a runtime sized array. void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermTyped& base) { @@ -3793,13 +4443,16 @@ void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermType if (isRuntimeLength(base)) return; + if (base.getType().getQualifier().builtIn == EbvSampleMask) + return; + // Check for last member of a bufferreference type, which is runtime sizeable // but doesn't support runtime length if (base.getType().getQualifier().storage == EvqBuffer) { const TIntermBinary* binary = base.getAsBinaryNode(); if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct && - binary->getLeft()->getBasicType() == EbtReference) { + binary->getLeft()->isReference()) { const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); const int memberCount = (int)binary->getLeft()->getType().getReferentType()->getStruct()->size(); @@ -3809,8 +4462,8 @@ void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermType } // check for additional things allowed by GL_EXT_nonuniform_qualifier - if (base.getBasicType() == EbtSampler || - (base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer())) + if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStruct || base.getBasicType() == EbtRayQuery || + (base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer())) requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index"); else error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable"); @@ -3826,7 +4479,7 @@ bool TParseContext::isRuntimeLength(const TIntermTyped& base) const // is it the last member? const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); - if (binary->getLeft()->getBasicType() == EbtReference) + if (binary->getLeft()->isReference()) return false; const int memberCount = (int)binary->getLeft()->getType().getStruct()->size(); @@ -3838,27 +4491,34 @@ bool TParseContext::isRuntimeLength(const TIntermTyped& base) const return false; } -#ifdef NV_EXTENSIONS -// Fix mesh view output array dimension -void TParseContext::resizeMeshViewDimension(const TSourceLoc& loc, TType& type) +// Check if mesh perviewNV attributes have a view dimension +// and resize it to gl_MaxMeshViewCountNV when implicitly sized. +void TParseContext::checkAndResizeMeshViewDim(const TSourceLoc& loc, TType& type, bool isBlockMember) { // see if member is a per-view attribute - if (type.getQualifier().isPerView()) { - // since we don't have the maxMeshViewCountNV set during parsing builtins, we hardcode the value - int maxViewCount = parsingBuiltins ? 4 : resources.maxMeshViewCountNV; + if (!type.getQualifier().isPerView()) + return; - if (! type.isArray()) { - error(loc, "requires an view array dimension", "perviewNV", ""); - } - else if (!type.isUnsizedArray() && type.getOuterArraySize() != maxViewCount) { + if ((isBlockMember && type.isArray()) || (!isBlockMember && type.isArrayOfArrays())) { + // since we don't have the maxMeshViewCountNV set during parsing builtins, we hardcode the value. + int maxViewCount = parsingBuiltins ? 4 : resources.maxMeshViewCountNV; + // For block members, outermost array dimension is the view dimension. + // For non-block members, outermost array dimension is the vertex/primitive dimension + // and 2nd outermost is the view dimension. + int viewDim = isBlockMember ? 0 : 1; + int viewDimSize = type.getArraySizes()->getDimSize(viewDim); + + if (viewDimSize != UnsizedArraySize && viewDimSize != maxViewCount) error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", ""); - } - else if (type.isUnsizedArray()) { - type.changeOuterArraySize(maxViewCount); - } + else if (viewDimSize == UnsizedArraySize) + type.getArraySizes()->setDimSize(viewDim, maxViewCount); + } + else { + error(loc, "requires a view array dimension", "perviewNV", ""); } } -#endif + +#endif // GLSLANG_WEB // Returns true if the first argument to the #line directive is the line number for the next line. // @@ -3871,7 +4531,7 @@ void TParseContext::resizeMeshViewDimension(const TSourceLoc& loc, TType& type) // source string number source-string-number. bool TParseContext::lineDirectiveShouldSetNextLine() const { - return profile == EEsProfile || version >= 330; + return isEsProfile() || version >= 330; } // @@ -3902,18 +4562,19 @@ void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType) { +#ifndef GLSLANG_WEB if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel()) return nullptr; - bool nonEsRedecls = (profile != EEsProfile && (version >= 130 || identifier == "gl_TexCoord")); - bool esRedecls = (profile == EEsProfile && + bool nonEsRedecls = (!isEsProfile() && (version >= 130 || identifier == "gl_TexCoord")); + bool esRedecls = (isEsProfile() && (version >= 320 || extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks))); if (! esRedecls && ! nonEsRedecls) return nullptr; // Special case when using GL_ARB_separate_shader_objects bool ssoPre150 = false; // means the only reason this variable is redeclared is due to this combination - if (profile != EEsProfile && version <= 140 && extensionTurnedOn(E_GL_ARB_separate_shader_objects)) { + if (!isEsProfile() && version <= 140 && extensionTurnedOn(E_GL_ARB_separate_shader_objects)) { if (identifier == "gl_Position" || identifier == "gl_PointSize" || identifier == "gl_ClipVertex" || @@ -3928,6 +4589,8 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS (identifier == "gl_FragCoord" && ((nonEsRedecls && version >= 150) || esRedecls)) || identifier == "gl_ClipDistance" || identifier == "gl_CullDistance" || + identifier == "gl_ShadingRateEXT" || + identifier == "gl_PrimitiveShadingRateEXT" || identifier == "gl_FrontColor" || identifier == "gl_BackColor" || identifier == "gl_FrontSecondaryColor" || @@ -3936,10 +4599,9 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS (identifier == "gl_Color" && language == EShLangFragment) || (identifier == "gl_FragStencilRefARB" && (nonEsRedecls && version >= 140) && language == EShLangFragment) || -#ifdef NV_EXTENSIONS identifier == "gl_SampleMask" || identifier == "gl_Layer" || -#endif + identifier == "gl_PrimitiveIndicesNV" || identifier == "gl_TexCoord") { // Find the existing symbol, if any. @@ -3954,8 +4616,10 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS // If it wasn't at a built-in level, then it's already been redeclared; // that is, this is a redeclaration of a redeclaration; reuse that initial // redeclaration. Otherwise, make the new one. - if (builtIn) + if (builtIn) { makeEditable(symbol); + symbolTable.amendSymbolIdLevel(*symbol); + } // Now, modify the type of the copy, as per the type of the current redeclaration. @@ -4018,13 +4682,14 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str()); } } - else if (identifier == "gl_FragStencilRefARB") { + else if ( + identifier == "gl_PrimitiveIndicesNV" || + identifier == "gl_FragStencilRefARB") { if (qualifier.hasLayout()) error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str()); if (qualifier.storage != EvqVaryingOut) error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str()); } -#ifdef NV_EXTENSIONS else if (identifier == "gl_SampleMask") { if (!publicType.layoutOverrideCoverage) { error(loc, "redeclaration only allowed for override_coverage layout", "redeclaration", symbol->getName().c_str()); @@ -4037,12 +4702,12 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS symbolQualifier.layoutViewportRelative = qualifier.layoutViewportRelative; symbolQualifier.layoutSecondaryViewportRelativeOffset = qualifier.layoutSecondaryViewportRelativeOffset; } -#endif // TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above return symbol; } +#endif return nullptr; } @@ -4054,16 +4719,13 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes) { +#ifndef GLSLANG_WEB const char* feature = "built-in block redeclaration"; profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature); profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature); - if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment" -#ifdef NV_EXTENSIONS - && blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV" -#endif - ) - { + if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment" && + blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV") { error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str()); return; } @@ -4122,7 +4784,6 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT TType& type = block->getWritableType(); -#ifdef NV_EXTENSIONS // if gl_PerVertex is redeclared for the purpose of passing through "gl_Position" // for passthrough purpose, the redeclared block should have the same qualifers as // the current one @@ -4132,7 +4793,6 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT type.getQualifier().layoutStream = currentBlockQualifier.layoutStream; type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; } -#endif TTypeList::iterator member = type.getWritableStruct()->begin(); size_t numOriginalMembersFound = 0; @@ -4165,7 +4825,6 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), ""); else if (! oldType.getQualifier().isPerView() && newType.isArray()) arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize()); -#ifdef NV_EXTENSIONS if (oldType.getQualifier().isPerView() && ! newType.getQualifier().isPerView()) error(memberLoc, "missing perviewNV qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); else if (! oldType.getQualifier().isPerView() && newType.getQualifier().isPerView()) @@ -4185,7 +4844,6 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT error(memberLoc, "missing perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); else if (! oldType.getQualifier().isPerPrimitive() && newType.getQualifier().isPerPrimitive()) error(memberLoc, "cannot add perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); -#endif if (newType.getQualifier().isMemory()) error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); if (newType.getQualifier().hasNonXfbLayout()) @@ -4270,12 +4928,13 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT // Tracking for implicit sizing of array if (isIoResizeArray(block->getType())) { ioArraySymbolResizeList.push_back(block); - checkIoArraysConsistency(loc, true, block->getType().getQualifier().isPerPrimitive()); + checkIoArraysConsistency(loc, true); } else if (block->getType().isArray()) fixIoArraySize(loc, block->getWritableType()); // Save it in the AST for linker use. trackLinkage(*block); +#endif // GLSLANG_WEB } void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type) @@ -4303,6 +4962,7 @@ void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQu void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& qualifier, TType& type) { +#ifndef GLSLANG_WEB if (qualifier.isMemory()) { type.getQualifier().volatil = qualifier.volatil; type.getQualifier().coherent = qualifier.coherent; @@ -4310,11 +4970,13 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali type.getQualifier().queuefamilycoherent = qualifier.queuefamilycoherent; type.getQualifier().workgroupcoherent = qualifier.workgroupcoherent; type.getQualifier().subgroupcoherent = qualifier.subgroupcoherent; + type.getQualifier().shadercallcoherent = qualifier.shadercallcoherent; type.getQualifier().nonprivate = qualifier.nonprivate; type.getQualifier().readonly = qualifier.readonly; type.getQualifier().writeonly = qualifier.writeonly; type.getQualifier().restrict = qualifier.restrict; } +#endif if (qualifier.isAuxiliary() || qualifier.isInterpolation()) @@ -4323,28 +4985,39 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali error(loc, "cannot use layout qualifiers on a function parameter", "", ""); if (qualifier.invariant) error(loc, "cannot use invariant qualifier on a function parameter", "", ""); - if (qualifier.noContraction) { + if (qualifier.isNoContraction()) { if (qualifier.isParamOutput()) - type.getQualifier().noContraction = true; + type.getQualifier().setNoContraction(); else warn(loc, "qualifier has no effect on non-output parameters", "precise", ""); } if (qualifier.isNonUniform()) type.getQualifier().nonUniform = qualifier.nonUniform; +#ifndef GLSLANG_WEB + if (qualifier.isSpirvByReference()) + type.getQualifier().setSpirvByReference(); + if (qualifier.isSpirvLiteral()) { + if (type.getBasicType() == EbtFloat || type.getBasicType() == EbtInt || type.getBasicType() == EbtUint || + type.getBasicType() == EbtBool) + type.getQualifier().setSpirvLiteral(); + else + error(loc, "cannot use spirv_literal qualifier", type.getBasicTypeString().c_str(), ""); +#endif + } paramCheckFixStorage(loc, qualifier.storage, type); } void TParseContext::nestedBlockCheck(const TSourceLoc& loc) { - if (structNestingLevel > 0) + if (structNestingLevel > 0 || blockNestingLevel > 0) error(loc, "cannot nest a block definition inside a structure or block", "", ""); - ++structNestingLevel; + ++blockNestingLevel; } void TParseContext::nestedStructCheck(const TSourceLoc& loc) { - if (structNestingLevel > 0) + if (structNestingLevel > 0 || blockNestingLevel > 0) error(loc, "cannot nest a structure definition inside a structure or block", "", ""); ++structNestingLevel; } @@ -4364,8 +5037,17 @@ void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const error(loc, "can't use with samplers or structs containing samplers", op, ""); } +void TParseContext::referenceCheck(const TSourceLoc& loc, const TType& type, const char* op) +{ +#ifndef GLSLANG_WEB + if (containsFieldWithBasicType(type, EbtReference)) + error(loc, "can't use with reference types", op, ""); +#endif +} + void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TType& type, const char* op) { +#ifndef GLSLANG_WEB if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtFloat16)) requireFloat16Arithmetic(loc, op, "can't use with structs containing float16"); @@ -4395,6 +5077,7 @@ void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TTy if (type.isArray() && type.getBasicType() == EbtUint8) requireInt8Arithmetic(loc, op, "can't use with arrays containing uint8"); +#endif } void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op) @@ -4446,6 +5129,7 @@ void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publ // void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop) { +#ifndef GLSLANG_WEB // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration bool badInit = false; if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1) @@ -4475,7 +5159,7 @@ void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, } // get the unique id of the loop index - int loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId(); + long long loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId(); inductiveLoopIds.insert(loopIndex); // condition's form must be "loop-index relational-operator constant-expression" @@ -4541,8 +5225,10 @@ void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, // the body inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable); +#endif } +#ifndef GLSLANG_WEB // Do limit checks for built-in arrays. void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size) { @@ -4552,13 +5238,12 @@ void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identi limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistance array size"); else if (identifier.compare("gl_CullDistance") == 0) limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistance array size"); -#ifdef NV_EXTENSIONS else if (identifier.compare("gl_ClipDistancePerViewNV") == 0) limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistancePerViewNV array size"); else if (identifier.compare("gl_CullDistancePerViewNV") == 0) limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistancePerViewNV array size"); -#endif } +#endif // GLSLANG_WEB // See if the provided value is less than or equal to the symbol indicated by limit, // which should be a constant in the symbol table. @@ -4572,6 +5257,8 @@ void TParseContext::limitCheck(const TSourceLoc& loc, int value, const char* lim error(loc, "must be less than or equal to", feature, "%s (%d)", limit, constArray[0].getIConst()); } +#ifndef GLSLANG_WEB + // // Do any additional error checking, etc., once we know the parsing is done. // @@ -4593,33 +5280,30 @@ void TParseContext::finish() // about the stage itself. switch (language) { case EShLangGeometry: - if (profile == EEsProfile && version == 310) + if (isEsProfile() && version == 310) requireExtensions(getCurrentLoc(), Num_AEP_geometry_shader, AEP_geometry_shader, "geometry shaders"); break; case EShLangTessControl: case EShLangTessEvaluation: - if (profile == EEsProfile && version == 310) + if (isEsProfile() && version == 310) requireExtensions(getCurrentLoc(), Num_AEP_tessellation_shader, AEP_tessellation_shader, "tessellation shaders"); - else if (profile != EEsProfile && version < 400) + else if (!isEsProfile() && version < 400) requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_tessellation_shader, "tessellation shaders"); break; case EShLangCompute: - if (profile != EEsProfile && version < 430) + if (!isEsProfile() && version < 430) requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders"); break; -#ifdef NV_EXTENSIONS case EShLangTaskNV: requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "task shaders"); break; case EShLangMeshNV: requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders"); break; -#endif default: break; } -#ifdef NV_EXTENSIONS // Set default outputs for GL_NV_geometry_shader_passthrough if (language == EShLangGeometry && extensionTurnedOn(E_SPV_NV_geometry_shader_passthrough)) { if (intermediate.getOutputPrimitive() == ElgNone) { @@ -4639,8 +5323,8 @@ void TParseContext::finish() } } } -#endif } +#endif // GLSLANG_WEB // // Layout qualifier stuff. @@ -4661,14 +5345,22 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi return; } if (id == TQualifier::getLayoutPackingString(ElpPacked)) { - if (spvVersion.spv != 0) - spvRemoved(loc, "packed"); + if (spvVersion.spv != 0) { + if (spvVersion.vulkanRelaxed) + return; // silently ignore qualifier + else + spvRemoved(loc, "packed"); + } publicType.qualifier.layoutPacking = ElpPacked; return; } if (id == TQualifier::getLayoutPackingString(ElpShared)) { - if (spvVersion.spv != 0) - spvRemoved(loc, "shared"); + if (spvVersion.spv != 0) { + if (spvVersion.vulkanRelaxed) + return; // silently ignore qualifier + else + spvRemoved(loc, "shared"); + } publicType.qualifier.layoutPacking = ElpShared; return; } @@ -4676,9 +5368,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.qualifier.layoutPacking = ElpStd140; return; } +#ifndef GLSLANG_WEB if (id == TQualifier::getLayoutPackingString(ElpStd430)) { requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430"); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "std430"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "std430"); profileRequires(loc, EEsProfile, 310, nullptr, "std430"); publicType.qualifier.layoutPacking = ElpStd430; return; @@ -4715,20 +5408,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi intermediate.setUsePhysicalStorageBuffer(); return; } - if (language == EShLangGeometry || language == EShLangTessEvaluation -#ifdef NV_EXTENSIONS - || language == EShLangMeshNV -#endif - ) { + if (language == EShLangGeometry || language == EShLangTessEvaluation || language == EShLangMeshNV) { if (id == TQualifier::getGeometryString(ElgTriangles)) { publicType.shaderQualifiers.geometry = ElgTriangles; return; } - if (language == EShLangGeometry -#ifdef NV_EXTENSIONS - || language == EShLangMeshNV -#endif - ) { + if (language == EShLangGeometry || language == EShLangMeshNV) { if (id == TQualifier::getGeometryString(ElgPoints)) { publicType.shaderQualifiers.geometry = ElgPoints; return; @@ -4737,10 +5422,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.shaderQualifiers.geometry = ElgLines; return; } -#ifdef NV_EXTENSIONS - if (language == EShLangGeometry) -#endif - { + if (language == EShLangGeometry) { if (id == TQualifier::getGeometryString(ElgLineStrip)) { publicType.shaderQualifiers.geometry = ElgLineStrip; return; @@ -4757,14 +5439,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.shaderQualifiers.geometry = ElgTriangleStrip; return; } -#ifdef NV_EXTENSIONS if (id == "passthrough") { requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough"); publicType.qualifier.layoutPassthrough = true; intermediate.setGeoPassthroughEXT(); return; } -#endif } } else { assert(language == EShLangTessEvaluation); @@ -4847,6 +5527,17 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi return; } } + for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) { + if (id == TQualifier::getInterlockOrderingString(order)) { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 450, nullptr, "fragment shader interlock layout qualifier"); + requireExtensions(loc, 1, &E_GL_ARB_fragment_shader_interlock, TQualifier::getInterlockOrderingString(order)); + if (order == EioShadingRateInterlockOrdered || order == EioShadingRateInterlockUnordered) + requireExtensions(loc, 1, &E_GL_NV_shading_rate_image, TQualifier::getInterlockOrderingString(order)); + publicType.shaderQualifiers.interlockOrdering = order; + return; + } + } if (id.compare(0, 13, "blend_support") == 0) { bool found = false; for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) { @@ -4863,7 +5554,6 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "unknown blend equation", "blend_support", ""); return; } -#ifdef NV_EXTENSIONS if (id == "override_coverage") { requireExtensions(loc, 1, &E_GL_NV_sample_mask_override_coverage, "sample mask override coverage"); publicType.shaderQualifiers.layoutOverrideCoverage = true; @@ -4880,13 +5570,19 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi return; } } else { - if (language == EShLangRayGenNV || language == EShLangIntersectNV || - language == EShLangAnyHitNV || language == EShLangClosestHitNV || - language == EShLangMissNV || language == EShLangCallableNV) { - if (id == "shaderrecordnv") { - publicType.qualifier.layoutShaderRecordNV = true; + if (language == EShLangRayGen || language == EShLangIntersect || + language == EShLangAnyHit || language == EShLangClosestHit || + language == EShLangMiss || language == EShLangCallable) { + if (id == "shaderrecordnv" || id == "shaderrecordext") { + if (id == "shaderrecordnv") { + requireExtensions(loc, 1, &E_GL_NV_ray_tracing, "shader record NV"); + } else { + requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "shader record EXT"); + } + publicType.qualifier.layoutShaderRecord = true; return; } + } } if (language == EShLangCompute) { @@ -4901,9 +5597,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } } } -#else + + if (id == "primitive_culling") { + requireExtensions(loc, 1, &E_GL_EXT_ray_flags_primitive_culling, "primitive culling"); + publicType.shaderQualifiers.layoutPrimitiveCulling = true; + return; } #endif + error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), ""); } @@ -4917,6 +5618,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi integerCheck(node, feature); const TIntermConstantUnion* constUnion = node->getAsConstantUnion(); int value; + bool nonLiteral = false; if (constUnion) { value = constUnion->getConstArray()[0].getIConst(); if (! constUnion->isLiteral()) { @@ -4926,6 +5628,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } else { // grammar should have give out the error message value = 0; + nonLiteral = true; } if (value < 0) { @@ -4947,6 +5650,9 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi profileRequires(loc, EEsProfile, 310, nullptr, feature); } publicType.qualifier.layoutOffset = value; + publicType.qualifier.explicitOffset = true; + if (nonLiteral) + error(loc, "needs a literal integer", "offset", ""); return; } else if (id == "align") { const char* feature = "uniform buffer-member align"; @@ -4959,15 +5665,20 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "must be a power of 2", "align", ""); else publicType.qualifier.layoutAlign = value; + if (nonLiteral) + error(loc, "needs a literal integer", "align", ""); return; } else if (id == "location") { profileRequires(loc, EEsProfile, 300, nullptr, "location"); - const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; + const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; + // GL_ARB_explicit_uniform_location requires 330 or GL_ARB_explicit_attrib_location we do not need to add it here profileRequires(loc, ~EEsProfile, 330, 2, exts, "location"); if ((unsigned int)value >= TQualifier::layoutLocationEnd) error(loc, "location is too large", id.c_str(), ""); else publicType.qualifier.layoutLocation = value; + if (nonLiteral) + error(loc, "needs a literal integer", "location", ""); return; } else if (id == "set") { if ((unsigned int)value >= TQualifier::layoutSetEnd) @@ -4976,24 +5687,49 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.qualifier.layoutSet = value; if (value != 0) requireVulkan(loc, "descriptor set"); + if (nonLiteral) + error(loc, "needs a literal integer", "set", ""); return; } else if (id == "binding") { +#ifndef GLSLANG_WEB profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding"); profileRequires(loc, EEsProfile, 310, nullptr, "binding"); +#endif if ((unsigned int)value >= TQualifier::layoutBindingEnd) error(loc, "binding is too large", id.c_str(), ""); else publicType.qualifier.layoutBinding = value; + if (nonLiteral) + error(loc, "needs a literal integer", "binding", ""); return; - } else if (id == "component") { + } + if (id == "constant_id") { + requireSpv(loc, "constant_id"); + if (value >= (int)TQualifier::layoutSpecConstantIdEnd) { + error(loc, "specialization-constant id is too large", id.c_str(), ""); + } else { + publicType.qualifier.layoutSpecConstantId = value; + publicType.qualifier.specConstant = true; + if (! intermediate.addUsedConstantId(value)) + error(loc, "specialization-constant id already used", id.c_str(), ""); + } + if (nonLiteral) + error(loc, "needs a literal integer", "constant_id", ""); + return; + } +#ifndef GLSLANG_WEB + if (id == "component") { requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "component"); if ((unsigned)value >= TQualifier::layoutComponentEnd) error(loc, "component is too large", id.c_str(), ""); else publicType.qualifier.layoutComponent = value; + if (nonLiteral) + error(loc, "needs a literal integer", "component", ""); return; - } else if (id.compare(0, 4, "xfb_") == 0) { + } + if (id.compare(0, 4, "xfb_") == 0) { // "Any shader making any static use (after preprocessing) of any of these // *xfb_* qualifiers will cause the shader to be in a transform feedback // capturing mode and hence responsible for describing the transform feedback @@ -5012,12 +5748,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1); else publicType.qualifier.layoutXfbBuffer = value; + if (nonLiteral) + error(loc, "needs a literal integer", "xfb_buffer", ""); return; } else if (id == "xfb_offset") { if (value >= (int)TQualifier::layoutXfbOffsetEnd) error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1); else publicType.qualifier.layoutXfbOffset = value; + if (nonLiteral) + error(loc, "needs a literal integer", "xfb_offset", ""); return; } else if (id == "xfb_stride") { // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the @@ -5030,37 +5770,28 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1); else publicType.qualifier.layoutXfbStride = value; + if (nonLiteral) + error(loc, "needs a literal integer", "xfb_stride", ""); return; } } - if (id == "input_attachment_index") { requireVulkan(loc, "input_attachment_index"); if (value >= (int)TQualifier::layoutAttachmentEnd) error(loc, "attachment index is too large", id.c_str(), ""); else publicType.qualifier.layoutAttachment = value; - return; - } - if (id == "constant_id") { - requireSpv(loc, "constant_id"); - if (value >= (int)TQualifier::layoutSpecConstantIdEnd) { - error(loc, "specialization-constant id is too large", id.c_str(), ""); - } else { - publicType.qualifier.layoutSpecConstantId = value; - publicType.qualifier.specConstant = true; - if (! intermediate.addUsedConstantId(value)) - error(loc, "specialization-constant id already used", id.c_str(), ""); - } + if (nonLiteral) + error(loc, "needs a literal integer", "input_attachment_index", ""); return; } if (id == "num_views") { requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views"); publicType.shaderQualifiers.numViews = value; + if (nonLiteral) + error(loc, "needs a literal integer", "num_views", ""); return; } - -#if NV_EXTENSIONS if (language == EShLangVertex || language == EShLangTessControl || language == EShLangTessEvaluation || @@ -5068,37 +5799,38 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi if (id == "secondary_view_offset") { requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering"); publicType.qualifier.layoutSecondaryViewportRelativeOffset = value; + if (nonLiteral) + error(loc, "needs a literal integer", "secondary_view_offset", ""); return; } } -#endif if (id == "buffer_reference_align") { requireExtensions(loc, 1, &E_GL_EXT_buffer_reference, "buffer_reference_align"); if (! IsPow2(value)) error(loc, "must be a power of 2", "buffer_reference_align", ""); else - publicType.qualifier.layoutBufferReferenceAlign = (unsigned int)std::log2(value); + publicType.qualifier.layoutBufferReferenceAlign = IntLog2(value); + if (nonLiteral) + error(loc, "needs a literal integer", "buffer_reference_align", ""); return; } +#endif switch (language) { - case EShLangVertex: - break; - +#ifndef GLSLANG_WEB case EShLangTessControl: if (id == "vertices") { if (value == 0) error(loc, "must be greater than 0", "vertices", ""); else publicType.shaderQualifiers.vertices = value; + if (nonLiteral) + error(loc, "needs a literal integer", "vertices", ""); return; } break; - case EShLangTessEvaluation: - break; - case EShLangGeometry: if (id == "invocations") { profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, nullptr, "invocations"); @@ -5106,12 +5838,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "must be at least 1", "invocations", ""); else publicType.shaderQualifiers.invocations = value; + if (nonLiteral) + error(loc, "needs a literal integer", "invocations", ""); return; } if (id == "max_vertices") { publicType.shaderQualifiers.vertices = value; if (value > resources.maxGeometryOutputVertices) error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", ""); + if (nonLiteral) + error(loc, "needs a literal integer", "max_vertices", ""); return; } if (id == "stream") { @@ -5119,16 +5855,18 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.qualifier.layoutStream = value; if (value > 0) intermediate.setMultiStream(); + if (nonLiteral) + error(loc, "needs a literal integer", "stream", ""); return; } break; case EShLangFragment: if (id == "index") { - requireProfile(loc, ECompatibilityProfile | ECoreProfile, "index layout qualifier on fragment output"); + requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, "index layout qualifier on fragment output"); const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output"); - + profileRequires(loc, EEsProfile ,310, E_GL_EXT_blend_func_extended, "index layout qualifier on fragment output"); // "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1." if (value < 0 || value > 1) { value = 0; @@ -5136,17 +5874,20 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } publicType.qualifier.layoutIndex = value; + if (nonLiteral) + error(loc, "needs a literal integer", "index", ""); return; } break; -#ifdef NV_EXTENSIONS case EShLangMeshNV: if (id == "max_vertices") { requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_vertices"); publicType.shaderQualifiers.vertices = value; if (value > resources.maxMeshOutputVerticesNV) error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", ""); + if (nonLiteral) + error(loc, "needs a literal integer", "max_vertices", ""); return; } if (id == "max_primitives") { @@ -5154,6 +5895,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.shaderQualifiers.primitives = value; if (value > resources.maxMeshOutputPrimitivesNV) error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", ""); + if (nonLiteral) + error(loc, "needs a literal integer", "max_primitives", ""); return; } // Fall through @@ -5163,30 +5906,33 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi #endif case EShLangCompute: if (id.compare(0, 11, "local_size_") == 0) { -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB if (language == EShLangMeshNV || language == EShLangTaskNV) { requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "gl_WorkGroupSize"); - } - else -#endif - { + } else { profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize"); profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize"); } +#endif + if (nonLiteral) + error(loc, "needs a literal integer", "local_size", ""); if (id.size() == 12 && value == 0) { error(loc, "must be at least 1", id.c_str(), ""); return; } if (id == "local_size_x") { publicType.shaderQualifiers.localSize[0] = value; + publicType.shaderQualifiers.localSizeNotDefault[0] = true; return; } if (id == "local_size_y") { publicType.shaderQualifiers.localSize[1] = value; + publicType.shaderQualifiers.localSizeNotDefault[1] = true; return; } if (id == "local_size_z") { publicType.shaderQualifiers.localSize[2] = value; + publicType.shaderQualifiers.localSizeNotDefault[2] = true; return; } if (spvVersion.spv != 0) { @@ -5234,61 +5980,58 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie if (src.hasPacking()) dst.layoutPacking = src.layoutPacking; +#ifndef GLSLANG_WEB if (src.hasStream()) dst.layoutStream = src.layoutStream; - if (src.hasFormat()) dst.layoutFormat = src.layoutFormat; - if (src.hasXfbBuffer()) dst.layoutXfbBuffer = src.layoutXfbBuffer; + if (src.hasBufferReferenceAlign()) + dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign; +#endif if (src.hasAlign()) dst.layoutAlign = src.layoutAlign; - if (src.hasBufferReferenceAlign()) - dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign; - if (! inheritOnly) { if (src.hasLocation()) dst.layoutLocation = src.layoutLocation; - if (src.hasComponent()) - dst.layoutComponent = src.layoutComponent; - if (src.hasIndex()) - dst.layoutIndex = src.layoutIndex; - if (src.hasOffset()) dst.layoutOffset = src.layoutOffset; - if (src.hasSet()) dst.layoutSet = src.layoutSet; if (src.layoutBinding != TQualifier::layoutBindingEnd) dst.layoutBinding = src.layoutBinding; + if (src.hasSpecConstantId()) + dst.layoutSpecConstantId = src.layoutSpecConstantId; + +#ifndef GLSLANG_WEB + if (src.hasComponent()) + dst.layoutComponent = src.layoutComponent; + if (src.hasIndex()) + dst.layoutIndex = src.layoutIndex; if (src.hasXfbStride()) dst.layoutXfbStride = src.layoutXfbStride; if (src.hasXfbOffset()) dst.layoutXfbOffset = src.layoutXfbOffset; if (src.hasAttachment()) dst.layoutAttachment = src.layoutAttachment; - if (src.hasSpecConstantId()) - dst.layoutSpecConstantId = src.layoutSpecConstantId; - if (src.layoutPushConstant) dst.layoutPushConstant = true; if (src.layoutBufferReference) dst.layoutBufferReference = true; -#ifdef NV_EXTENSIONS if (src.layoutPassthrough) dst.layoutPassthrough = true; if (src.layoutViewportRelative) dst.layoutViewportRelative = true; if (src.layoutSecondaryViewportRelativeOffset != -2048) dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset; - if (src.layoutShaderRecordNV) - dst.layoutShaderRecordNV = true; + if (src.layoutShaderRecord) + dst.layoutShaderRecord = true; if (src.pervertexNV) dst.pervertexNV = true; #endif @@ -5328,6 +6071,9 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb case EvqVaryingIn: case EvqVaryingOut: if (!type.getQualifier().isTaskMemory() && +#ifndef GLSLANG_WEB + !type.getQualifier().hasSprivDecorate() && +#endif (type.getBasicType() != EbtBlock || (!(*type.getStruct())[0].type->getQualifier().hasLocation() && (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone))) @@ -5349,17 +6095,17 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb if (qualifier.hasPacking()) error(loc, "cannot specify packing on a variable declaration", "layout", ""); // "The offset qualifier can only be used on block members of blocks..." - if (qualifier.hasOffset() && type.getBasicType() != EbtAtomicUint) + if (qualifier.hasOffset() && !type.isAtomic()) error(loc, "cannot specify on a variable declaration", "offset", ""); // "The align qualifier can only be used on blocks or block members..." if (qualifier.hasAlign()) error(loc, "cannot specify on a variable declaration", "align", ""); - if (qualifier.layoutPushConstant) + if (qualifier.isPushConstant()) error(loc, "can only specify on a uniform block", "push_constant", ""); -#ifdef NV_EXTENSIONS - if (qualifier.layoutShaderRecordNV) + if (qualifier.isShaderRecord()) error(loc, "can only specify on a buffer block", "shaderRecordNV", ""); -#endif + if (qualifier.hasLocation() && type.isAtomic()) + error(loc, "cannot specify on atomic counter", "location", ""); } break; default: @@ -5389,6 +6135,11 @@ void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool m // Do layout error checking with respect to a type. void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) { +#ifndef GLSLANG_WEB + if (extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) + return; // Skip any check if GL_EXT_spirv_intrinsics is turned on +#endif + const TQualifier& qualifier = type.getQualifier(); // first, intra-layout qualifier-only error checking @@ -5423,22 +6174,20 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) case EvqVaryingOut: if (type.getBasicType() == EbtBlock) profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "location qualifier on in/out block"); -#ifdef NV_EXTENSIONS if (type.getQualifier().isTaskMemory()) error(loc, "cannot apply to taskNV in/out blocks", "location", ""); -#endif break; case EvqUniform: case EvqBuffer: if (type.getBasicType() == EbtBlock) error(loc, "cannot apply to uniform or buffer block", "location", ""); break; -#ifdef NV_EXTENSIONS - case EvqPayloadNV: - case EvqPayloadInNV: - case EvqHitAttrNV: - case EvqCallableDataNV: - case EvqCallableDataInNV: +#ifndef GLSLANG_WEB + case EvqPayload: + case EvqPayloadIn: + case EvqHitAttr: + case EvqCallableData: + case EvqCallableDataIn: break; #endif default: @@ -5456,10 +6205,13 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) error(loc, "fragment outputs sharing the same location must be the same basic type", "location", "%d", repeated); } +#ifndef GLSLANG_WEB if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) { int repeated = intermediate.addXfbBufferOffset(type); if (repeated >= 0) error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer); + if (type.isUnsizedArray()) + error(loc, "unsized array", "xfb_offset", "in buffer %d", qualifier.layoutXfbBuffer); // "The offset must be a multiple of the size of the first component of the first // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate @@ -5467,25 +6219,20 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) if ((type.containsBasicType(EbtDouble) || type.containsBasicType(EbtInt64) || type.containsBasicType(EbtUint64)) && ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8)) error(loc, "type contains double or 64-bit integer; xfb_offset must be a multiple of 8", "xfb_offset", ""); -#ifdef AMD_EXTENSIONS else if ((type.containsBasicType(EbtBool) || type.containsBasicType(EbtFloat) || type.containsBasicType(EbtInt) || type.containsBasicType(EbtUint)) && ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4)) error(loc, "must be a multiple of size of first component", "xfb_offset", ""); // ..., if applied to an aggregate containing a half float or 16-bit integer, the offset must also be a multiple of 2..." - else if ((type.containsBasicType(EbtFloat16) || type.containsBasicType(EbtInt16) || type.containsBasicType(EbtUint16)) && + else if ((type.contains16BitFloat() || type.containsBasicType(EbtInt16) || type.containsBasicType(EbtUint16)) && !IsMultipleOfPow2(qualifier.layoutXfbOffset, 2)) error(loc, "type contains half float or 16-bit integer; xfb_offset must be a multiple of 2", "xfb_offset", ""); -#else - else if (! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4)) - error(loc, "must be a multiple of size of first component", "xfb_offset", ""); -#endif } - if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) { if (! intermediate.setXfbBufferStride(qualifier.layoutXfbBuffer, qualifier.layoutXfbStride)) error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer); } +#endif if (qualifier.hasBinding()) { // Binding checking, from the spec: @@ -5501,22 +6248,22 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) if (type.getBasicType() == EbtSampler) { int lastBinding = qualifier.layoutBinding; if (type.isArray()) { - if (spvVersion.vulkan > 0) - lastBinding += 1; - else { + if (spvVersion.vulkan == 0) { if (type.isSizedArray()) - lastBinding += type.getCumulativeArraySize(); + lastBinding += (type.getCumulativeArraySize() - 1); else { - lastBinding += 1; - if (spvVersion.vulkan == 0) - warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", ""); +#ifndef GLSLANG_WEB + warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", ""); +#endif } } } +#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits) error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : ""); +#endif } - if (type.getBasicType() == EbtAtomicUint) { + if (type.isAtomic() && !spvVersion.vulkanRelaxed) { if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { error(loc, "atomic_uint binding is too large; see gl_MaxAtomicCounterBindings", "binding", ""); return; @@ -5526,18 +6273,16 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // some types require bindings // atomic_uint - if (type.getBasicType() == EbtAtomicUint) + if (type.isAtomic()) error(loc, "layout(binding=X) is required", "atomic_uint", ""); // SPIR-V if (spvVersion.spv > 0) { if (qualifier.isUniformOrBuffer()) { - if (type.getBasicType() == EbtBlock && !qualifier.layoutPushConstant && -#ifdef NV_EXTENSIONS - !qualifier.layoutShaderRecordNV && -#endif - !qualifier.layoutAttachment && - !qualifier.layoutBufferReference) + if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() && + !qualifier.isShaderRecord() && + !qualifier.hasAttachment() && + !qualifier.hasBufferReference()) error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", ""); else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler) error(loc, "sampler/texture/image requires layout(binding=X)", "binding", ""); @@ -5562,40 +6307,38 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // Image format if (qualifier.hasFormat()) { if (! type.isImage()) - error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); else { - if (type.getSampler().type == EbtFloat && qualifier.layoutFormat > ElfFloatGuard) - error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); - if (type.getSampler().type == EbtInt && (qualifier.layoutFormat < ElfFloatGuard || qualifier.layoutFormat > ElfIntGuard)) - error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); - if (type.getSampler().type == EbtUint && qualifier.layoutFormat < ElfIntGuard) - error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + if (type.getSampler().type == EbtFloat && qualifier.getFormat() > ElfFloatGuard) + error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); + if (type.getSampler().type == EbtInt && (qualifier.getFormat() < ElfFloatGuard || qualifier.getFormat() > ElfIntGuard)) + error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); + if (type.getSampler().type == EbtUint && qualifier.getFormat() < ElfIntGuard) + error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); - if (profile == EEsProfile) { + if (isEsProfile()) { // "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must // specify either memory qualifier readonly or the memory qualifier writeonly." - if (! (qualifier.layoutFormat == ElfR32f || qualifier.layoutFormat == ElfR32i || qualifier.layoutFormat == ElfR32ui)) { - if (! qualifier.readonly && ! qualifier.writeonly) - error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + if (! (qualifier.getFormat() == ElfR32f || qualifier.getFormat() == ElfR32i || qualifier.getFormat() == ElfR32ui)) { + if (! qualifier.isReadOnly() && ! qualifier.isWriteOnly()) + error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); } } } - } else if (type.isImage() && ! qualifier.writeonly) { + } else if (type.isImage() && ! qualifier.isWriteOnly()) { const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier"; requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation); } - if (qualifier.layoutPushConstant && type.getBasicType() != EbtBlock) + if (qualifier.isPushConstant() && type.getBasicType() != EbtBlock) error(loc, "can only be used with a block", "push_constant", ""); - if (qualifier.layoutBufferReference && type.getBasicType() != EbtBlock) + if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock) error(loc, "can only be used with a block", "buffer_reference", ""); -#ifdef NV_EXTENSIONS - if (qualifier.layoutShaderRecordNV && type.getBasicType() != EbtBlock) + if (qualifier.isShaderRecord() && type.getBasicType() != EbtBlock) error(loc, "can only be used with a block", "shaderRecordNV", ""); -#endif // input attachment if (type.isSubpass()) { @@ -5634,12 +6377,28 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) } } +static bool storageCanHaveLayoutInBlock(const enum TStorageQualifier storage) +{ + switch (storage) { + case EvqUniform: + case EvqBuffer: + case EvqShared: + return true; + default: + return false; + } +} + // Do layout error checking that can be done within a layout qualifier proper, not needing to know // if there are blocks, atomic counters, variables, etc. void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier) { - if (qualifier.storage == EvqShared && qualifier.hasLayout()) - error(loc, "cannot apply layout qualifiers to a shared variable", "shared", ""); + if (qualifier.storage == EvqShared && qualifier.hasLayout()) { + if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_4) { + error(loc, "shared block requires at least SPIR-V 1.4", "shared block", ""); + } + profileRequires(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shared_memory_block, "shared block"); + } // "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)." if (qualifier.hasComponent() && ! qualifier.hasLocation()) @@ -5652,10 +6411,11 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier // output block declarations, and output block member declarations." switch (qualifier.storage) { +#ifndef GLSLANG_WEB case EvqVaryingIn: { const char* feature = "location qualifier on input"; - if (profile == EEsProfile && version < 310) + if (isEsProfile() && version < 310) requireStage(loc, EShLangVertex, feature); else requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature); @@ -5672,7 +6432,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier case EvqVaryingOut: { const char* feature = "location qualifier on output"; - if (profile == EEsProfile && version < 310) + if (isEsProfile() && version < 310) requireStage(loc, EShLangFragment, feature); else requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature); @@ -5686,12 +6446,14 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier } break; } +#endif case EvqUniform: case EvqBuffer: { const char* feature = "location qualifier on uniform or buffer"; - requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature); + requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile | ENoProfile, feature); + profileRequires(loc, ~EEsProfile, 330, E_GL_ARB_explicit_attrib_location, feature); + profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_explicit_uniform_location, feature); profileRequires(loc, EEsProfile, 310, nullptr, feature); break; } @@ -5719,25 +6481,24 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier error(loc, "can only be used on an output", "xfb layout qualifier", ""); } if (qualifier.hasUniformLayout()) { - if (! qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory()) { + if (!storageCanHaveLayoutInBlock(qualifier.storage) && !qualifier.isTaskMemory()) { if (qualifier.hasMatrix() || qualifier.hasPacking()) error(loc, "matrix or packing qualifiers can only be used on a uniform or buffer", "layout", ""); if (qualifier.hasOffset() || qualifier.hasAlign()) error(loc, "offset/align can only be used on a uniform or buffer", "layout", ""); } } - if (qualifier.layoutPushConstant) { + if (qualifier.isPushConstant()) { if (qualifier.storage != EvqUniform) error(loc, "can only be used with a uniform", "push_constant", ""); if (qualifier.hasSet()) error(loc, "cannot be used with push_constant", "set", ""); } - if (qualifier.layoutBufferReference) { + if (qualifier.hasBufferReference()) { if (qualifier.storage != EvqBuffer) error(loc, "can only be used with buffer", "buffer_reference", ""); } -#ifdef NV_EXTENSIONS - if (qualifier.layoutShaderRecordNV) { + if (qualifier.isShaderRecord()) { if (qualifier.storage != EvqBuffer) error(loc, "can only be used with a buffer", "shaderRecordNV", ""); if (qualifier.hasBinding()) @@ -5746,15 +6507,15 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier error(loc, "cannot be used with shaderRecordNV", "set", ""); } - if (qualifier.storage == EvqHitAttrNV && qualifier.hasLayout()) { + if (qualifier.storage == EvqHitAttr && qualifier.hasLayout()) { error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", ""); } -#endif } // For places that can't have shader-level layout qualifiers void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQualifiers& shaderQualifiers) { +#ifndef GLSLANG_WEB const char* message = "can only apply to a standalone qualifier"; if (shaderQualifiers.geometry != ElgNone) @@ -5767,10 +6528,6 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, "point_mode", ""); if (shaderQualifiers.invocations != TQualifier::layoutNotSet) error(loc, message, "invocations", ""); - if (shaderQualifiers.earlyFragmentTests) - error(loc, message, "early_fragment_tests", ""); - if (shaderQualifiers.postDepthCoverage) - error(loc, message, "post_depth_coverage", ""); for (int i = 0; i < 3; ++i) { if (shaderQualifiers.localSize[i] > 1) error(loc, message, "local_size", ""); @@ -5778,36 +6535,40 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, "local_size id", ""); } if (shaderQualifiers.vertices != TQualifier::layoutNotSet) { - if (language == EShLangGeometry -#ifdef NV_EXTENSIONS - || language == EShLangMeshNV -#endif - ) + if (language == EShLangGeometry || language == EShLangMeshNV) error(loc, message, "max_vertices", ""); else if (language == EShLangTessControl) error(loc, message, "vertices", ""); else assert(0); } -#ifdef NV_EXTENSIONS + if (shaderQualifiers.earlyFragmentTests) + error(loc, message, "early_fragment_tests", ""); + if (shaderQualifiers.postDepthCoverage) + error(loc, message, "post_depth_coverage", ""); if (shaderQualifiers.primitives != TQualifier::layoutNotSet) { if (language == EShLangMeshNV) error(loc, message, "max_primitives", ""); else assert(0); } -#endif - if (shaderQualifiers.blendEquation) + if (shaderQualifiers.hasBlendEquation()) error(loc, message, "blend equation", ""); if (shaderQualifiers.numViews != TQualifier::layoutNotSet) error(loc, message, "num_views", ""); + if (shaderQualifiers.interlockOrdering != EioNone) + error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), ""); + if (shaderQualifiers.layoutPrimitiveCulling) + error(loc, "can only be applied as standalone", "primitive_culling", ""); +#endif } // Correct and/or advance an object's offset layout qualifier. void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) { const TQualifier& qualifier = symbol.getType().getQualifier(); - if (symbol.getType().getBasicType() == EbtAtomicUint) { +#ifndef GLSLANG_WEB + if (symbol.getType().isAtomic()) { if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) { // Set the offset @@ -5816,6 +6577,10 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) offset = qualifier.layoutOffset; else offset = atomicUintOffsets[qualifier.layoutBinding]; + + if (offset % 4 != 0) + error(loc, "atomic counters offset should align based on 4:", "offset", "%d", offset); + symbol.getWritableType().getQualifier().layoutOffset = offset; // Check for overlap @@ -5836,6 +6601,7 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) atomicUintOffsets[qualifier.layoutBinding] = offset + numOffsets; } } +#endif } // @@ -5845,13 +6611,25 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) // const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn) { - const TFunction* function = nullptr; - if (symbolTable.isFunctionNameVariable(call.getName())) { error(loc, "can't use function syntax on variable", call.getName().c_str(), ""); return nullptr; } +#ifdef GLSLANG_WEB + return findFunctionExact(loc, call, builtIn); +#endif + + const TFunction* function = nullptr; + + // debugPrintfEXT has var args and is in the symbol table as "debugPrintfEXT()", + // mangled to "debugPrintfEXT(" + if (call.getName() == "debugPrintfEXT") { + TSymbol* symbol = symbolTable.find("debugPrintfEXT(", &builtIn); + if (symbol) + return symbol->getAsFunction(); + } + bool explicitTypesEnabled = extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8) || extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16) || @@ -5861,10 +6639,16 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32) || extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64); - if (profile == EEsProfile || version < 120) + if (isEsProfile()) + function = (explicitTypesEnabled && version >= 310) + ? findFunctionExplicitTypes(loc, call, builtIn) + : ((extensionTurnedOn(E_GL_EXT_shader_implicit_conversions) && version >= 310) + ? findFunction120(loc, call, builtIn) + : findFunctionExact(loc, call, builtIn)); + else if (version < 120) function = findFunctionExact(loc, call, builtIn); else if (version < 400) - function = findFunction120(loc, call, builtIn); + function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn); else if (explicitTypesEnabled) function = findFunctionExplicitTypes(loc, call, builtIn); else @@ -6009,11 +6793,22 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); // can 'from' convert to 'to'? - const auto convertible = [this](const TType& from, const TType& to, TOperator, int) -> bool { + const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool { if (from == to) return true; + if (from.coopMatParameterOK(to)) + return true; + // Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions + if (builtIn && from.isArray() && to.isUnsizedArray()) { + TType fromElementType(from, 0); + TType toElementType(to, 0); + if (fromElementType == toElementType) + return true; + } if (from.isArray() || to.isArray() || ! from.sameElementShape(to)) return false; + if (from.isCoopMat() && to.isCoopMat()) + return from.sameCoopMatBaseType(to); return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType()); }; @@ -6074,11 +6869,22 @@ const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc, symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); // can 'from' convert to 'to'? - const auto convertible = [this](const TType& from, const TType& to, TOperator, int) -> bool { + const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool { if (from == to) return true; + if (from.coopMatParameterOK(to)) + return true; + // Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions + if (builtIn && from.isArray() && to.isUnsizedArray()) { + TType fromElementType(from, 0); + TType toElementType(to, 0); + if (fromElementType == toElementType) + return true; + } if (from.isArray() || to.isArray() || ! from.sameElementShape(to)) return false; + if (from.isCoopMat() && to.isCoopMat()) + return from.sameCoopMatBaseType(to); return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType()); }; @@ -6130,21 +6936,175 @@ const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc, return bestMatch; } -// When a declaration includes a type, but not a variable name, it can be +// +// Adjust function calls that aren't declared in Vulkan to a +// calls with equivalent effects +// +TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments) +{ + TIntermTyped* result = nullptr; + +#ifndef GLSLANG_WEB + if (function->getBuiltInOp() != EOpNull) { + return nullptr; + } + + if (function->getName() == "atomicCounterIncrement") { + // change atomicCounterIncrement into an atomicAdd of 1 + TString name("atomicAdd"); + TType uintType(EbtUint); + + TFunction realFunc(&name, function->getType()); + + for (int i = 0; i < function->getParamCount(); ++i) { + realFunc.addParameter((*function)[i]); + } + + TParameter tmpP = { 0, &uintType }; + realFunc.addParameter(tmpP); + arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(1, loc, true)); + + result = handleFunctionCall(loc, &realFunc, arguments); + } else if (function->getName() == "atomicCounterDecrement") { + // change atomicCounterDecrement into an atomicAdd with -1 + // and subtract 1 from result, to return post-decrement value + TString name("atomicAdd"); + TType uintType(EbtUint); + + TFunction realFunc(&name, function->getType()); + + for (int i = 0; i < function->getParamCount(); ++i) { + realFunc.addParameter((*function)[i]); + } + + TParameter tmpP = { 0, &uintType }; + realFunc.addParameter(tmpP); + arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(-1, loc, true)); + + result = handleFunctionCall(loc, &realFunc, arguments); + + // post decrement, so that it matches AtomicCounterDecrement semantics + if (result) { + result = handleBinaryMath(loc, "-", EOpSub, result, intermediate.addConstantUnion(1, loc, true)); + } + } else if (function->getName() == "atomicCounter") { + // change atomicCounter into a direct read of the variable + if (arguments->getAsTyped()) { + result = arguments->getAsTyped(); + } + } +#endif + + return result; +} + +// When a declaration includes a type, but not a variable name, it can be used // to establish defaults. void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType) { - if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding() && publicType.qualifier.hasOffset()) { +#ifndef GLSLANG_WEB + if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding()) { if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { error(loc, "atomic_uint binding is too large", "binding", ""); return; } - atomicUintOffsets[publicType.qualifier.layoutBinding] = publicType.qualifier.layoutOffset; + if (publicType.qualifier.hasOffset()) + atomicUintOffsets[publicType.qualifier.layoutBinding] = publicType.qualifier.layoutOffset; return; } - if (publicType.qualifier.hasLayout() && !publicType.qualifier.layoutBufferReference) + if (publicType.arraySizes) { + error(loc, "expect an array name", "", ""); + } + + if (publicType.qualifier.hasLayout() && !publicType.qualifier.hasBufferReference()) warn(loc, "useless application of layout qualifier", "layout", ""); +#endif +} + +bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType&, + TArraySizes*, TIntermTyped* initializer, TType& type) +{ + if (parsingBuiltins || symbolTable.atBuiltInLevel() || !symbolTable.atGlobalLevel() || + type.getQualifier().storage != EvqUniform || + !(type.containsNonOpaque() +#ifndef GLSLANG_WEB + || type.getBasicType() == EbtAtomicUint +#endif + )) { + return false; + } + + if (type.getQualifier().hasLocation()) { + warn(loc, "ignoring layout qualifier for uniform", identifier.c_str(), "location"); + type.getQualifier().layoutLocation = TQualifier::layoutLocationEnd; + } + + if (initializer) { + warn(loc, "Ignoring initializer for uniform", identifier.c_str(), ""); + initializer = nullptr; + } + + if (type.isArray()) { + // do array size checks here + arraySizesCheck(loc, type.getQualifier(), type.getArraySizes(), initializer, false); + + if (arrayQualifierError(loc, type.getQualifier()) || arrayError(loc, type)) { + error(loc, "array param error", identifier.c_str(), ""); + } + } + + // do some checking on the type as it was declared + layoutTypeCheck(loc, type); + + int bufferBinding = TQualifier::layoutBindingEnd; + TVariable* updatedBlock = nullptr; + +#ifndef GLSLANG_WEB + // Convert atomic_uint into members of a buffer block + if (type.isAtomic()) { + type.setBasicType(EbtUint); + type.getQualifier().storage = EvqBuffer; + + type.getQualifier().volatil = true; + type.getQualifier().coherent = true; + + // xxTODO: use logic from fixOffset() to apply explicit member offset + bufferBinding = type.getQualifier().layoutBinding; + type.getQualifier().layoutBinding = TQualifier::layoutBindingEnd; + type.getQualifier().explicitOffset = false; + growAtomicCounterBlock(bufferBinding, loc, type, identifier, nullptr); + updatedBlock = atomicCounterBuffers[bufferBinding]; + } +#endif + + if (!updatedBlock) { + growGlobalUniformBlock(loc, type, identifier, nullptr); + updatedBlock = globalUniformBlock; + } + + // + // don't assign explicit member offsets here + // if any are assigned, need to be updated here and in the merge/link step + // fixBlockUniformOffsets(updatedBlock->getWritableType().getQualifier(), *updatedBlock->getWritableType().getWritableStruct()); + + // checks on update buffer object + layoutObjectCheck(loc, *updatedBlock); + + TSymbol* symbol = symbolTable.find(identifier); + + if (!symbol) { + if (updatedBlock == globalUniformBlock) + error(loc, "error adding uniform to default uniform block", identifier.c_str(), ""); + else + error(loc, "error adding atomic counter to atomic counter block", identifier.c_str(), ""); + return false; + } + + // merge qualifiers + mergeObjectLayoutQualifiers(updatedBlock->getWritableType().getQualifier(), type.getQualifier(), true); + + return true; } // @@ -6168,6 +7128,39 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden type.copyArrayInnerSizes(publicType.arraySizes); arrayOfArrayVersionCheck(loc, type.getArraySizes()); + if (initializer) { + if (type.getBasicType() == EbtRayQuery) { + error(loc, "ray queries can only be initialized by using the rayQueryInitializeEXT intrinsic:", "=", identifier.c_str()); + } + } + + if (type.isCoopMat()) { + intermediate.setUseVulkanMemoryModel(); + intermediate.setUseStorageBuffer(); + + if (!publicType.typeParameters || publicType.typeParameters->getNumDims() != 4) { + error(loc, "expected four type parameters", identifier.c_str(), ""); + } + if (publicType.typeParameters) { + if (isTypeFloat(publicType.basicType) && + publicType.typeParameters->getDimSize(0) != 16 && + publicType.typeParameters->getDimSize(0) != 32 && + publicType.typeParameters->getDimSize(0) != 64) { + error(loc, "expected 16, 32, or 64 bits for first type parameter", identifier.c_str(), ""); + } + if (isTypeInt(publicType.basicType) && + publicType.typeParameters->getDimSize(0) != 8 && + publicType.typeParameters->getDimSize(0) != 32) { + error(loc, "expected 8 or 32 bits for first type parameter", identifier.c_str(), ""); + } + } + + } else { + if (publicType.typeParameters && publicType.typeParameters->getNumDims() != 0) { + error(loc, "unexpected type parameters", identifier.c_str(), ""); + } + } + if (voidErrorCheck(loc, identifier, type.getBasicType())) return nullptr; @@ -6177,14 +7170,18 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden nonInitConstCheck(loc, identifier, type); samplerCheck(loc, type, identifier, initializer); - atomicUintCheck(loc, type, identifier); transparentOpaqueCheck(loc, type, identifier); -#ifdef NV_EXTENSIONS - accStructNVCheck(loc, type, identifier); +#ifndef GLSLANG_WEB + atomicUintCheck(loc, type, identifier); + accStructCheck(loc, type, identifier); + checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false); #endif + if (type.getQualifier().storage == EvqConst && type.containsReference()) { + error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", ""); + } if (type.getQualifier().storage != EvqUniform && type.getQualifier().storage != EvqBuffer) { - if (type.containsBasicType(EbtFloat16)) + if (type.contains16BitFloat()) requireFloat16Arithmetic(loc, "qualifier", "float16 types can only be in uniform block or buffer storage"); if (type.contains16BitInt()) requireInt16Arithmetic(loc, "qualifier", "(u)int16 types can only be in uniform block or buffer storage"); @@ -6192,9 +7189,28 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden requireInt8Arithmetic(loc, "qualifier", "(u)int8 types can only be in uniform block or buffer storage"); } + if (type.getQualifier().storage == EvqShared && type.containsCoopMat()) + error(loc, "qualifier", "Cooperative matrix types must not be used in shared memory", ""); + + if (profile == EEsProfile) { + if (type.getQualifier().isPipeInput() && type.getBasicType() == EbtStruct) { + if (type.getQualifier().isArrayedIo(language)) { + TType perVertexType(type, 0); + if (perVertexType.containsArray() && perVertexType.containsBuiltIn() == false) { + error(loc, "A per vertex structure containing an array is not allowed as input in ES", type.getTypeName().c_str(), ""); + } + } + else if (type.containsArray() && type.containsBuiltIn() == false) { + error(loc, "A structure containing an array is not allowed as input in ES", type.getTypeName().c_str(), ""); + } + if (type.containsStructure()) + error(loc, "A structure containing an struct is not allowed as input in ES", type.getTypeName().c_str(), ""); + } + } + if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger)) error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", ""); - if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.layoutDepth != EldNone) + if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.getDepth() != EldNone) error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", ""); // Check for redeclaration of built-ins and/or attempting to declare a reserved name @@ -6202,6 +7218,14 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden if (symbol == nullptr) reservedErrorCheck(loc, identifier); + if (symbol == nullptr && spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) { + bool remapped = vkRelaxedRemapUniformVariable(loc, identifier, publicType, arraySizes, initializer, type); + + if (remapped) { + return nullptr; + } + } + inheritGlobalDefaults(type.getQualifier()); // Declare the variable @@ -6250,12 +7274,14 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden // Pick up global defaults from the provide global defaults into dst. void TParseContext::inheritGlobalDefaults(TQualifier& dst) const { +#ifndef GLSLANG_WEB if (dst.storage == EvqVaryingOut) { if (! dst.hasStream() && language == EShLangGeometry) dst.layoutStream = globalOutputDefaults.layoutStream; if (! dst.hasXfbBuffer()) dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; } +#endif } // @@ -6284,7 +7310,9 @@ TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& // make a new variable TVariable* variable = new TVariable(&identifier, type); +#ifndef GLSLANG_WEB ioArrayCheck(loc, type, identifier); +#endif // add variable to symbol table if (symbolTable.insert(*variable)) { @@ -6305,16 +7333,48 @@ TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& // TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable) { + // A null initializer is an aggregate that hasn't had an op assigned yet + // (still EOpNull, no relation to nullInit), and has no children. + bool nullInit = initializer->getAsAggregate() && initializer->getAsAggregate()->getOp() == EOpNull && + initializer->getAsAggregate()->getSequence().size() == 0; + // // Identifier must be of type constant, a global, or a temporary, and // starting at version 120, desktop allows uniforms to have initializers. // TStorageQualifier qualifier = variable->getType().getQualifier().storage; if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst || - (qualifier == EvqUniform && profile != EEsProfile && version >= 120))) { - error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), ""); + (qualifier == EvqUniform && !isEsProfile() && version >= 120))) { + if (qualifier == EvqShared) { + // GL_EXT_null_initializer allows this for shared, if it's a null initializer + if (nullInit) { + const char* feature = "initialization with shared qualifier"; + profileRequires(loc, EEsProfile, 0, E_GL_EXT_null_initializer, feature); + profileRequires(loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, feature); + } else { + error(loc, "initializer can only be a null initializer ('{}')", "shared", ""); + } + } else { + error(loc, " cannot initialize this type of qualifier ", + variable->getType().getStorageQualifierString(), ""); + return nullptr; + } + } + + if (nullInit) { + // only some types can be null initialized + if (variable->getType().containsUnsizedArray()) { + error(loc, "null initializers can't size unsized arrays", "{}", ""); + return nullptr; + } + if (variable->getType().containsOpaque()) { + error(loc, "null initializers can't be used on opaque values", "{}", ""); + return nullptr; + } + variable->getWritableType().getQualifier().setNullInit(); return nullptr; } + arrayObjectCheck(loc, variable->getType(), "array initializer"); // @@ -6329,7 +7389,9 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp TType skeletalType; skeletalType.shallowCopy(variable->getType()); skeletalType.getQualifier().makeTemporary(); +#ifndef GLSLANG_WEB initializer = convertInitializerList(loc, skeletalType, initializer); +#endif if (! initializer) { // error recovery; don't leave const without constant values if (qualifier == EvqConst) @@ -6356,13 +7418,15 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp // Uniforms require a compile-time constant initializer if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) { - error(loc, "uniform initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str()); + error(loc, "uniform initializers must be constant", "=", "'%s'", + variable->getType().getCompleteString().c_str()); variable->getWritableType().getQualifier().makeTemporary(); return nullptr; } // Global consts require a constant initializer (specialization constant is okay) if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) { - error(loc, "global const initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str()); + error(loc, "global const initializers must be constant", "=", "'%s'", + variable->getType().getCompleteString().c_str()); variable->getWritableType().getQualifier().makeTemporary(); return nullptr; } @@ -6382,8 +7446,9 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp // "In declarations of global variables with no storage qualifier or with a const // qualifier any initializer must be a constant expression." if (symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) { - const char* initFeature = "non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)"; - if (profile == EEsProfile) { + const char* initFeature = + "non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)"; + if (isEsProfile()) { if (relaxedErrors() && ! extensionTurnedOn(E_GL_EXT_shader_non_constant_global_initializers)) warn(loc, "not allowed in this version", initFeature, ""); else @@ -6396,7 +7461,8 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp // Compile-time tagging of the variable with its constant value... initializer = intermediate.addConversion(EOpAssign, variable->getType(), initializer); - if (! initializer || ! initializer->getType().getQualifier().isConstant() || variable->getType() != initializer->getType()) { + if (! initializer || ! initializer->getType().getQualifier().isConstant() || + variable->getType() != initializer->getType()) { error(loc, "non-matching or non-convertible constant type for const initializer", variable->getType().getStorageQualifierString(), ""); variable->getWritableType().getQualifier().makeTemporary(); @@ -6508,6 +7574,15 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str()); return nullptr; } + TBasicType destType = type.getBasicType(); + for (int i = 0; i < type.getVectorSize(); ++i) { + TBasicType initType = initList->getSequence()[i]->getAsTyped()->getBasicType(); + if (destType != initType && !intermediate.canImplicitlyPromote(initType, destType)) { + error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString().c_str()); + return nullptr; + } + + } } else { error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str()); return nullptr; @@ -6634,7 +7709,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T // This avoids requesting a matrix of a new type that is going to be discarded anyway. // TODO: This could be generalized to more type combinations, but that would require // more extensive testing and full algorithm rework. For now, the need to do two changes makes - // the recursive call work, and avoids the most aggregious case of creating integer matrices. + // the recursive call work, and avoids the most egregious case of creating integer matrices. if (node->getType().isMatrix() && (type.isScalar() || type.isVector()) && type.isFloatingDomain() != node->getType().isFloatingDomain()) { TType transitionType(node->getBasicType(), glslang::EvqTemporary, type.getVectorSize(), 0, 0, node->isVector()); @@ -6665,6 +7740,35 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T basicOp = EOpConstructFloat; break; + case EOpConstructIVec2: + case EOpConstructIVec3: + case EOpConstructIVec4: + case EOpConstructInt: + basicOp = EOpConstructInt; + break; + + case EOpConstructUVec2: + if (node->getType().getBasicType() == EbtReference) { + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference_uvec2, "reference conversion to uvec2"); + TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUvec2, true, node, + type); + return newNode; + } + case EOpConstructUVec3: + case EOpConstructUVec4: + case EOpConstructUint: + basicOp = EOpConstructUint; + break; + + case EOpConstructBVec2: + case EOpConstructBVec3: + case EOpConstructBVec4: + case EOpConstructBool: + basicOp = EOpConstructBool; + break; + +#ifndef GLSLANG_WEB + case EOpConstructDVec2: case EOpConstructDVec3: case EOpConstructDVec4: @@ -6695,6 +7799,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructF16Mat4x4: case EOpConstructFloat16: basicOp = EOpConstructFloat16; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticFloat16Enabled()) { + TType tempType(EbtFloat, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructFloat16) + aggregateOp = EOpConstructFloat; + else + aggregateOp = (TOperator)(EOpConstructVec2 + op - EOpConstructF16Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtFloat16, newNode); + return newNode; + } break; case EOpConstructI8Vec2: @@ -6702,6 +7822,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructI8Vec4: case EOpConstructInt8: basicOp = EOpConstructInt8; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticInt8Enabled()) { + TType tempType(EbtInt, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructInt8) + aggregateOp = EOpConstructInt; + else + aggregateOp = (TOperator)(EOpConstructIVec2 + op - EOpConstructI8Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtInt8, newNode); + return newNode; + } break; case EOpConstructU8Vec2: @@ -6709,6 +7845,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructU8Vec4: case EOpConstructUint8: basicOp = EOpConstructUint8; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticInt8Enabled()) { + TType tempType(EbtUint, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructUint8) + aggregateOp = EOpConstructUint; + else + aggregateOp = (TOperator)(EOpConstructUVec2 + op - EOpConstructU8Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtUint8, newNode); + return newNode; + } break; case EOpConstructI16Vec2: @@ -6716,6 +7868,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructI16Vec4: case EOpConstructInt16: basicOp = EOpConstructInt16; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticInt16Enabled()) { + TType tempType(EbtInt, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructInt16) + aggregateOp = EOpConstructInt; + else + aggregateOp = (TOperator)(EOpConstructIVec2 + op - EOpConstructI16Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtInt16, newNode); + return newNode; + } break; case EOpConstructU16Vec2: @@ -6723,20 +7891,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructU16Vec4: case EOpConstructUint16: basicOp = EOpConstructUint16; - break; - - case EOpConstructIVec2: - case EOpConstructIVec3: - case EOpConstructIVec4: - case EOpConstructInt: - basicOp = EOpConstructInt; - break; - - case EOpConstructUVec2: - case EOpConstructUVec3: - case EOpConstructUVec4: - case EOpConstructUint: - basicOp = EOpConstructUint; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticInt16Enabled()) { + TType tempType(EbtUint, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructUint16) + aggregateOp = EOpConstructUint; + else + aggregateOp = (TOperator)(EOpConstructUVec2 + op - EOpConstructU16Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtUint16, newNode); + return newNode; + } break; case EOpConstructI64Vec2: @@ -6747,8 +7917,8 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T break; case EOpConstructUint64: - if (type.isScalar() && node->getType().getBasicType() == EbtReference) { - TIntermUnary* newNode = intermediate.addUnaryNode(EOpConvPtrToUint64, node, node->getLoc(), type); + if (type.isScalar() && node->getType().isReference()) { + TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUint64, true, node, type); return newNode; } // fall through @@ -6758,31 +7928,132 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T basicOp = EOpConstructUint64; break; - case EOpConstructBVec2: - case EOpConstructBVec3: - case EOpConstructBVec4: - case EOpConstructBool: - basicOp = EOpConstructBool; - break; - case EOpConstructNonuniform: - node->getWritableType().getQualifier().nonUniform = true; - return node; - break; + // Make a nonuniform copy of node + newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpCopyObject, true, node, type); + return newNode; case EOpConstructReference: // construct reference from reference - if (node->getType().getBasicType() == EbtReference) { - newNode = intermediate.addUnaryNode(EOpConstructReference, node, node->getLoc(), type); + if (node->getType().isReference()) { + newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConstructReference, true, node, type); return newNode; // construct reference from uint64 } else if (node->getType().isScalar() && node->getType().getBasicType() == EbtUint64) { - TIntermUnary* newNode = intermediate.addUnaryNode(EOpConvUint64ToPtr, node, node->getLoc(), type); + TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUint64ToPtr, true, node, + type); + return newNode; + // construct reference from uvec2 + } else if (node->getType().isVector() && node->getType().getBasicType() == EbtUint && + node->getVectorSize() == 2) { + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference_uvec2, "uvec2 conversion to reference"); + TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUvec2ToPtr, true, node, + type); return newNode; } else { return nullptr; } + case EOpConstructCooperativeMatrix: + if (!node->getType().isCoopMat()) { + if (type.getBasicType() != node->getType().getBasicType()) { + node = intermediate.addConversion(type.getBasicType(), node); + if (node == nullptr) + return nullptr; + } + node = intermediate.setAggregateOperator(node, EOpConstructCooperativeMatrix, type, node->getLoc()); + } else { + TOperator op = EOpNull; + switch (type.getBasicType()) { + default: + assert(0); + break; + case EbtInt: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToInt; break; + case EbtFloat16: op = EOpConvFloat16ToInt; break; + case EbtUint8: op = EOpConvUint8ToInt; break; + case EbtInt8: op = EOpConvInt8ToInt; break; + case EbtUint: op = EOpConvUintToInt; break; + default: assert(0); + } + break; + case EbtUint: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToUint; break; + case EbtFloat16: op = EOpConvFloat16ToUint; break; + case EbtUint8: op = EOpConvUint8ToUint; break; + case EbtInt8: op = EOpConvInt8ToUint; break; + case EbtInt: op = EOpConvIntToUint; break; + case EbtUint: op = EOpConvUintToInt8; break; + default: assert(0); + } + break; + case EbtInt8: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToInt8; break; + case EbtFloat16: op = EOpConvFloat16ToInt8; break; + case EbtUint8: op = EOpConvUint8ToInt8; break; + case EbtInt: op = EOpConvIntToInt8; break; + case EbtUint: op = EOpConvUintToInt8; break; + default: assert(0); + } + break; + case EbtUint8: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToUint8; break; + case EbtFloat16: op = EOpConvFloat16ToUint8; break; + case EbtInt8: op = EOpConvInt8ToUint8; break; + case EbtInt: op = EOpConvIntToUint8; break; + case EbtUint: op = EOpConvUintToUint8; break; + default: assert(0); + } + break; + case EbtFloat: + switch (node->getType().getBasicType()) { + case EbtFloat16: op = EOpConvFloat16ToFloat; break; + case EbtInt8: op = EOpConvInt8ToFloat; break; + case EbtUint8: op = EOpConvUint8ToFloat; break; + case EbtInt: op = EOpConvIntToFloat; break; + case EbtUint: op = EOpConvUintToFloat; break; + default: assert(0); + } + break; + case EbtFloat16: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToFloat16; break; + case EbtInt8: op = EOpConvInt8ToFloat16; break; + case EbtUint8: op = EOpConvUint8ToFloat16; break; + case EbtInt: op = EOpConvIntToFloat16; break; + case EbtUint: op = EOpConvUintToFloat16; break; + default: assert(0); + } + break; + } + + node = intermediate.addUnaryNode(op, node, node->getLoc(), type); + // If it's a (non-specialization) constant, it must be folded. + if (node->getAsUnaryNode()->getOperand()->getAsConstantUnion()) + return node->getAsUnaryNode()->getOperand()->getAsConstantUnion()->fold(op, node->getType()); + } + + return node; + + case EOpConstructAccStruct: + if ((node->getType().isScalar() && node->getType().getBasicType() == EbtUint64)) { + // construct acceleration structure from uint64 + requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "uint64_t conversion to acclerationStructureEXT"); + return intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUint64ToAccStruct, true, node, + type); + } else if (node->getType().isVector() && node->getType().getBasicType() == EbtUint && node->getVectorSize() == 2) { + // construct acceleration structure from uint64 + requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "uvec2 conversion to accelerationStructureEXT"); + return intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUvec2ToAccStruct, true, node, + type); + } else + return nullptr; +#endif // GLSLANG_WEB + default: error(loc, "unsupported construction", "", ""); @@ -6824,12 +8095,31 @@ TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& return converted; } +// If a memory qualifier is present in 'to', also make it present in 'from'. +void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier& to) +{ +#ifndef GLSLANG_WEB + if (from.isReadOnly()) + to.readonly = from.readonly; + if (from.isWriteOnly()) + to.writeonly = from.writeonly; + if (from.coherent) + to.coherent = from.coherent; + if (from.volatil) + to.volatil = from.volatil; + if (from.restrict) + to.restrict = from.restrict; +#endif +} + // // Do everything needed to add an interface block. // void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes) { + if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) + blockStorageRemap(loc, blockName, currentBlockQualifier); blockStageIoCheck(loc, currentBlockQualifier); blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr); if (arraySizes != nullptr) { @@ -6839,22 +8129,27 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con requireProfile(loc, ~EEsProfile, "array-of-array of block"); } - // fix and check for member storage qualifiers and types that don't belong within a block + // Inherit and check member storage qualifiers WRT to the block-level qualifier. for (unsigned int member = 0; member < typeList.size(); ++member) { TType& memberType = *typeList[member].type; TQualifier& memberQualifier = memberType.getQualifier(); const TSourceLoc& memberLoc = typeList[member].loc; - globalQualifierFixCheck(memberLoc, memberQualifier); if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage) error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), ""); memberQualifier.storage = currentBlockQualifier.storage; -#ifdef NV_EXTENSIONS + globalQualifierFixCheck(memberLoc, memberQualifier); +#ifndef GLSLANG_WEB + inheritMemoryQualifiers(currentBlockQualifier, memberQualifier); if (currentBlockQualifier.perPrimitiveNV) memberQualifier.perPrimitiveNV = currentBlockQualifier.perPrimitiveNV; if (currentBlockQualifier.perViewNV) memberQualifier.perViewNV = currentBlockQualifier.perViewNV; if (currentBlockQualifier.perTaskNV) memberQualifier.perTaskNV = currentBlockQualifier.perTaskNV; + if (memberQualifier.storage == EvqSpirvStorageClass) + error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), ""); + if (memberQualifier.hasSprivDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty()) + error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), ""); #endif if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary())) error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), ""); @@ -6862,13 +8157,16 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con arraySizesCheck(memberLoc, currentBlockQualifier, memberType.getArraySizes(), nullptr, member == typeList.size() - 1); if (memberQualifier.hasOffset()) { if (spvVersion.spv == 0) { - requireProfile(memberLoc, ~EEsProfile, "offset on block member"); - profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "offset on block member"); + profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "\"offset\" on block member"); + profileRequires(memberLoc, EEsProfile, 300, E_GL_ARB_enhanced_layouts, "\"offset\" on block member"); } } if (memberType.containsOpaque()) error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), ""); + + if (memberType.containsCoopMat()) + error(memberLoc, "member of block cannot be or contain a cooperative matrix type", typeList[member].type->getFieldName().c_str(), ""); } // This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will @@ -6893,23 +8191,19 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con case EvqBuffer: defaultQualification = globalBufferDefaults; break; case EvqVaryingIn: defaultQualification = globalInputDefaults; break; case EvqVaryingOut: defaultQualification = globalOutputDefaults; break; + case EvqShared: defaultQualification = globalSharedDefaults; break; default: defaultQualification.clear(); break; } // Special case for "push_constant uniform", which has a default of std430, // contrary to normal uniform defaults, and can't have a default tracked for it. - if ((currentBlockQualifier.layoutPushConstant && !currentBlockQualifier.hasPacking()) -#ifdef NV_EXTENSIONS - || (currentBlockQualifier.layoutShaderRecordNV && !currentBlockQualifier.hasPacking()) -#endif - ) + if ((currentBlockQualifier.isPushConstant() && !currentBlockQualifier.hasPacking()) || + (currentBlockQualifier.isShaderRecord() && !currentBlockQualifier.hasPacking())) currentBlockQualifier.layoutPacking = ElpStd430; -#ifdef NV_EXTENSIONS // Special case for "taskNV in/out", which has a default of std430, - if (currentBlockQualifier.perTaskNV && !currentBlockQualifier.hasPacking()) + if (currentBlockQualifier.isTaskMemory() && !currentBlockQualifier.hasPacking()) currentBlockQualifier.layoutPacking = ElpStd430; -#endif // fix and check for member layout qualifiers @@ -6927,12 +8221,11 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con bool memberWithLocation = false; bool memberWithoutLocation = false; -#ifdef NV_EXTENSIONS bool memberWithPerViewQualifier = false; -#endif for (unsigned int member = 0; member < typeList.size(); ++member) { TQualifier& memberQualifier = typeList[member].type->getQualifier(); const TSourceLoc& memberLoc = typeList[member].loc; +#ifndef GLSLANG_WEB if (memberQualifier.hasStream()) { if (defaultQualification.layoutStream != memberQualifier.layoutStream) error(memberLoc, "member cannot contradict block", "stream", ""); @@ -6946,12 +8239,14 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer) error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", ""); } +#endif if (memberQualifier.hasPacking()) error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), ""); if (memberQualifier.hasLocation()) { const char* feature = "location on block member"; switch (currentBlockQualifier.storage) { +#ifndef GLSLANG_WEB case EvqVaryingIn: case EvqVaryingOut: requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile | EEsProfile, feature); @@ -6959,6 +8254,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con profileRequires(memberLoc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature); memberWithLocation = true; break; +#endif default: error(memberLoc, "can only use in an in/out block", feature, ""); break; @@ -6975,11 +8271,9 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con error(memberLoc, "can only be used with std140, std430, or scalar layout packing", "offset/align", ""); } -#ifdef NV_EXTENSIONS if (memberQualifier.isPerView()) { memberWithPerViewQualifier = true; } -#endif TQualifier newMemberQualification = defaultQualification; mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false); @@ -6988,6 +8282,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes); +#ifndef GLSLANG_WEB // Ensure that the block has an XfbBuffer assigned. This is needed // because if the block has a XfbOffset assigned, then it is // assumed that it has implicitly assigned the current global @@ -6997,18 +8292,21 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con if (!currentBlockQualifier.hasXfbBuffer() && currentBlockQualifier.hasXfbOffset()) currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; } +#endif // Process the members fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation); fixXfbOffsets(currentBlockQualifier, typeList); fixBlockUniformOffsets(currentBlockQualifier, typeList); + fixBlockUniformLayoutMatrix(currentBlockQualifier, &typeList, nullptr); + fixBlockUniformLayoutPacking(currentBlockQualifier, &typeList, nullptr); for (unsigned int member = 0; member < typeList.size(); ++member) layoutTypeCheck(typeList[member].loc, *typeList[member].type); -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB if (memberWithPerViewQualifier) { for (unsigned int member = 0; member < typeList.size(); ++member) { - resizeMeshViewDimension(typeList[member].loc, *typeList[member].type); + checkAndResizeMeshViewDim(typeList[member].loc, *typeList[member].type, /*isBlockMember*/ true); } } #endif @@ -7024,10 +8322,11 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con TType blockType(&typeList, *blockName, currentBlockQualifier); if (arraySizes != nullptr) blockType.transferArraySizes(arraySizes); - else - ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName); - if (currentBlockQualifier.layoutBufferReference) { +#ifndef GLSLANG_WEB + if (arraySizes == nullptr) + ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName); + if (currentBlockQualifier.hasBufferReference()) { if (currentBlockQualifier.storage != EvqBuffer) error(loc, "can only be used with buffer", "buffer_reference", ""); @@ -7039,7 +8338,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con TVariable* blockNameVar = new TVariable(blockName, blockNameType, true); if (! symbolTable.insert(*blockNameVar)) { TSymbol* existingName = symbolTable.find(*blockName); - if (existingName->getType().getBasicType() == EbtReference && + if (existingName->getType().isReference() && existingName->getType().getReferentType()->getStruct() && existingName->getType().getReferentType()->getStruct()->size() == 0 && existingName->getType().getQualifier().storage == blockType.getQualifier().storage) { @@ -7051,7 +8350,9 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con if (!instanceName) { return; } - } else { + } else +#endif + { // // Don't make a user-defined type out of block name; that will cause an error // if the same block name gets reused in a different interface. @@ -7099,94 +8400,101 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con // Check for general layout qualifier errors layoutObjectCheck(loc, variable); +#ifndef GLSLANG_WEB // fix up if (isIoResizeArray(blockType)) { ioArraySymbolResizeList.push_back(&variable); - checkIoArraysConsistency(loc, true, blockType.getQualifier().isPerPrimitive()); + checkIoArraysConsistency(loc, true); } else fixIoArraySize(loc, variable.getWritableType()); +#endif // Save it in the AST for linker use. trackLinkage(variable); } +// +// allow storage type of block to be remapped at compile time +// +void TParseContext::blockStorageRemap(const TSourceLoc&, const TString* instanceName, TQualifier& qualifier) +{ + TBlockStorageClass type = intermediate.getBlockStorageOverride(instanceName->c_str()); + if (type != EbsNone) { + qualifier.setBlockStorage(type); + } +} + // Do all block-declaration checking regarding the combination of in/out/uniform/buffer // with a particular stage. void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier) { + const char *extsrt[2] = { E_GL_NV_ray_tracing, E_GL_EXT_ray_tracing }; switch (qualifier.storage) { case EvqUniform: profileRequires(loc, EEsProfile, 300, nullptr, "uniform block"); - profileRequires(loc, ENoProfile, 140, nullptr, "uniform block"); - if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.layoutPushConstant) + profileRequires(loc, ENoProfile, 140, E_GL_ARB_uniform_buffer_object, "uniform block"); + if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.isPushConstant()) requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier"); break; case EvqBuffer: requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block"); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "buffer block"); profileRequires(loc, EEsProfile, 310, nullptr, "buffer block"); break; case EvqVaryingIn: profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "input block"); // It is a compile-time error to have an input block in a vertex shader or an output block in a fragment shader // "Compute shaders do not permit user-defined input variables..." - requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask|EShLangFragmentMask -#ifdef NV_EXTENSIONS - |EShLangMeshNVMask -#endif - ), "input block"); + requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask| + EShLangFragmentMask|EShLangMeshNVMask), "input block"); if (language == EShLangFragment) { profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block"); - } -#ifdef NV_EXTENSIONS - else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) { + } else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) { error(loc, "input blocks cannot be used in a mesh shader", "out", ""); } -#endif break; case EvqVaryingOut: profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block"); - requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask -#ifdef NV_EXTENSIONS - |EShLangMeshNVMask|EShLangTaskNVMask -#endif - ), "output block"); + requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask| + EShLangGeometryMask|EShLangMeshNVMask|EShLangTaskNVMask), "output block"); // ES 310 can have a block before shader_io is turned on, so skip this test for built-ins if (language == EShLangVertex && ! parsingBuiltins) { profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block"); - } -#ifdef NV_EXTENSIONS - else if (language == EShLangMeshNV && qualifier.isTaskMemory()) { + } else if (language == EShLangMeshNV && qualifier.isTaskMemory()) { error(loc, "can only use on input blocks in mesh shader", "taskNV", ""); - } - else if (language == EShLangTaskNV && ! qualifier.isTaskMemory()) { + } else if (language == EShLangTaskNV && ! qualifier.isTaskMemory()) { error(loc, "output blocks cannot be used in a task shader", "out", ""); } -#endif break; -#ifdef NV_EXTENSIONS - case EvqPayloadNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block"); - requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask), + case EvqShared: + if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_4) { + error(loc, "shared block requires at least SPIR-V 1.4", "shared block", ""); + } + profileRequires(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shared_memory_block, "shared block"); + break; +#ifndef GLSLANG_WEB + case EvqPayload: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadNV block"); + requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask), "rayPayloadNV block"); break; - case EvqPayloadInNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV block"); - requireStage(loc, (EShLanguageMask)(EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask), + case EvqPayloadIn: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadInNV block"); + requireStage(loc, (EShLanguageMask)(EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask), "rayPayloadInNV block"); break; - case EvqHitAttrNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV block"); - requireStage(loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask), "hitAttributeNV block"); + case EvqHitAttr: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "hitAttributeNV block"); + requireStage(loc, (EShLanguageMask)(EShLangIntersectMask | EShLangAnyHitMask | EShLangClosestHitMask), "hitAttributeNV block"); break; - case EvqCallableDataNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataNV block"); - requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), + case EvqCallableData: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataNV block"); + requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataNV block"); break; - case EvqCallableDataInNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV block"); - requireStage(loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV block"); + case EvqCallableDataIn: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataInNV block"); + requireStage(loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV block"); break; #endif default: @@ -7219,18 +8527,16 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& error(loc, "cannot use interpolation qualifiers on an interface block", "flat/smooth/noperspective", ""); if (qualifier.centroid) error(loc, "cannot use centroid qualifier on an interface block", "centroid", ""); - if (qualifier.sample) + if (qualifier.isSample()) error(loc, "cannot use sample qualifier on an interface block", "sample", ""); if (qualifier.invariant) error(loc, "cannot use invariant qualifier on an interface block", "invariant", ""); - if (qualifier.layoutPushConstant) + if (qualifier.isPushConstant()) intermediate.addPushConstantCount(); -#ifdef NV_EXTENSIONS - if (qualifier.layoutShaderRecordNV) - intermediate.addShaderRecordNVCount(); - if (qualifier.perTaskNV) + if (qualifier.isShaderRecord()) + intermediate.addShaderRecordCount(); + if (qualifier.isTaskMemory()) intermediate.addTaskNVCount(); -#endif } // @@ -7279,6 +8585,7 @@ void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifi void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList) { +#ifndef GLSLANG_WEB // "If a block is qualified with xfb_offset, all its // members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any // members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer @@ -7291,24 +8598,18 @@ void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList) for (unsigned int member = 0; member < typeList.size(); ++member) { TQualifier& memberQualifier = typeList[member].type->getQualifier(); bool contains64BitType = false; -#ifdef AMD_EXTENSIONS bool contains32BitType = false; bool contains16BitType = false; int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType, contains32BitType, contains16BitType); -#else - int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType); -#endif // see if we need to auto-assign an offset to this member if (! memberQualifier.hasXfbOffset()) { // "if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8" if (contains64BitType) RoundToPow2(nextOffset, 8); -#ifdef AMD_EXTENSIONS else if (contains32BitType) RoundToPow2(nextOffset, 4); else if (contains16BitType) RoundToPow2(nextOffset, 2); -#endif memberQualifier.layoutXfbOffset = nextOffset; } else nextOffset = memberQualifier.layoutXfbOffset; @@ -7318,6 +8619,7 @@ void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList) // The above gave all block members an offset, so we can take it off the block now, // which will avoid double counting the offset usage. qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd; +#endif } // Calculate and save the offset of each block member, using the recursively @@ -7328,7 +8630,7 @@ void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList) // void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typeList) { - if (!qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory()) + if (!storageCanHaveLayoutInBlock(qualifier.storage) && !qualifier.isTaskMemory()) return; if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430 && qualifier.layoutPacking != ElpScalar) return; @@ -7385,6 +8687,103 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ } } +// +// Spread LayoutMatrix to uniform block member, if a uniform block member is a struct, +// we need spread LayoutMatrix to this struct member too. and keep this rule for recursive. +// +void TParseContext::fixBlockUniformLayoutMatrix(TQualifier& qualifier, TTypeList* originTypeList, + TTypeList* tmpTypeList) +{ + assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size()); + for (unsigned int member = 0; member < originTypeList->size(); ++member) { + if (qualifier.layoutPacking != ElpNone) { + if (tmpTypeList == nullptr) { + if (((*originTypeList)[member].type->isMatrix() || + (*originTypeList)[member].type->getBasicType() == EbtStruct) && + (*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) { + (*originTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix; + } + } else { + if (((*tmpTypeList)[member].type->isMatrix() || + (*tmpTypeList)[member].type->getBasicType() == EbtStruct) && + (*tmpTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) { + (*tmpTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix; + } + } + } + + if ((*originTypeList)[member].type->getBasicType() == EbtStruct) { + TQualifier* memberQualifier = nullptr; + // block member can be declare a matrix style, so it should be update to the member's style + if ((*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) { + memberQualifier = &qualifier; + } else { + memberQualifier = &((*originTypeList)[member].type->getQualifier()); + } + + const TType* tmpType = tmpTypeList == nullptr ? + (*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type; + + fixBlockUniformLayoutMatrix(*memberQualifier, (*originTypeList)[member].type->getWritableStruct(), + tmpType->getWritableStruct()); + + const TTypeList* structure = recordStructCopy(matrixFixRecord, (*originTypeList)[member].type, tmpType); + + if (tmpTypeList == nullptr) { + (*originTypeList)[member].type->setStruct(const_cast(structure)); + } + if (tmpTypeList != nullptr) { + (*tmpTypeList)[member].type->setStruct(const_cast(structure)); + } + } + } +} + +// +// Spread LayoutPacking to matrix or aggregate block members. If a block member is a struct or +// array of struct, spread LayoutPacking recursively to its matrix or aggregate members. +// +void TParseContext::fixBlockUniformLayoutPacking(TQualifier& qualifier, TTypeList* originTypeList, + TTypeList* tmpTypeList) +{ + assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size()); + for (unsigned int member = 0; member < originTypeList->size(); ++member) { + if (qualifier.layoutPacking != ElpNone) { + if (tmpTypeList == nullptr) { + if ((*originTypeList)[member].type->getQualifier().layoutPacking == ElpNone && + !(*originTypeList)[member].type->isScalarOrVector()) { + (*originTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking; + } + } else { + if ((*tmpTypeList)[member].type->getQualifier().layoutPacking == ElpNone && + !(*tmpTypeList)[member].type->isScalarOrVector()) { + (*tmpTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking; + } + } + } + + if ((*originTypeList)[member].type->getBasicType() == EbtStruct) { + // Deep copy the type in pool. + // Because, struct use in different block may have different layout qualifier. + // We have to new a object to distinguish between them. + const TType* tmpType = tmpTypeList == nullptr ? + (*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type; + + fixBlockUniformLayoutPacking(qualifier, (*originTypeList)[member].type->getWritableStruct(), + tmpType->getWritableStruct()); + + const TTypeList* structure = recordStructCopy(packingFixRecord, (*originTypeList)[member].type, tmpType); + + if (tmpTypeList == nullptr) { + (*originTypeList)[member].type->setStruct(const_cast(structure)); + } + if (tmpTypeList != nullptr) { + (*tmpTypeList)[member].type->setStruct(const_cast(structure)); + } + } + } +} + // For an identifier that is already declared, add more qualification to it. void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier) { @@ -7394,7 +8793,7 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qua // a qualifier to an existing symbol. Detect this and create the block reference // type with an empty type list, which will be filled in later in // TParseContext::declareBlock. - if (!symbol && qualifier.layoutBufferReference) { + if (!symbol && qualifier.hasBufferReference()) { TTypeList typeList; TType blockType(&typeList, identifier, qualifier);; TType blockNameType(EbtReference, blockType, identifier); @@ -7434,10 +8833,10 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qua error(loc, "cannot change qualification after use", "invariant", ""); symbol->getWritableType().getQualifier().invariant = true; invariantCheck(loc, symbol->getType().getQualifier()); - } else if (qualifier.noContraction) { + } else if (qualifier.isNoContraction()) { if (intermediate.inIoAccessed(identifier)) error(loc, "cannot change qualification after use", "precise", ""); - symbol->getWritableType().getQualifier().noContraction = true; + symbol->getWritableType().getQualifier().setNoContraction(); } else if (qualifier.specConstant) { symbol->getWritableType().getQualifier().makeSpecConstant(); if (qualifier.hasSpecConstantId()) @@ -7460,7 +8859,7 @@ void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qual bool pipeOut = qualifier.isPipeOutput(); bool pipeIn = qualifier.isPipeInput(); - if (version >= 300 || (profile != EEsProfile && version >= 420)) { + if ((version >= 300 && isEsProfile()) || (!isEsProfile() && version >= 420)) { if (! pipeOut) error(loc, "can only apply to an output", "invariant", ""); } else { @@ -7475,12 +8874,9 @@ void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qual // void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType) { +#ifndef GLSLANG_WEB if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) { -#ifdef NV_EXTENSIONS assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMeshNV); -#else - assert(language == EShLangTessControl || language == EShLangGeometry); -#endif const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices"; if (publicType.qualifier.storage != EvqVaryingOut) @@ -7491,7 +8887,6 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con if (language == EShLangTessControl) checkIoArraysConsistency(loc); } -#ifdef NV_EXTENSIONS if (publicType.shaderQualifiers.primitives != TQualifier::layoutNotSet) { assert(language == EShLangMeshNV); const char* id = "max_primitives"; @@ -7501,7 +8896,6 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con if (! intermediate.setPrimitives(publicType.shaderQualifiers.primitives)) error(loc, "cannot change previously set layout value", id, ""); } -#endif if (publicType.shaderQualifiers.invocations != TQualifier::layoutNotSet) { if (publicType.qualifier.storage != EvqVaryingIn) error(loc, "can only apply to 'in'", "invocations", ""); @@ -7518,12 +8912,10 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con case ElgTrianglesAdjacency: case ElgQuads: case ElgIsolines: -#ifdef NV_EXTENSIONS if (language == EShLangMeshNV) { error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); break; } -#endif if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry)) { if (language == EShLangGeometry) checkIoArraysConsistency(loc); @@ -7535,14 +8927,12 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con } } else if (publicType.qualifier.storage == EvqVaryingOut) { switch (publicType.shaderQualifiers.geometry) { -#ifdef NV_EXTENSIONS case ElgLines: case ElgTriangles: if (language != EShLangMeshNV) { error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); break; } -#endif // Fall through case ElgPoints: case ElgLineStrip: @@ -7576,8 +8966,9 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con else error(loc, "can only apply to 'in'", "point_mode", ""); } +#endif for (int i = 0; i < 3; ++i) { - if (publicType.shaderQualifiers.localSize[i] > 1) { + if (publicType.shaderQualifiers.localSizeNotDefault[i]) { if (publicType.qualifier.storage == EvqVaryingIn) { if (! intermediate.setLocalSize(i, publicType.shaderQualifiers.localSize[i])) error(loc, "cannot change previously set size", "local_size", ""); @@ -7593,7 +8984,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con if (intermediate.getLocalSize(i) > (unsigned int)max) error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", ""); } -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB else if (language == EShLangMeshNV) { switch (i) { case 0: max = resources.maxMeshWorkGroupSizeX_NV; break; @@ -7603,8 +8994,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con } if (intermediate.getLocalSize(i) > (unsigned int)max) error(loc, "too large; see gl_MaxMeshWorkGroupSizeNV", "local_size", ""); - } - else if (language == EShLangTaskNV) { + } else if (language == EShLangTaskNV) { switch (i) { case 0: max = resources.maxTaskWorkGroupSizeX_NV; break; case 1: max = resources.maxTaskWorkGroupSizeY_NV; break; @@ -7639,6 +9029,8 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con workGroupSize->getWritableType().getQualifier().specConstant = true; } } + +#ifndef GLSLANG_WEB if (publicType.shaderQualifiers.earlyFragmentTests) { if (publicType.qualifier.storage == EvqVaryingIn) intermediate.setEarlyFragmentTests(); @@ -7651,12 +9043,19 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con else error(loc, "can only apply to 'in'", "post_coverage_coverage", ""); } - if (publicType.shaderQualifiers.blendEquation) { + if (publicType.shaderQualifiers.hasBlendEquation()) { if (publicType.qualifier.storage != EvqVaryingOut) error(loc, "can only apply to 'out'", "blend equation", ""); } + if (publicType.shaderQualifiers.interlockOrdering) { + if (publicType.qualifier.storage == EvqVaryingIn) { + if (!intermediate.setInterlockOrdering(publicType.shaderQualifiers.interlockOrdering)) + error(loc, "cannot change previously set fragment shader interlock ordering", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), ""); + } + else + error(loc, "can only apply to 'in'", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), ""); + } -#ifdef NV_EXTENSIONS if (publicType.shaderQualifiers.layoutDerivativeGroupQuads && publicType.shaderQualifiers.layoutDerivativeGroupLinear) { error(loc, "cannot be both specified", "derivative_group_quadsNV and derivative_group_linearNV", ""); @@ -7685,6 +9084,24 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con else error(loc, "can only apply to 'in'", "derivative_group_linearNV", ""); } + // Check mesh out array sizes, once all the necessary out qualifiers are defined. + if ((language == EShLangMeshNV) && + (intermediate.getVertices() != TQualifier::layoutNotSet) && + (intermediate.getPrimitives() != TQualifier::layoutNotSet) && + (intermediate.getOutputPrimitive() != ElgNone)) + { + checkIoArraysConsistency(loc); + } + + if (publicType.shaderQualifiers.layoutPrimitiveCulling) { + if (publicType.qualifier.storage != EvqTemporary) + error(loc, "layout qualifier can not have storage qualifiers", "primitive_culling","", ""); + else { + intermediate.setLayoutPrimitiveCulling(); + } + // Exit early as further checks are not valid + return; + } #endif const TQualifier& qualifier = publicType.qualifier; @@ -7693,6 +9110,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con qualifier.isInterpolation() || qualifier.precision != EpqNone) error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "qualifier", ""); + // "The offset qualifier can only be used on block members of blocks..." // "The align qualifier can only be used on blocks or block members..." if (qualifier.hasOffset() || @@ -7717,6 +9135,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con case EvqVaryingIn: break; case EvqVaryingOut: +#ifndef GLSLANG_WEB if (qualifier.hasStream()) globalOutputDefaults.layoutStream = qualifier.layoutStream; if (qualifier.hasXfbBuffer()) @@ -7725,9 +9144,16 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con if (! intermediate.setXfbBufferStride(globalOutputDefaults.layoutXfbBuffer, qualifier.layoutXfbStride)) error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer); } +#endif + break; + case EvqShared: + if (qualifier.hasMatrix()) + globalSharedDefaults.layoutMatrix = qualifier.layoutMatrix; + if (qualifier.hasPacking()) + globalSharedDefaults.layoutPacking = qualifier.layoutPacking; break; default: - error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", ""); + error(loc, "default qualifier requires 'uniform', 'buffer', 'in', 'out' or 'shared' storage qualification", "", ""); return; } @@ -7737,16 +9163,14 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con error(loc, "cannot declare a default, use a full declaration", "location/component/index", ""); if (qualifier.hasXfbOffset()) error(loc, "cannot declare a default, use a full declaration", "xfb_offset", ""); - if (qualifier.layoutPushConstant) + if (qualifier.isPushConstant()) error(loc, "cannot declare a default, can only be used on a block", "push_constant", ""); - if (qualifier.layoutBufferReference) + if (qualifier.hasBufferReference()) error(loc, "cannot declare a default, can only be used on a block", "buffer_reference", ""); if (qualifier.hasSpecConstantId()) error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", ""); -#ifdef NV_EXTENSIONS - if (qualifier.layoutShaderRecordNV) + if (qualifier.isShaderRecord()) error(loc, "cannot declare a default, can only be used on a block", "shaderRecordNV", ""); -#endif } // @@ -7813,7 +9237,7 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre // "it is an error to have no statement between a label and the end of the switch statement." // The specifications were updated to remove this (being ill-defined what a "statement" was), // so, this became a warning. However, 3.0 tests still check for the error. - if (profile == EEsProfile && version <= 300 && ! relaxedErrors()) + if (isEsProfile() && version <= 300 && ! relaxedErrors()) error(loc, "last case/default label not followed by statements", "switch", ""); else warn(loc, "last case/default label not followed by statements", "switch", ""); @@ -7834,4 +9258,43 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre return switchNode; } +// +// When a struct used in block, and has it's own layout packing, layout matrix, +// record the origin structure of a struct to map, and Record the structure copy to the copy table, +// +const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TType* originType, const TType* tmpType) +{ + size_t memberCount = tmpType->getStruct()->size(); + size_t originHash = 0, tmpHash = 0; + std::hash hasher; + for (size_t i = 0; i < memberCount; i++) { + size_t originMemberHash = hasher(originType->getStruct()->at(i).type->getQualifier().layoutPacking + + originType->getStruct()->at(i).type->getQualifier().layoutMatrix); + size_t tmpMemberHash = hasher(tmpType->getStruct()->at(i).type->getQualifier().layoutPacking + + tmpType->getStruct()->at(i).type->getQualifier().layoutMatrix); + originHash = hasher((originHash ^ originMemberHash) << 1); + tmpHash = hasher((tmpHash ^ tmpMemberHash) << 1); + } + const TTypeList* originStruct = originType->getStruct(); + const TTypeList* tmpStruct = tmpType->getStruct(); + if (originHash != tmpHash) { + auto fixRecords = record.find(originStruct); + if (fixRecords != record.end()) { + auto fixRecord = fixRecords->second.find(tmpHash); + if (fixRecord != fixRecords->second.end()) { + return fixRecord->second; + } else { + record[originStruct][tmpHash] = tmpStruct; + return tmpStruct; + } + } else { + record[originStruct] = std::map(); + record[originStruct][tmpHash] = tmpStruct; + return tmpStruct; + } + } + return originStruct; +} + } // end namespace glslang + diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseHelper.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseHelper.h index 5b7d430..de44884 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseHelper.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/ParseHelper.h @@ -67,7 +67,8 @@ struct TPragma { class TScanContext; class TPpContext; -typedef std::set TIdSetType; +typedef std::set TIdSetType; +typedef std::map> TStructRecord; // // Sharable code (as well as what's in TParseVersions) across @@ -82,20 +83,24 @@ public: : TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages), scopeMangler("::"), symbolTable(symbolTable), - statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), + statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), blockNestingLevel(0), controlFlowNestingLevel(0), + currentFunctionType(nullptr), postEntryPointReturn(false), contextPragma(true, false), + beginInvocationInterlockCount(0), endInvocationInterlockCount(0), parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr), limits(resources.limits), globalUniformBlock(nullptr), globalUniformBinding(TQualifier::layoutBindingEnd), - globalUniformSet(TQualifier::layoutSetEnd) + globalUniformSet(TQualifier::layoutSetEnd), + atomicCounterBlockSet(TQualifier::layoutSetEnd) { if (entryPoint != nullptr) sourceEntryPointName = *entryPoint; } virtual ~TParseContextBase() { } +#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL) virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...); virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, @@ -104,6 +109,7 @@ public: const char* szExtraInfoFormat, ...); virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...); +#endif virtual void setLimits(const TBuiltInResource&) = 0; @@ -152,6 +158,9 @@ public: // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); + // Manage global buffer (used for backing atomic counters in GLSL when using relaxed Vulkan semantics) + virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); + // Potentially rename shader entry point function void renameShaderFunction(TString*& name) const { @@ -171,7 +180,8 @@ public: TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile int statementNestingLevel; // 0 if outside all flow control or compound statements int loopNestingLevel; // 0 if outside all loops - int structNestingLevel; // 0 if outside blocks and structures + int structNestingLevel; // 0 if outside structures + int blockNestingLevel; // 0 if outside blocks int controlFlowNestingLevel; // 0 if outside all flow control const TType* currentFunctionType; // the return type of the function that's currently being parsed bool functionReturnsValue; // true if a non-void function has a return @@ -182,6 +192,8 @@ public: // the statementNestingLevel the current switch statement is at, which must match the level of its case statements TList switchLevel; struct TPragma contextPragma; + int beginInvocationInterlockCount; + int endInvocationInterlockCount; protected: TParseContextBase(TParseContextBase&); @@ -220,7 +232,25 @@ protected: // override this to set the language-specific name virtual const char* getGlobalUniformBlockName() const { return ""; } virtual void setUniformBlockDefaults(TType&) const { } - virtual void finalizeGlobalUniformBlockLayout(TVariable&) { } + virtual void finalizeGlobalUniformBlockLayout(TVariable&) {} + + // Manage the atomic counter block (used for atomic_uints with Vulkan-Relaxed) + TMap atomicCounterBuffers; + unsigned int atomicCounterBlockSet; + TMap atomicCounterBlockFirstNewMember; + // override this to set the language-specific name + virtual const char* getAtomicCounterBlockName() const { return ""; } + virtual void setAtomicCounterBlockDefaults(TType&) const {} + virtual void setInvariant(const TSourceLoc& loc, const char* builtin) {} + virtual void finalizeAtomicCounterBlockLayout(TVariable&) {} + bool isAtomicCounterBlock(const TSymbol& symbol) { + const TVariable* var = symbol.getAsVariable(); + if (!var) + return false; + const auto& at = atomicCounterBuffers.find(var->getType().getQualifier().layoutBinding); + return (at != atomicCounterBuffers.end() && (*at).second->getType() == var->getType()); + } + virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, TPrefixType prefix, va_list args); @@ -276,13 +306,16 @@ public: const TString* entryPoint = nullptr); virtual ~TParseContext(); - bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); }; + bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); } void setPrecisionDefaults(); void setLimits(const TBuiltInResource&) override; bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override; void parserError(const char* s); // for bison's yyerror + virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override; + virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override; + void reservedErrorCheck(const TSourceLoc&, const TString&); void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override; bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override; @@ -294,18 +327,21 @@ public: TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); +#ifndef GLSLANG_WEB void makeEditable(TSymbol*&) override; + void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier); +#endif bool isIoResizeArray(const TType&) const; void fixIoArraySize(const TSourceLoc&, TType&); - void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier); void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base); - void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false, bool isPerPrimitive = false); - int getIoArrayImplicitSize(bool isPerPrimitive = false) const; + void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false); + int getIoArrayImplicitSize(const TQualifier&, TString* featureString = nullptr) const; void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&); TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right); TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode); TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field); + TIntermTyped* handleDotSwizzle(const TSourceLoc&, TIntermTyped* base, const TString& field); void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName); TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype); TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&); @@ -317,6 +353,7 @@ public: TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*); void addInputArgumentConversions(const TFunction&, TIntermNode*&) const; TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const; + TIntermTyped* addAssign(const TSourceLoc&, TOperator op, TIntermTyped* left, TIntermTyped* right); void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&); void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&); void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&); @@ -326,6 +363,10 @@ public: void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier); void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode); + TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*); + // returns true if the variable was remapped to something else + bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&); + void assignError(const TSourceLoc&, const char* op, TString left, TString right); void unaryOpError(const TSourceLoc&, const char* op, TString operand); void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right); @@ -337,7 +378,7 @@ public: void globalCheck(const TSourceLoc&, const char* token); bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&); bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&); - void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&); + void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType); bool arrayQualifierError(const TSourceLoc&, const TQualifier&); bool arrayError(const TSourceLoc&, const TType&); void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&); @@ -349,10 +390,10 @@ public: void boolCheck(const TSourceLoc&, const TPublicType&); void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer); void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier); - void accStructNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier); + void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier); void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier); void memberQualifierCheck(glslang::TPublicType&); - void globalQualifierFixCheck(const TSourceLoc&, TQualifier&); + void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false); void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&); bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType); void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force); @@ -370,6 +411,7 @@ public: void nestedStructCheck(const TSourceLoc&); void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op); void opaqueCheck(const TSourceLoc&, const TType&, const char* op); + void referenceCheck(const TSourceLoc&, const TType&, const char* op); void storage16BitAssignmentCheck(const TSourceLoc&, const TType&, const char* op); void specializationCheck(const TSourceLoc&, const TType&, const char* op); void structTypeCheck(const TSourceLoc&, TPublicType&); @@ -377,7 +419,7 @@ public: void arrayLimitCheck(const TSourceLoc&, const TString&, int size); void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature); - void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&); + void inductiveLoopBodyCheck(TIntermNode*, long long loopIndexId, TSymbolTable&); void constantIndexExpressionCheck(TIntermNode*); void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&); @@ -400,19 +442,25 @@ public: TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&); TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset); + void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to); void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); + void blockStorageRemap(const TSourceLoc&, const TString*, TQualifier&); void blockStageIoCheck(const TSourceLoc&, const TQualifier&); void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName); void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); void fixXfbOffsets(TQualifier&, TTypeList&); void fixBlockUniformOffsets(TQualifier&, TTypeList&); + void fixBlockUniformLayoutMatrix(TQualifier&, TTypeList*, TTypeList*); + void fixBlockUniformLayoutPacking(TQualifier&, TTypeList*, TTypeList*); void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier); void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&); void invariantCheck(const TSourceLoc&, const TQualifier&); void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&); void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode); TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body); + const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*); +#ifndef GLSLANG_WEB TAttributeType attributeFromName(const TString& name) const; TAttributes* makeAttributes(const TString& identifier) const; TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const; @@ -421,11 +469,27 @@ public: // Determine selection control from attributes void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*); void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*); - // Determine loop control from attributes void handleLoopAttributes(const TAttributes& attributes, TIntermNode*); + // Function attributes + void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*); - void resizeMeshViewDimension(const TSourceLoc&, TType&); + // GL_EXT_spirv_intrinsics + TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name, + const TIntermAggregate* extensions, const TIntermAggregate* capabilities); + TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1, + TSpirvRequirement* spirvReq2); + TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant); + TSpirvTypeParameters* makeSpirvTypeParameters(const TPublicType& type); + TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, + TSpirvTypeParameters* spirvTypeParams2); + TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value); + TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value); + TSpirvInstruction* mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1, + TSpirvInstruction* spirvInst2); +#endif + + void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember); protected: void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type); @@ -437,7 +501,18 @@ protected: bool isRuntimeLength(const TIntermTyped&) const; TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer); +#ifndef GLSLANG_WEB void finish() override; +#endif + + virtual const char* getGlobalUniformBlockName() const override; + virtual void finalizeGlobalUniformBlockLayout(TVariable&) override; + virtual void setUniformBlockDefaults(TType& block) const override; + + virtual const char* getAtomicCounterBlockName() const override; + virtual void finalizeAtomicCounterBlockLayout(TVariable&) override; + virtual void setAtomicCounterBlockDefaults(TType& block) const override; + virtual void setInvariant(const TSourceLoc& loc, const char* builtin) override; public: // @@ -463,11 +538,15 @@ protected: TQualifier globalUniformDefaults; TQualifier globalInputDefaults; TQualifier globalOutputDefaults; - int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point + TQualifier globalSharedDefaults; TString currentCaller; // name of last function body entered (not valid when at global scope) - TIdSetType inductiveLoopIds; +#ifndef GLSLANG_WEB + int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point bool anyIndexLimits; + TIdSetType inductiveLoopIds; TVector needsIndexLimitationChecking; + TStructRecord matrixFixRecord; + TStructRecord packingFixRecord; // // Geometry shader input arrays: @@ -502,6 +581,7 @@ protected: // array-sizing declarations // TVector ioArraySymbolResizeList; +#endif }; } // end namespace glslang diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Scan.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Scan.cpp index 49ce077..c387aed 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Scan.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Scan.cpp @@ -2,6 +2,8 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. +// Copyright (C) 2020 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -187,17 +189,15 @@ bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstT if (lookingInMiddle) { notFirstToken = true; // make forward progress by finishing off the current line plus extra new lines - if (peek() == '\n' || peek() == '\r') { - while (peek() == '\n' || peek() == '\r') - get(); - } else + if (peek() != '\n' && peek() != '\r') { do { c = get(); } while (c != EndOfInput && c != '\n' && c != '\r'); - while (peek() == '\n' || peek() == '\r') - get(); - if (peek() == EndOfInput) - return true; + } + while (peek() == '\n' || peek() == '\r') + get(); + if (peek() == EndOfInput) + return true; } lookingInMiddle = true; @@ -324,7 +324,9 @@ struct str_hash // A single global usable by all threads, by all versions, by all languages. // After a single process-level initialization, this is read only and thread safe std::unordered_map* KeywordMap = nullptr; +#ifndef GLSLANG_WEB std::unordered_set* ReservedSet = nullptr; +#endif }; @@ -341,9 +343,15 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["const"] = CONST; (*KeywordMap)["uniform"] = UNIFORM; - (*KeywordMap)["nonuniformEXT"] = NONUNIFORM; + (*KeywordMap)["buffer"] = BUFFER; (*KeywordMap)["in"] = IN; (*KeywordMap)["out"] = OUT; + (*KeywordMap)["smooth"] = SMOOTH; + (*KeywordMap)["flat"] = FLAT; + (*KeywordMap)["centroid"] = CENTROID; + (*KeywordMap)["invariant"] = INVARIANT; + (*KeywordMap)["packed"] = PACKED; + (*KeywordMap)["resource"] = RESOURCE; (*KeywordMap)["inout"] = INOUT; (*KeywordMap)["struct"] = STRUCT; (*KeywordMap)["break"] = BREAK; @@ -357,6 +365,9 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["if"] = IF; (*KeywordMap)["else"] = ELSE; (*KeywordMap)["discard"] = DISCARD; + (*KeywordMap)["terminateInvocation"] = TERMINATE_INVOCATION; + (*KeywordMap)["terminateRayEXT"] = TERMINATE_RAY; + (*KeywordMap)["ignoreIntersectionEXT"] = IGNORE_INTERSECTION; (*KeywordMap)["return"] = RETURN; (*KeywordMap)["void"] = VOID; (*KeywordMap)["bool"] = BOOL; @@ -376,28 +387,12 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["mat4"] = MAT4; (*KeywordMap)["true"] = BOOLCONSTANT; (*KeywordMap)["false"] = BOOLCONSTANT; - (*KeywordMap)["attribute"] = ATTRIBUTE; - (*KeywordMap)["varying"] = VARYING; - (*KeywordMap)["buffer"] = BUFFER; - (*KeywordMap)["coherent"] = COHERENT; - (*KeywordMap)["devicecoherent"] = DEVICECOHERENT; - (*KeywordMap)["queuefamilycoherent"] = QUEUEFAMILYCOHERENT; - (*KeywordMap)["workgroupcoherent"] = WORKGROUPCOHERENT; - (*KeywordMap)["subgroupcoherent"] = SUBGROUPCOHERENT; - (*KeywordMap)["nonprivate"] = NONPRIVATE; - (*KeywordMap)["restrict"] = RESTRICT; - (*KeywordMap)["readonly"] = READONLY; - (*KeywordMap)["writeonly"] = WRITEONLY; - (*KeywordMap)["atomic_uint"] = ATOMIC_UINT; - (*KeywordMap)["volatile"] = VOLATILE; (*KeywordMap)["layout"] = LAYOUT; (*KeywordMap)["shared"] = SHARED; - (*KeywordMap)["patch"] = PATCH; - (*KeywordMap)["sample"] = SAMPLE; - (*KeywordMap)["subroutine"] = SUBROUTINE; (*KeywordMap)["highp"] = HIGH_PRECISION; (*KeywordMap)["mediump"] = MEDIUM_PRECISION; (*KeywordMap)["lowp"] = LOW_PRECISION; + (*KeywordMap)["superp"] = SUPERP; (*KeywordMap)["precision"] = PRECISION; (*KeywordMap)["mat2x2"] = MAT2X2; (*KeywordMap)["mat2x3"] = MAT2X3; @@ -408,6 +403,32 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["mat4x2"] = MAT4X2; (*KeywordMap)["mat4x3"] = MAT4X3; (*KeywordMap)["mat4x4"] = MAT4X4; + (*KeywordMap)["uint"] = UINT; + (*KeywordMap)["uvec2"] = UVEC2; + (*KeywordMap)["uvec3"] = UVEC3; + (*KeywordMap)["uvec4"] = UVEC4; + +#ifndef GLSLANG_WEB + (*KeywordMap)["nonuniformEXT"] = NONUNIFORM; + (*KeywordMap)["demote"] = DEMOTE; + (*KeywordMap)["attribute"] = ATTRIBUTE; + (*KeywordMap)["varying"] = VARYING; + (*KeywordMap)["noperspective"] = NOPERSPECTIVE; + (*KeywordMap)["coherent"] = COHERENT; + (*KeywordMap)["devicecoherent"] = DEVICECOHERENT; + (*KeywordMap)["queuefamilycoherent"] = QUEUEFAMILYCOHERENT; + (*KeywordMap)["workgroupcoherent"] = WORKGROUPCOHERENT; + (*KeywordMap)["subgroupcoherent"] = SUBGROUPCOHERENT; + (*KeywordMap)["shadercallcoherent"] = SHADERCALLCOHERENT; + (*KeywordMap)["nonprivate"] = NONPRIVATE; + (*KeywordMap)["restrict"] = RESTRICT; + (*KeywordMap)["readonly"] = READONLY; + (*KeywordMap)["writeonly"] = WRITEONLY; + (*KeywordMap)["atomic_uint"] = ATOMIC_UINT; + (*KeywordMap)["volatile"] = VOLATILE; + (*KeywordMap)["patch"] = PATCH; + (*KeywordMap)["sample"] = SAMPLE; + (*KeywordMap)["subroutine"] = SUBROUTINE; (*KeywordMap)["dmat2"] = DMAT2; (*KeywordMap)["dmat3"] = DMAT3; (*KeywordMap)["dmat4"] = DMAT4; @@ -453,15 +474,32 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["image2DMSArray"] = IMAGE2DMSARRAY; (*KeywordMap)["iimage2DMSArray"] = IIMAGE2DMSARRAY; (*KeywordMap)["uimage2DMSArray"] = UIMAGE2DMSARRAY; + (*KeywordMap)["i64image1D"] = I64IMAGE1D; + (*KeywordMap)["u64image1D"] = U64IMAGE1D; + (*KeywordMap)["i64image2D"] = I64IMAGE2D; + (*KeywordMap)["u64image2D"] = U64IMAGE2D; + (*KeywordMap)["i64image3D"] = I64IMAGE3D; + (*KeywordMap)["u64image3D"] = U64IMAGE3D; + (*KeywordMap)["i64image2DRect"] = I64IMAGE2DRECT; + (*KeywordMap)["u64image2DRect"] = U64IMAGE2DRECT; + (*KeywordMap)["i64imageCube"] = I64IMAGECUBE; + (*KeywordMap)["u64imageCube"] = U64IMAGECUBE; + (*KeywordMap)["i64imageBuffer"] = I64IMAGEBUFFER; + (*KeywordMap)["u64imageBuffer"] = U64IMAGEBUFFER; + (*KeywordMap)["i64image1DArray"] = I64IMAGE1DARRAY; + (*KeywordMap)["u64image1DArray"] = U64IMAGE1DARRAY; + (*KeywordMap)["i64image2DArray"] = I64IMAGE2DARRAY; + (*KeywordMap)["u64image2DArray"] = U64IMAGE2DARRAY; + (*KeywordMap)["i64imageCubeArray"] = I64IMAGECUBEARRAY; + (*KeywordMap)["u64imageCubeArray"] = U64IMAGECUBEARRAY; + (*KeywordMap)["i64image2DMS"] = I64IMAGE2DMS; + (*KeywordMap)["u64image2DMS"] = U64IMAGE2DMS; + (*KeywordMap)["i64image2DMSArray"] = I64IMAGE2DMSARRAY; + (*KeywordMap)["u64image2DMSArray"] = U64IMAGE2DMSARRAY; (*KeywordMap)["double"] = DOUBLE; (*KeywordMap)["dvec2"] = DVEC2; (*KeywordMap)["dvec3"] = DVEC3; (*KeywordMap)["dvec4"] = DVEC4; - (*KeywordMap)["uint"] = UINT; - (*KeywordMap)["uvec2"] = UVEC2; - (*KeywordMap)["uvec3"] = UVEC3; - (*KeywordMap)["uvec4"] = UVEC4; - (*KeywordMap)["int64_t"] = INT64_T; (*KeywordMap)["uint64_t"] = UINT64_T; (*KeywordMap)["i64vec2"] = I64VEC2; @@ -549,18 +587,21 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["f64mat4x3"] = F64MAT4X3; (*KeywordMap)["f64mat4x4"] = F64MAT4X4; + // GL_EXT_spirv_intrinsics + (*KeywordMap)["spirv_instruction"] = SPIRV_INSTRUCTION; + (*KeywordMap)["spirv_execution_mode"] = SPIRV_EXECUTION_MODE; + (*KeywordMap)["spirv_execution_mode_id"] = SPIRV_EXECUTION_MODE_ID; + (*KeywordMap)["spirv_decorate"] = SPIRV_DECORATE; + (*KeywordMap)["spirv_decorate_id"] = SPIRV_DECORATE_ID; + (*KeywordMap)["spirv_decorate_string"] = SPIRV_DECORATE_STRING; + (*KeywordMap)["spirv_type"] = SPIRV_TYPE; + (*KeywordMap)["spirv_storage_class"] = SPIRV_STORAGE_CLASS; + (*KeywordMap)["spirv_by_reference"] = SPIRV_BY_REFERENCE; + (*KeywordMap)["spirv_literal"] = SPIRV_LITERAL; +#endif + (*KeywordMap)["sampler2D"] = SAMPLER2D; (*KeywordMap)["samplerCube"] = SAMPLERCUBE; - (*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY; - (*KeywordMap)["samplerCubeArrayShadow"] = SAMPLERCUBEARRAYSHADOW; - (*KeywordMap)["isamplerCubeArray"] = ISAMPLERCUBEARRAY; - (*KeywordMap)["usamplerCubeArray"] = USAMPLERCUBEARRAY; - (*KeywordMap)["sampler1DArrayShadow"] = SAMPLER1DARRAYSHADOW; - (*KeywordMap)["isampler1DArray"] = ISAMPLER1DARRAY; - (*KeywordMap)["usampler1D"] = USAMPLER1D; - (*KeywordMap)["isampler1D"] = ISAMPLER1D; - (*KeywordMap)["usampler1DArray"] = USAMPLER1DARRAY; - (*KeywordMap)["samplerBuffer"] = SAMPLERBUFFER; (*KeywordMap)["samplerCubeShadow"] = SAMPLERCUBESHADOW; (*KeywordMap)["sampler2DArray"] = SAMPLER2DARRAY; (*KeywordMap)["sampler2DArrayShadow"] = SAMPLER2DARRAYSHADOW; @@ -572,6 +613,39 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["usampler3D"] = USAMPLER3D; (*KeywordMap)["usamplerCube"] = USAMPLERCUBE; (*KeywordMap)["usampler2DArray"] = USAMPLER2DARRAY; + (*KeywordMap)["sampler3D"] = SAMPLER3D; + (*KeywordMap)["sampler2DShadow"] = SAMPLER2DSHADOW; + + (*KeywordMap)["texture2D"] = TEXTURE2D; + (*KeywordMap)["textureCube"] = TEXTURECUBE; + (*KeywordMap)["texture2DArray"] = TEXTURE2DARRAY; + (*KeywordMap)["itexture2D"] = ITEXTURE2D; + (*KeywordMap)["itexture3D"] = ITEXTURE3D; + (*KeywordMap)["itextureCube"] = ITEXTURECUBE; + (*KeywordMap)["itexture2DArray"] = ITEXTURE2DARRAY; + (*KeywordMap)["utexture2D"] = UTEXTURE2D; + (*KeywordMap)["utexture3D"] = UTEXTURE3D; + (*KeywordMap)["utextureCube"] = UTEXTURECUBE; + (*KeywordMap)["utexture2DArray"] = UTEXTURE2DARRAY; + (*KeywordMap)["texture3D"] = TEXTURE3D; + + (*KeywordMap)["sampler"] = SAMPLER; + (*KeywordMap)["samplerShadow"] = SAMPLERSHADOW; + +#ifndef GLSLANG_WEB + (*KeywordMap)["textureCubeArray"] = TEXTURECUBEARRAY; + (*KeywordMap)["itextureCubeArray"] = ITEXTURECUBEARRAY; + (*KeywordMap)["utextureCubeArray"] = UTEXTURECUBEARRAY; + (*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY; + (*KeywordMap)["samplerCubeArrayShadow"] = SAMPLERCUBEARRAYSHADOW; + (*KeywordMap)["isamplerCubeArray"] = ISAMPLERCUBEARRAY; + (*KeywordMap)["usamplerCubeArray"] = USAMPLERCUBEARRAY; + (*KeywordMap)["sampler1DArrayShadow"] = SAMPLER1DARRAYSHADOW; + (*KeywordMap)["isampler1DArray"] = ISAMPLER1DARRAY; + (*KeywordMap)["usampler1D"] = USAMPLER1D; + (*KeywordMap)["isampler1D"] = ISAMPLER1D; + (*KeywordMap)["usampler1DArray"] = USAMPLER1DARRAY; + (*KeywordMap)["samplerBuffer"] = SAMPLERBUFFER; (*KeywordMap)["isampler2DRect"] = ISAMPLER2DRECT; (*KeywordMap)["usampler2DRect"] = USAMPLER2DRECT; (*KeywordMap)["isamplerBuffer"] = ISAMPLERBUFFER; @@ -584,8 +658,6 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["usampler2DMSArray"] = USAMPLER2DMSARRAY; (*KeywordMap)["sampler1D"] = SAMPLER1D; (*KeywordMap)["sampler1DShadow"] = SAMPLER1DSHADOW; - (*KeywordMap)["sampler3D"] = SAMPLER3D; - (*KeywordMap)["sampler2DShadow"] = SAMPLER2DSHADOW; (*KeywordMap)["sampler2DRect"] = SAMPLER2DRECT; (*KeywordMap)["sampler2DRectShadow"] = SAMPLER2DRECTSHADOW; (*KeywordMap)["sampler1DArray"] = SAMPLER1DARRAY; @@ -594,28 +666,11 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["__samplerExternal2DY2YEXT"] = SAMPLEREXTERNAL2DY2YEXT; // GL_EXT_YUV_target - (*KeywordMap)["sampler"] = SAMPLER; - (*KeywordMap)["samplerShadow"] = SAMPLERSHADOW; - - (*KeywordMap)["texture2D"] = TEXTURE2D; - (*KeywordMap)["textureCube"] = TEXTURECUBE; - (*KeywordMap)["textureCubeArray"] = TEXTURECUBEARRAY; - (*KeywordMap)["itextureCubeArray"] = ITEXTURECUBEARRAY; - (*KeywordMap)["utextureCubeArray"] = UTEXTURECUBEARRAY; (*KeywordMap)["itexture1DArray"] = ITEXTURE1DARRAY; (*KeywordMap)["utexture1D"] = UTEXTURE1D; (*KeywordMap)["itexture1D"] = ITEXTURE1D; (*KeywordMap)["utexture1DArray"] = UTEXTURE1DARRAY; (*KeywordMap)["textureBuffer"] = TEXTUREBUFFER; - (*KeywordMap)["texture2DArray"] = TEXTURE2DARRAY; - (*KeywordMap)["itexture2D"] = ITEXTURE2D; - (*KeywordMap)["itexture3D"] = ITEXTURE3D; - (*KeywordMap)["itextureCube"] = ITEXTURECUBE; - (*KeywordMap)["itexture2DArray"] = ITEXTURE2DARRAY; - (*KeywordMap)["utexture2D"] = UTEXTURE2D; - (*KeywordMap)["utexture3D"] = UTEXTURE3D; - (*KeywordMap)["utextureCube"] = UTEXTURECUBE; - (*KeywordMap)["utexture2DArray"] = UTEXTURE2DARRAY; (*KeywordMap)["itexture2DRect"] = ITEXTURE2DRECT; (*KeywordMap)["utexture2DRect"] = UTEXTURE2DRECT; (*KeywordMap)["itextureBuffer"] = ITEXTUREBUFFER; @@ -627,7 +682,6 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["itexture2DMSArray"] = ITEXTURE2DMSARRAY; (*KeywordMap)["utexture2DMSArray"] = UTEXTURE2DMSARRAY; (*KeywordMap)["texture1D"] = TEXTURE1D; - (*KeywordMap)["texture3D"] = TEXTURE3D; (*KeywordMap)["texture2DRect"] = TEXTURE2DRECT; (*KeywordMap)["texture1DArray"] = TEXTURE1DARRAY; @@ -638,7 +692,6 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["usubpassInput"] = USUBPASSINPUT; (*KeywordMap)["usubpassInputMS"] = USUBPASSINPUTMS; -#ifdef AMD_EXTENSIONS (*KeywordMap)["f16sampler1D"] = F16SAMPLER1D; (*KeywordMap)["f16sampler2D"] = F16SAMPLER2D; (*KeywordMap)["f16sampler3D"] = F16SAMPLER3D; @@ -684,35 +737,30 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["f16subpassInput"] = F16SUBPASSINPUT; (*KeywordMap)["f16subpassInputMS"] = F16SUBPASSINPUTMS; -#endif - - (*KeywordMap)["noperspective"] = NOPERSPECTIVE; - (*KeywordMap)["smooth"] = SMOOTH; - (*KeywordMap)["flat"] = FLAT; -#ifdef AMD_EXTENSIONS (*KeywordMap)["__explicitInterpAMD"] = EXPLICITINTERPAMD; -#endif - (*KeywordMap)["centroid"] = CENTROID; -#ifdef NV_EXTENSIONS (*KeywordMap)["pervertexNV"] = PERVERTEXNV; -#endif (*KeywordMap)["precise"] = PRECISE; - (*KeywordMap)["invariant"] = INVARIANT; - (*KeywordMap)["packed"] = PACKED; - (*KeywordMap)["resource"] = RESOURCE; - (*KeywordMap)["superp"] = SUPERP; -#ifdef NV_EXTENSIONS (*KeywordMap)["rayPayloadNV"] = PAYLOADNV; + (*KeywordMap)["rayPayloadEXT"] = PAYLOADEXT; (*KeywordMap)["rayPayloadInNV"] = PAYLOADINNV; + (*KeywordMap)["rayPayloadInEXT"] = PAYLOADINEXT; (*KeywordMap)["hitAttributeNV"] = HITATTRNV; + (*KeywordMap)["hitAttributeEXT"] = HITATTREXT; (*KeywordMap)["callableDataNV"] = CALLDATANV; + (*KeywordMap)["callableDataEXT"] = CALLDATAEXT; (*KeywordMap)["callableDataInNV"] = CALLDATAINNV; + (*KeywordMap)["callableDataInEXT"] = CALLDATAINEXT; (*KeywordMap)["accelerationStructureNV"] = ACCSTRUCTNV; + (*KeywordMap)["accelerationStructureEXT"] = ACCSTRUCTEXT; + (*KeywordMap)["rayQueryEXT"] = RAYQUERYEXT; (*KeywordMap)["perprimitiveNV"] = PERPRIMITIVENV; (*KeywordMap)["perviewNV"] = PERVIEWNV; (*KeywordMap)["taskNV"] = PERTASKNV; -#endif + + (*KeywordMap)["fcoopmatNV"] = FCOOPMATNV; + (*KeywordMap)["icoopmatNV"] = ICOOPMATNV; + (*KeywordMap)["ucoopmatNV"] = UCOOPMATNV; ReservedSet = new std::unordered_set; @@ -753,14 +801,17 @@ void TScanContext::fillInKeywordMap() ReservedSet->insert("cast"); ReservedSet->insert("namespace"); ReservedSet->insert("using"); +#endif } void TScanContext::deleteKeywordMap() { delete KeywordMap; KeywordMap = nullptr; +#ifndef GLSLANG_WEB delete ReservedSet; ReservedSet = nullptr; +#endif } // Called by yylex to get the next token. @@ -837,15 +888,18 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) parseContext.error(loc, "not supported", "::", ""); break; + case PpAtomConstString: parserToken->sType.lex.string = NewPoolTString(tokenText); return STRING_LITERAL; case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; + case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; +#ifndef GLSLANG_WEB case PpAtomConstInt16: parserToken->sType.lex.i = ppToken.ival; return INT16CONSTANT; case PpAtomConstUint16: parserToken->sType.lex.i = ppToken.ival; return UINT16CONSTANT; case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT; case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT; - case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT; case PpAtomConstFloat16: parserToken->sType.lex.d = ppToken.dval; return FLOAT16CONSTANT; +#endif case PpAtomIdentifier: { int token = tokenizeIdentifier(); @@ -867,8 +921,10 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) int TScanContext::tokenizeIdentifier() { +#ifndef GLSLANG_WEB if (ReservedSet->find(tokenText) != ReservedSet->end()) return reservedWord(); +#endif auto it = KeywordMap->find(tokenText); if (it == KeywordMap->end()) { @@ -895,20 +951,33 @@ int TScanContext::tokenizeIdentifier() case CASE: return keyword; + case TERMINATE_INVOCATION: + if (!parseContext.extensionTurnedOn(E_GL_EXT_terminate_invocation)) + return identifierOrType(); + return keyword; + + case TERMINATE_RAY: + case IGNORE_INTERSECTION: + if (!parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing)) + return identifierOrType(); + return keyword; + + case BUFFER: + afterBuffer = true; + if ((parseContext.isEsProfile() && parseContext.version < 310) || + (!parseContext.isEsProfile() && (parseContext.version < 430 && + !parseContext.extensionTurnedOn(E_GL_ARB_shader_storage_buffer_object)))) + return identifierOrType(); + return keyword; + case STRUCT: afterStruct = true; return keyword; - case NONUNIFORM: - if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier)) - return keyword; - else - return identifierOrType(); - case SWITCH: case DEFAULT: - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 130)) + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 130)) reservedWord(); return keyword; @@ -940,20 +1009,59 @@ int TScanContext::tokenizeIdentifier() parserToken->sType.lex.b = false; return keyword; - case ATTRIBUTE: - case VARYING: - if (parseContext.profile == EEsProfile && parseContext.version >= 300) - reservedWord(); - return keyword; - - case BUFFER: - afterBuffer = true; - if ((parseContext.profile == EEsProfile && parseContext.version < 310) || - (parseContext.profile != EEsProfile && parseContext.version < 430)) + case SMOOTH: + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 130)) return identifierOrType(); return keyword; + case FLAT: + if (parseContext.isEsProfile() && parseContext.version < 300) + reservedWord(); + else if (!parseContext.isEsProfile() && parseContext.version < 130) + return identifierOrType(); + return keyword; + case CENTROID: + if (parseContext.version < 120) + return identifierOrType(); + return keyword; + case INVARIANT: + if (!parseContext.isEsProfile() && parseContext.version < 120) + return identifierOrType(); + return keyword; + case PACKED: + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 140)) + return reservedWord(); + return identifierOrType(); -#ifdef NV_EXTENSIONS + case RESOURCE: + { + bool reserved = (parseContext.isEsProfile() && parseContext.version >= 300) || + (!parseContext.isEsProfile() && parseContext.version >= 420); + return identifierOrReserved(reserved); + } + case SUPERP: + { + bool reserved = parseContext.isEsProfile() || parseContext.version >= 130; + return identifierOrReserved(reserved); + } + +#ifndef GLSLANG_WEB + case NOPERSPECTIVE: + if (parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation)) + return keyword; + return es30ReservedFromGLSL(130); + + case NONUNIFORM: + if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier)) + return keyword; + else + return identifierOrType(); + case ATTRIBUTE: + case VARYING: + if (parseContext.isEsProfile() && parseContext.version >= 300) + reservedWord(); + return keyword; case PAYLOADNV: case PAYLOADINNV: case HITATTRNV: @@ -961,14 +1069,28 @@ int TScanContext::tokenizeIdentifier() case CALLDATAINNV: case ACCSTRUCTNV: if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && parseContext.version >= 460 - && parseContext.extensionTurnedOn(E_GL_NV_ray_tracing))) + parseContext.extensionTurnedOn(E_GL_NV_ray_tracing)) + return keyword; + return identifierOrType(); + case PAYLOADEXT: + case PAYLOADINEXT: + case HITATTREXT: + case CALLDATAEXT: + case CALLDATAINEXT: + case ACCSTRUCTEXT: + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing) || + parseContext.extensionTurnedOn(E_GL_EXT_ray_query)) + return keyword; + return identifierOrType(); + case RAYQUERYEXT: + if (parseContext.symbolTable.atBuiltInLevel() || + (!parseContext.isEsProfile() && parseContext.version >= 460 + && parseContext.extensionTurnedOn(E_GL_EXT_ray_query))) return keyword; return identifierOrType(); -#endif - case ATOMIC_UINT: - if ((parseContext.profile == EEsProfile && parseContext.version >= 310) || + if ((parseContext.isEsProfile() && parseContext.version >= 310) || parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters)) return keyword; return es30ReservedFromGLSL(420); @@ -978,57 +1100,56 @@ int TScanContext::tokenizeIdentifier() case QUEUEFAMILYCOHERENT: case WORKGROUPCOHERENT: case SUBGROUPCOHERENT: + case SHADERCALLCOHERENT: case NONPRIVATE: case RESTRICT: case READONLY: case WRITEONLY: - if (parseContext.profile == EEsProfile && parseContext.version >= 310) + if (parseContext.isEsProfile() && parseContext.version >= 310) return keyword; return es30ReservedFromGLSL(parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store) ? 130 : 420); - case VOLATILE: - if (parseContext.profile == EEsProfile && parseContext.version >= 310) + if (parseContext.isEsProfile() && parseContext.version >= 310) return keyword; - if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile || + if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.isEsProfile() || (parseContext.version < 420 && ! parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) reservedWord(); return keyword; - - case LAYOUT: - { - const int numLayoutExts = 2; - const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack, - E_GL_ARB_explicit_attrib_location }; - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 140 && - ! parseContext.extensionsTurnedOn(numLayoutExts, layoutExts))) - return identifierOrType(); - return keyword; - } - case SHARED: - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 140)) - return identifierOrType(); - return keyword; - case PATCH: if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile == EEsProfile && + (parseContext.isEsProfile() && (parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))) || - (parseContext.profile != EEsProfile && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader))) + (!parseContext.isEsProfile() && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader))) return keyword; return es30ReservedFromGLSL(400); case SAMPLE: - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(1, &E_GL_OES_shader_multisample_interpolation)) return keyword; return es30ReservedFromGLSL(400); case SUBROUTINE: return es30ReservedFromGLSL(400); +#endif + case SHARED: + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 140)) + return identifierOrType(); + return keyword; + case LAYOUT: + { + const int numLayoutExts = 2; + const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack, + E_GL_ARB_explicit_attrib_location }; + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 140 && + ! parseContext.extensionsTurnedOn(numLayoutExts, layoutExts))) + return identifierOrType(); + return keyword; + } case HIGH_PRECISION: case MEDIUM_PRECISION: @@ -1047,6 +1168,7 @@ int TScanContext::tokenizeIdentifier() case MAT4X4: return matNxM(); +#ifndef GLSLANG_WEB case DMAT2: case DMAT3: case DMAT4: @@ -1073,14 +1195,39 @@ int TScanContext::tokenizeIdentifier() afterType = true; return firstGenerationImage(false); + case I64IMAGE1D: + case U64IMAGE1D: + case I64IMAGE1DARRAY: + case U64IMAGE1DARRAY: + case I64IMAGE2DRECT: + case U64IMAGE2DRECT: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64)) { + return firstGenerationImage(false); + } + return identifierOrType(); + case IMAGEBUFFER: case IIMAGEBUFFER: case UIMAGEBUFFER: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) return keyword; return firstGenerationImage(false); + + case I64IMAGEBUFFER: + case U64IMAGEBUFFER: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64)) { + if ((parseContext.isEsProfile() && parseContext.version >= 320) || + parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) + return keyword; + return firstGenerationImage(false); + } + return identifierOrType(); case IMAGE2D: case IIMAGE2D: @@ -1097,14 +1244,40 @@ int TScanContext::tokenizeIdentifier() afterType = true; return firstGenerationImage(true); + case I64IMAGE2D: + case U64IMAGE2D: + case I64IMAGE3D: + case U64IMAGE3D: + case I64IMAGECUBE: + case U64IMAGECUBE: + case I64IMAGE2DARRAY: + case U64IMAGE2DARRAY: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64)) + return firstGenerationImage(true); + return identifierOrType(); + case IMAGECUBEARRAY: case IIMAGECUBEARRAY: case UIMAGECUBEARRAY: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) return keyword; return secondGenerationImage(); + + case I64IMAGECUBEARRAY: + case U64IMAGECUBEARRAY: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64)) { + if ((parseContext.isEsProfile() && parseContext.version >= 320) || + parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) + return keyword; + return secondGenerationImage(); + } + return identifierOrType(); case IMAGE2DMS: case IIMAGE2DMS: @@ -1114,13 +1287,27 @@ int TScanContext::tokenizeIdentifier() case UIMAGE2DMSARRAY: afterType = true; return secondGenerationImage(); + + case I64IMAGE2DMS: + case U64IMAGE2DMS: + case I64IMAGE2DMSARRAY: + case U64IMAGE2DMSARRAY: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64)) { + return secondGenerationImage(); + } + return identifierOrType(); case DOUBLE: case DVEC2: case DVEC3: case DVEC4: afterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) + if (parseContext.isEsProfile() || parseContext.version < 150 || + (!parseContext.symbolTable.atBuiltInLevel() && + (parseContext.version < 400 && !parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) && + (parseContext.version < 410 && !parseContext.extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit))))) reservedWord(); return keyword; @@ -1134,10 +1321,9 @@ int TScanContext::tokenizeIdentifier() case U64VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && parseContext.version >= 450 && - (parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64)))) + parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64)) return keyword; return identifierOrType(); @@ -1151,10 +1337,9 @@ int TScanContext::tokenizeIdentifier() case U8VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8)) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8)) return keyword; return identifierOrType(); @@ -1168,14 +1353,10 @@ int TScanContext::tokenizeIdentifier() case U16VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && parseContext.version >= 450 && - ( -#ifdef AMD_EXTENSIONS - parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) || -#endif - parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16)))) + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16)) return keyword; return identifierOrType(); case INT32_T: @@ -1188,9 +1369,8 @@ int TScanContext::tokenizeIdentifier() case U32VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32)) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32)) return keyword; return identifierOrType(); case FLOAT32_T: @@ -1211,9 +1391,8 @@ int TScanContext::tokenizeIdentifier() case F32MAT4X4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32)) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32)) return keyword; return identifierOrType(); @@ -1235,9 +1414,8 @@ int TScanContext::tokenizeIdentifier() case F64MAT4X4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64)) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64)) return keyword; return identifierOrType(); @@ -1247,14 +1425,10 @@ int TScanContext::tokenizeIdentifier() case F16VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && parseContext.version >= 450 && - ( -#ifdef AMD_EXTENSIONS - parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) || -#endif - parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16)))) + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16)) return keyword; return identifierOrType(); @@ -1273,13 +1447,9 @@ int TScanContext::tokenizeIdentifier() case F16MAT4X4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && parseContext.version >= 450 && - ( -#ifdef AMD_EXTENSIONS - parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) || -#endif - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16)))) + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16)) return keyword; return identifierOrType(); @@ -1289,20 +1459,21 @@ int TScanContext::tokenizeIdentifier() case ISAMPLERCUBEARRAY: case USAMPLERCUBEARRAY: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) return keyword; - if (parseContext.profile == EEsProfile || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array))) + if (parseContext.isEsProfile() || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array))) reservedWord(); return keyword; - case ISAMPLER1D: - case ISAMPLER1DARRAY: - case SAMPLER1DARRAYSHADOW: - case USAMPLER1D: - case USAMPLER1DARRAY: - afterType = true; - return es30ReservedFromGLSL(130); + case TEXTURECUBEARRAY: + case ITEXTURECUBEARRAY: + case UTEXTURECUBEARRAY: + if (parseContext.spvVersion.vulkan > 0) + return keyword; + else + return identifierOrType(); +#endif case UINT: case UVEC2: @@ -1322,6 +1493,49 @@ int TScanContext::tokenizeIdentifier() afterType = true; return nonreservedKeyword(300, 130); + case SAMPLER3D: + afterType = true; + if (parseContext.isEsProfile() && parseContext.version < 300) { + if (!parseContext.extensionTurnedOn(E_GL_OES_texture_3D)) + reservedWord(); + } + return keyword; + + case SAMPLER2DSHADOW: + afterType = true; + if (parseContext.isEsProfile() && parseContext.version < 300) { + if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers)) + reservedWord(); + } + return keyword; + + case TEXTURE2D: + case TEXTURECUBE: + case TEXTURE2DARRAY: + case ITEXTURE2D: + case ITEXTURE3D: + case ITEXTURECUBE: + case ITEXTURE2DARRAY: + case UTEXTURE2D: + case UTEXTURE3D: + case UTEXTURECUBE: + case UTEXTURE2DARRAY: + case TEXTURE3D: + case SAMPLER: + case SAMPLERSHADOW: + if (parseContext.spvVersion.vulkan > 0) + return keyword; + else + return identifierOrType(); + +#ifndef GLSLANG_WEB + case ISAMPLER1D: + case ISAMPLER1DARRAY: + case SAMPLER1DARRAYSHADOW: + case USAMPLER1D: + case USAMPLER1DARRAY: + afterType = true; + return es30ReservedFromGLSL(130); case ISAMPLER2DRECT: case USAMPLER2DRECT: afterType = true; @@ -1329,7 +1543,7 @@ int TScanContext::tokenizeIdentifier() case SAMPLERBUFFER: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) return keyword; return es30ReservedFromGLSL(130); @@ -1337,7 +1551,7 @@ int TScanContext::tokenizeIdentifier() case ISAMPLERBUFFER: case USAMPLERBUFFER: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) return keyword; return es30ReservedFromGLSL(140); @@ -1346,7 +1560,10 @@ int TScanContext::tokenizeIdentifier() case ISAMPLER2DMS: case USAMPLER2DMS: afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version >= 310) + if (parseContext.isEsProfile() && parseContext.version >= 310) + return keyword; + if (!parseContext.isEsProfile() && (parseContext.version > 140 || + (parseContext.version == 140 && parseContext.extensionsTurnedOn(1, &E_GL_ARB_texture_multisample)))) return keyword; return es30ReservedFromGLSL(150); @@ -1354,38 +1571,25 @@ int TScanContext::tokenizeIdentifier() case ISAMPLER2DMSARRAY: case USAMPLER2DMSARRAY: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(1, &E_GL_OES_texture_storage_multisample_2d_array)) return keyword; + if (!parseContext.isEsProfile() && (parseContext.version > 140 || + (parseContext.version == 140 && parseContext.extensionsTurnedOn(1, &E_GL_ARB_texture_multisample)))) + return keyword; return es30ReservedFromGLSL(150); case SAMPLER1D: case SAMPLER1DSHADOW: afterType = true; - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) reservedWord(); return keyword; - case SAMPLER3D: - afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version < 300) { - if (!parseContext.extensionTurnedOn(E_GL_OES_texture_3D)) - reservedWord(); - } - return keyword; - - case SAMPLER2DSHADOW: - afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version < 300) { - if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers)) - reservedWord(); - } - return keyword; - case SAMPLER2DRECT: case SAMPLER2DRECTSHADOW: afterType = true; - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) reservedWord(); else if (parseContext.version < 140 && ! parseContext.symbolTable.atBuiltInLevel() && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_rectangle)) { if (parseContext.relaxedErrors()) @@ -1397,10 +1601,10 @@ int TScanContext::tokenizeIdentifier() case SAMPLER1DARRAY: afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version == 300) + if (parseContext.isEsProfile() && parseContext.version == 300) reservedWord(); - else if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 130)) + else if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 130)) return identifierOrType(); return keyword; @@ -1419,25 +1623,11 @@ int TScanContext::tokenizeIdentifier() return keyword; return identifierOrType(); - case TEXTURE2D: - case TEXTURECUBE: - case TEXTURECUBEARRAY: - case ITEXTURECUBEARRAY: - case UTEXTURECUBEARRAY: case ITEXTURE1DARRAY: case UTEXTURE1D: case ITEXTURE1D: case UTEXTURE1DARRAY: case TEXTUREBUFFER: - case TEXTURE2DARRAY: - case ITEXTURE2D: - case ITEXTURE3D: - case ITEXTURECUBE: - case ITEXTURE2DARRAY: - case UTEXTURE2D: - case UTEXTURE3D: - case UTEXTURECUBE: - case UTEXTURE2DARRAY: case ITEXTURE2DRECT: case UTEXTURE2DRECT: case ITEXTUREBUFFER: @@ -1449,11 +1639,8 @@ int TScanContext::tokenizeIdentifier() case ITEXTURE2DMSARRAY: case UTEXTURE2DMSARRAY: case TEXTURE1D: - case TEXTURE3D: case TEXTURE2DRECT: case TEXTURE1DARRAY: - case SAMPLER: - case SAMPLERSHADOW: if (parseContext.spvVersion.vulkan > 0) return keyword; else @@ -1470,7 +1657,6 @@ int TScanContext::tokenizeIdentifier() else return identifierOrType(); -#ifdef AMD_EXTENSIONS case F16SAMPLER1D: case F16SAMPLER2D: case F16SAMPLER3D: @@ -1518,98 +1704,76 @@ int TScanContext::tokenizeIdentifier() case F16SUBPASSINPUTMS: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch)) return keyword; return identifierOrType(); -#endif - case NOPERSPECTIVE: -#ifdef NV_EXTENSIONS - if (parseContext.profile == EEsProfile && parseContext.version >= 300 && - parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation)) - return keyword; -#endif - return es30ReservedFromGLSL(130); - - case SMOOTH: - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 130)) - return identifierOrType(); - return keyword; - -#ifdef AMD_EXTENSIONS case EXPLICITINTERPAMD: - if (parseContext.profile != EEsProfile && parseContext.version >= 450 && - parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter)) + if (parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter)) return keyword; return identifierOrType(); -#endif -#ifdef NV_EXTENSIONS case PERVERTEXNV: - if (((parseContext.profile != EEsProfile && parseContext.version >= 450) || - (parseContext.profile == EEsProfile && parseContext.version >= 320)) && + if ((!parseContext.isEsProfile() && parseContext.version >= 450) || parseContext.extensionTurnedOn(E_GL_NV_fragment_shader_barycentric)) return keyword; return identifierOrType(); -#endif - - case FLAT: - if (parseContext.profile == EEsProfile && parseContext.version < 300) - reservedWord(); - else if (parseContext.profile != EEsProfile && parseContext.version < 130) - return identifierOrType(); - return keyword; - - case CENTROID: - if (parseContext.version < 120) - return identifierOrType(); - return keyword; case PRECISE: - if ((parseContext.profile == EEsProfile && + if ((parseContext.isEsProfile() && (parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) || - (parseContext.profile != EEsProfile && parseContext.version >= 400)) + (!parseContext.isEsProfile() && parseContext.version >= 400)) return keyword; - if (parseContext.profile == EEsProfile && parseContext.version == 310) { + if (parseContext.isEsProfile() && parseContext.version == 310) { reservedWord(); return keyword; } return identifierOrType(); - case INVARIANT: - if (parseContext.profile != EEsProfile && parseContext.version < 120) - return identifierOrType(); - return keyword; - - case PACKED: - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 330)) - return reservedWord(); - return identifierOrType(); - - case RESOURCE: - { - bool reserved = (parseContext.profile == EEsProfile && parseContext.version >= 300) || - (parseContext.profile != EEsProfile && parseContext.version >= 420); - return identifierOrReserved(reserved); - } - case SUPERP: - { - bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130; - return identifierOrReserved(reserved); - } - -#ifdef NV_EXTENSIONS case PERPRIMITIVENV: case PERVIEWNV: case PERTASKNV: - if ((parseContext.profile != EEsProfile && parseContext.version >= 450) || - (parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((!parseContext.isEsProfile() && parseContext.version >= 450) || + (parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionTurnedOn(E_GL_NV_mesh_shader)) return keyword; return identifierOrType(); + + case FCOOPMATNV: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix)) + return keyword; + return identifierOrType(); + + case UCOOPMATNV: + case ICOOPMATNV: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_NV_integer_cooperative_matrix)) + return keyword; + return identifierOrType(); + + case DEMOTE: + if (parseContext.extensionTurnedOn(E_GL_EXT_demote_to_helper_invocation)) + return keyword; + else + return identifierOrType(); + + case SPIRV_INSTRUCTION: + case SPIRV_EXECUTION_MODE: + case SPIRV_EXECUTION_MODE_ID: + case SPIRV_DECORATE: + case SPIRV_DECORATE_ID: + case SPIRV_DECORATE_STRING: + case SPIRV_TYPE: + case SPIRV_STORAGE_CLASS: + case SPIRV_BY_REFERENCE: + case SPIRV_LITERAL: + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) + return keyword; + return identifierOrType(); #endif default: @@ -1629,7 +1793,7 @@ int TScanContext::identifierOrType() if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) { if (variable->isUserType() && // treat redeclaration of forward-declared buffer/uniform reference as an identifier - !(variable->getType().getBasicType() == EbtReference && afterBuffer)) { + !(variable->getType().isReference() && afterBuffer)) { afterType = true; return TYPE_NAME; @@ -1659,7 +1823,7 @@ int TScanContext::identifierOrReserved(bool reserved) return 0; } - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future reserved keyword", tokenText, ""); return identifierOrType(); @@ -1672,13 +1836,13 @@ int TScanContext::es30ReservedFromGLSL(int version) if (parseContext.symbolTable.atBuiltInLevel()) return keyword; - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < version)) { - if (parseContext.forwardCompatible) + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < version)) { + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, ""); return identifierOrType(); - } else if (parseContext.profile == EEsProfile && parseContext.version >= 300) + } else if (parseContext.isEsProfile() && parseContext.version >= 300) reservedWord(); return keyword; @@ -1688,9 +1852,9 @@ int TScanContext::es30ReservedFromGLSL(int version) // showed up, both in an es version and a non-ES version. int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion) { - if ((parseContext.profile == EEsProfile && parseContext.version < esVersion) || - (parseContext.profile != EEsProfile && parseContext.version < nonEsVersion)) { - if (parseContext.forwardCompatible) + if ((parseContext.isEsProfile() && parseContext.version < esVersion) || + (!parseContext.isEsProfile() && parseContext.version < nonEsVersion)) { + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future keyword", tokenText, ""); return identifierOrType(); @@ -1701,10 +1865,10 @@ int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion) int TScanContext::precisionKeyword() { - if (parseContext.profile == EEsProfile || parseContext.version >= 130) + if (parseContext.isEsProfile() || parseContext.version >= 130) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using ES precision qualifier keyword", tokenText, ""); return identifierOrType(); @@ -1717,7 +1881,7 @@ int TScanContext::matNxM() if (parseContext.version > 110) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future non-square matrix type keyword", tokenText, ""); return identifierOrType(); @@ -1727,16 +1891,20 @@ int TScanContext::dMat() { afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version >= 300) { + if (parseContext.isEsProfile() && parseContext.version >= 300) { reservedWord(); return keyword; } - if (parseContext.profile != EEsProfile && parseContext.version >= 400) + if (!parseContext.isEsProfile() && (parseContext.version >= 400 || + parseContext.symbolTable.atBuiltInLevel() || + (parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64)) || + (parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit) + && parseContext.language == EShLangVertex))) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future type keyword", tokenText, ""); return identifierOrType(); @@ -1745,19 +1913,19 @@ int TScanContext::dMat() int TScanContext::firstGenerationImage(bool inEs310) { if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && (parseContext.version >= 420 || + (!parseContext.isEsProfile() && (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) || - (inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310)) + (inEs310 && parseContext.isEsProfile() && parseContext.version >= 310)) return keyword; - if ((parseContext.profile == EEsProfile && parseContext.version >= 300) || - (parseContext.profile != EEsProfile && parseContext.version >= 130)) { + if ((parseContext.isEsProfile() && parseContext.version >= 300) || + (!parseContext.isEsProfile() && parseContext.version >= 130)) { reservedWord(); return keyword; } - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future type keyword", tokenText, ""); return identifierOrType(); @@ -1765,17 +1933,17 @@ int TScanContext::firstGenerationImage(bool inEs310) int TScanContext::secondGenerationImage() { - if (parseContext.profile == EEsProfile && parseContext.version >= 310) { + if (parseContext.isEsProfile() && parseContext.version >= 310) { reservedWord(); return keyword; } if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && + (!parseContext.isEsProfile() && (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future type keyword", tokenText, ""); return identifierOrType(); diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/ShaderLang.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/ShaderLang.cpp index d6441ef..17902b5 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/ShaderLang.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/ShaderLang.cpp @@ -1,7 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013-2016 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // // All rights reserved. // @@ -51,9 +51,9 @@ #include "ScanContext.h" #ifdef ENABLE_HLSL -#include "../../hlsl/hlslParseHelper.h" -#include "../../hlsl/hlslParseables.h" -#include "../../hlsl/hlslScanContext.h" +#include "../HLSL/hlslParseHelper.h" +#include "../HLSL/hlslParseables.h" +#include "../HLSL/hlslScanContext.h" #endif #include "../Include/ShHandle.h" @@ -72,6 +72,9 @@ // token to print ", but none of that seems appropriate for this file. #include "preprocessor/PpTokens.h" +// Build-time generated includes +#include "../Include/build_info.h" + namespace { // anonymous namespace for file-local functions and symbols // Total number of successful initializers of glslang: a refcount @@ -156,7 +159,7 @@ int MapVersionToIndex(int version) return index; } -const int SpvVersionCount = 3; // index range in MapSpvVersionToIndex +const int SpvVersionCount = 4; // index range in MapSpvVersionToIndex int MapSpvVersionToIndex(const SpvVersion& spvVersion) { @@ -164,8 +167,12 @@ int MapSpvVersionToIndex(const SpvVersion& spvVersion) if (spvVersion.openGl > 0) index = 1; - else if (spvVersion.vulkan > 0) - index = 2; + else if (spvVersion.vulkan > 0) { + if (!spvVersion.vulkanRelaxed) + index = 2; + else + index = 3; + } assert(index < SpvVersionCount); @@ -288,6 +295,14 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables) { +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; +#endif + (*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]); InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source, infoSink, *symbolTables[language]); @@ -304,6 +319,14 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi // bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source) { +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; +#endif + std::unique_ptr builtInParseables(CreateBuiltInParseables(infoSink, source)); if (builtInParseables == nullptr) @@ -326,6 +349,7 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source, infoSink, commonTable, symbolTables); +#ifndef GLSLANG_WEB // check for tessellation if ((profile != EEsProfile && version >= 150) || (profile == EEsProfile && version >= 310)) { @@ -347,20 +371,20 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source, infoSink, commonTable, symbolTables); -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_ANGLE // check for ray tracing stages if (profile != EEsProfile && version >= 450) { - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGen, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersectNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersect, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHitNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHit, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHitNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHit, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMiss, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallableNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallable, source, infoSink, commonTable, symbolTables); } @@ -375,7 +399,8 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS (profile == EEsProfile && version >= 320)) InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source, infoSink, commonTable, symbolTables); -#endif +#endif // !GLSLANG_ANGLE +#endif // !GLSLANG_WEB return true; } @@ -474,6 +499,18 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp glslang::ReleaseGlobalLock(); } +// Function to Print all builtins +void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable) +{ +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + infoSink.debug << "BuiltinSymbolTable {\n"; + + symbolTable.dump(infoSink, true); + + infoSink.debug << "}\n"; +#endif +} + // Return true if the shader was correctly specified for version/profile/stage. bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion, EShSource source, int& version, EProfile& profile, const SpvVersion& spvVersion) @@ -569,6 +606,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo break; } +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Correct for stage type... switch (stage) { case EShLangGeometry: @@ -600,13 +638,12 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo version = profile == EEsProfile ? 310 : 420; } break; -#ifdef NV_EXTENSIONS - case EShLangRayGenNV: - case EShLangIntersectNV: - case EShLangAnyHitNV: - case EShLangClosestHitNV: - case EShLangMissNV: - case EShLangCallableNV: + case EShLangRayGen: + case EShLangIntersect: + case EShLangAnyHit: + case EShLangClosestHit: + case EShLangMiss: + case EShLangCallable: if (profile == EEsProfile || version < 460) { correct = false; infoSink.info.message(EPrefixError, "#version: ray tracing shaders require non-es profile with version 460 or above"); @@ -621,7 +658,6 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above"); version = profile == EEsProfile ? 320 : 450; } -#endif default: break; } @@ -634,15 +670,10 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo // Check for SPIR-V compatibility if (spvVersion.spv != 0) { switch (profile) { - case EEsProfile: - if (spvVersion.vulkan > 0 && version < 310) { + case EEsProfile: + if (version < 310) { correct = false; - infoSink.info.message(EPrefixError, "#version: ES shaders for Vulkan SPIR-V require version 310 or higher"); - version = 310; - } - if (spvVersion.openGl >= 100) { - correct = false; - infoSink.info.message(EPrefixError, "#version: ES shaders for OpenGL SPIR-V are not supported"); + infoSink.info.message(EPrefixError, "#version: ES shaders for SPIR-V require version 310 or higher"); version = 310; } break; @@ -663,6 +694,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo break; } } +#endif return correct; } @@ -695,10 +727,14 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages break; case EShClientVulkan: spvVersion.vulkanGlsl = environment->input.dialectVersion; + spvVersion.vulkanRelaxed = environment->input.vulkanRulesRelaxed; break; case EShClientOpenGL: spvVersion.openGl = environment->input.dialectVersion; break; + case EShClientCount: + assert(0); + break; } switch (environment->input.languageFamily) { case EShSourceNone: @@ -711,6 +747,9 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages source = EShSourceHlsl; messages = static_cast(messages | EShMsgReadHlsl); break; + case EShSourceCount: + assert(0); + break; } } @@ -821,13 +860,17 @@ bool ProcessDeferred( // Get all the stages, languages, clients, and other environment // stuff sorted out. - EShSource source = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl; + EShSource sourceGuess = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl; SpvVersion spvVersion; EShLanguage stage = compiler->getLanguage(); - TranslateEnvironment(environment, messages, source, stage, spvVersion); + TranslateEnvironment(environment, messages, sourceGuess, stage, spvVersion); +#ifdef ENABLE_HLSL + EShSource source = sourceGuess; if (environment != nullptr && environment->target.hlslFunctionality1) intermediate.setHlslFunctionality1(); - +#else + const EShSource source = EShSourceGlsl; +#endif // First, without using the preprocessor or parser, find the #version, so we know what // symbol tables, processing rules, etc. to set up. This does not need the extra strings // outlined above, just the user shader, after the system and user preambles. @@ -840,6 +883,7 @@ bool ProcessDeferred( : userInput.scanVersion(version, profile, versionNotFirstToken); bool versionNotFound = version == 0; if (forceDefaultVersionAndProfile && source == EShSourceGlsl) { +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound && (version != defaultVersion || profile != defaultProfile)) { compiler->infoSink.info << "Warning, (version, profile) forced to be (" @@ -847,7 +891,7 @@ bool ProcessDeferred( << "), while in source code it is (" << version << ", " << ProfileName(profile) << ")\n"; } - +#endif if (versionNotFound) { versionNotFirstToken = false; versionNotFirst = false; @@ -859,7 +903,16 @@ bool ProcessDeferred( bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage, versionNotFirst, defaultVersion, source, version, profile, spvVersion); +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; +#endif + bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst)); +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) bool warnVersionNotFirst = false; if (! versionWillBeError && versionNotFirstToken) { if (messages & EShMsgRelaxedErrors) @@ -867,6 +920,7 @@ bool ProcessDeferred( else versionWillBeError = true; } +#endif intermediate.setSource(source); intermediate.setVersion(version); @@ -875,8 +929,10 @@ bool ProcessDeferred( RecordProcesses(intermediate, messages, sourceEntryPointName); if (spvVersion.vulkan > 0) intermediate.setOriginUpperLeft(); +#ifdef ENABLE_HLSL if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl) intermediate.setHlslOffsets(); +#endif if (messages & EShMsgDebugInfo) { intermediate.setSourceFile(names[numPre]); for (int s = 0; s < numStrings; ++s) { @@ -898,6 +954,9 @@ bool ProcessDeferred( if (cachedTable) symbolTable->adoptLevels(*cachedTable); + if (intermediate.getUniqueId() != 0) + symbolTable->overwriteUniqueId(intermediate.getUniqueId()); + // Add built-in symbols that are potentially context dependent; // they get popped again further down. if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion, @@ -905,6 +964,9 @@ bool ProcessDeferred( return false; } + if (messages & EShMsgBuiltinSymbolTable) + DumpBuiltinSymbolTable(compiler->infoSink, *symbolTable); + // // Now we can process the full shader under proper symbols and rules. // @@ -923,11 +985,13 @@ bool ProcessDeferred( parseContext->setLimits(*resources); if (! goodVersion) parseContext->addError(); +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) if (warnVersionNotFirst) { TSourceLoc loc; loc.init(); parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", ""); } +#endif parseContext->initializeExtensionBehavior(); @@ -955,9 +1019,12 @@ bool ProcessDeferred( bool success = processingContext(*parseContext, ppContext, fullInput, versionWillBeError, *symbolTable, intermediate, optLevel, messages); + intermediate.setUniqueId(symbolTable->getMaxSymbolId()); return success; } +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + // Responsible for keeping track of the most recent source string and line in // the preprocessor and outputting newlines appropriately if the source string // or line changes. @@ -1154,6 +1221,8 @@ struct DoPreprocessing { std::string* outputString; }; +#endif + // DoFullParse is a valid ProcessingConext template argument for fully // parsing the shader. It populates the "intermediate" with the AST. struct DoFullParse{ @@ -1177,13 +1246,16 @@ struct DoFullParse{ parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n"; } +#ifndef GLSLANG_ANGLE if (messages & EShMsgAST) intermediate.output(parseContext.infoSink, true); +#endif return success; } }; +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Take a single compilation unit, and run the preprocessor on it. // Return: True if there were no issues found in preprocessing, // False if during preprocessing any unknown version, pragmas or @@ -1207,15 +1279,17 @@ bool PreprocessDeferred( EShMessages messages, // warnings/errors/AST; things to print out TShader::Includer& includer, TIntermediate& intermediate, // returned tree, etc. - std::string* outputString) + std::string* outputString, + TEnvironment* environment = nullptr) { DoPreprocessing parser(outputString); return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, preamble, optLevel, resources, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, intermediate, parser, - false, includer); + false, includer, "", environment); } +#endif // // do a partial compile on the given strings for a single compilation unit @@ -1636,19 +1710,29 @@ int ShGetUniformLocation(const ShHandle handle, const char* name) namespace glslang { -#include "../Include/revision.h" +Version GetVersion() +{ + Version version; + version.major = GLSLANG_VERSION_MAJOR; + version.minor = GLSLANG_VERSION_MINOR; + version.patch = GLSLANG_VERSION_PATCH; + version.flavor = GLSLANG_VERSION_FLAVOR; + return version; +} #define QUOTE(s) #s #define STR(n) QUOTE(n) const char* GetEsslVersionString() { - return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL); + return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_VERSION_MAJOR) "." STR(GLSLANG_VERSION_MINOR) "." STR( + GLSLANG_VERSION_PATCH) GLSLANG_VERSION_FLAVOR; } const char* GetGlslVersionString() { - return "4.60 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL); + return "4.60 glslang Khronos. " STR(GLSLANG_VERSION_MAJOR) "." STR(GLSLANG_VERSION_MINOR) "." STR( + GLSLANG_VERSION_PATCH) GLSLANG_VERSION_FLAVOR; } int GetKhronosToolId() @@ -1683,6 +1767,7 @@ TShader::TShader(EShLanguage s) // clear environment (avoid constructors in them for use in a C interface) environment.input.languageFamily = EShSourceNone; environment.input.dialect = EShClientNone; + environment.input.vulkanRulesRelaxed = false; environment.client.client = EShClientNone; environment.target.language = EShTargetNone; environment.target.hlslFunctionality1 = false; @@ -1729,11 +1814,23 @@ void TShader::setSourceEntryPoint(const char* name) sourceEntryPointName = name; } +// Log initial settings and transforms. +// See comment for class TProcesses. void TShader::addProcesses(const std::vector& p) { intermediate->addProcesses(p); } +void TShader::setUniqueId(unsigned long long id) +{ + intermediate->setUniqueId(id); +} + +void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } +void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } + +#ifndef GLSLANG_WEB + // Set binding base for given resource type void TShader::setShiftBinding(TResourceType res, unsigned int base) { intermediate->setShiftBinding(res, base); @@ -1761,7 +1858,7 @@ void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSs // Enables binding automapping using TIoMapper void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); } // Enables position.Y output negation in vertex shader -void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } + // Fragile: currently within one stage: simple auto-assignment of location void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); } void TShader::addUniformLocationOverride(const char* name, int loc) @@ -1772,12 +1869,25 @@ void TShader::setUniformLocationBase(int base) { intermediate->setUniformLocationBase(base); } -// See comment above TDefaultHlslIoMapper in iomapper.cpp: -void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } -void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); } void TShader::setResourceSetBinding(const std::vector& base) { intermediate->setResourceSetBinding(base); } void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); } +#endif + +void TShader::addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) { intermediate->addBlockStorageOverride(nameStr, backing); } + +void TShader::setGlobalUniformBlockName(const char* name) { intermediate->setGlobalUniformBlockName(name); } +void TShader::setGlobalUniformSet(unsigned int set) { intermediate->setGlobalUniformSet(set); } +void TShader::setGlobalUniformBinding(unsigned int binding) { intermediate->setGlobalUniformBinding(binding); } + +void TShader::setAtomicCounterBlockName(const char* name) { intermediate->setAtomicCounterBlockName(name); } +void TShader::setAtomicCounterBlockSet(unsigned int set) { intermediate->setAtomicCounterBlockSet(set); } + +#ifdef ENABLE_HLSL +// See comment above TDefaultHlslIoMapper in iomapper.cpp: +void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } +void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } +#endif // // Turn the shader strings into a parse tree in the TIntermediate. @@ -1801,6 +1911,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion &environment); } +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Fill in a string with the result of preprocessing ShaderStrings // Returns true if all extensions, pragmas and version strings were valid. // @@ -1823,8 +1934,10 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources, return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, EShOptNone, builtInResources, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, - forwardCompatible, message, includer, *intermediate, output_string); + forwardCompatible, message, includer, *intermediate, output_string, + &environment); } +#endif const char* TShader::getInfoLog() { @@ -1836,7 +1949,11 @@ const char* TShader::getInfoDebugLog() return infoSink->debug.c_str(); } -TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false) +TProgram::TProgram() : +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + reflection(0), +#endif + linked(false) { pool = new TPoolAllocator; infoSink = new TInfoSink; @@ -1848,9 +1965,10 @@ TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false) TProgram::~TProgram() { - delete ioMapper; delete infoSink; +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) delete reflection; +#endif for (int s = 0; s < EShLangCount; ++s) if (newedIntermediate[s]) @@ -1880,7 +1998,10 @@ bool TProgram::link(EShMessages messages) error = true; } - // TODO: Link: cross-stage error checking + if (!error) { + if (! crossStageCheck(messages)) + error = true; + } return ! error; } @@ -1895,6 +2016,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) if (stages[stage].size() == 0) return true; +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) int numEsShaders = 0, numNonEsShaders = 0; for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) { if ((*it)->intermediate->getProfile() == EEsProfile) { @@ -1923,7 +2045,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) intermediate[stage] = new TIntermediate(stage, firstIntermediate->getVersion(), firstIntermediate->getProfile()); - + intermediate[stage]->setLimits(firstIntermediate->getLimits()); // The new TIntermediate must use the same origin as the original TIntermediates. // Otherwise linking will fail due to different coordinate systems. @@ -1943,15 +2065,82 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) for (it = stages[stage].begin(); it != stages[stage].end(); ++it) intermediate[stage]->merge(*infoSink, *(*it)->intermediate); } - +#else + intermediate[stage] = stages[stage].front()->intermediate; +#endif intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0); +#ifndef GLSLANG_ANGLE if (messages & EShMsgAST) intermediate[stage]->output(*infoSink, true); +#endif return intermediate[stage]->getNumErrors() == 0; } +// +// Check that there are no errors in linker objects accross stages +// +// Return true if no errors. +// +bool TProgram::crossStageCheck(EShMessages) { + + // make temporary intermediates to hold the linkage symbols for each linking interface + // while we do the checks + // Independent interfaces are: + // all uniform variables and blocks + // all buffer blocks + // all in/out on a stage boundary + + TVector activeStages; + for (int s = 0; s < EShLangCount; ++s) { + if (intermediate[s]) + activeStages.push_back(intermediate[s]); + } + + // no extra linking if there is only one stage + if (! (activeStages.size() > 1)) + return true; + + // setup temporary tree to hold unfirom objects from different stages + TIntermediate* firstIntermediate = activeStages.front(); + TIntermediate uniforms(EShLangCount, + firstIntermediate->getVersion(), + firstIntermediate->getProfile()); + uniforms.setSpv(firstIntermediate->getSpv()); + + TIntermAggregate uniformObjects(EOpLinkerObjects); + TIntermAggregate root(EOpSequence); + root.getSequence().push_back(&uniformObjects); + uniforms.setTreeRoot(&root); + + bool error = false; + + // merge uniforms from all stages into a single intermediate + for (unsigned int i = 0; i < activeStages.size(); ++i) { + uniforms.mergeUniformObjects(*infoSink, *activeStages[i]); + } + error |= uniforms.getNumErrors() != 0; + + // copy final definition of global block back into each stage + for (unsigned int i = 0; i < activeStages.size(); ++i) { + // We only want to merge into already existing global uniform blocks. + // A stage that doesn't already know about the global doesn't care about it's content. + // Otherwise we end up pointing to the same object between different stages + // and that will break binding/set remappings + bool mergeExistingOnly = true; + activeStages[i]->mergeGlobalUniformBlocks(*infoSink, uniforms, mergeExistingOnly); + } + + // compare cross stage symbols for each stage boundary + for (unsigned int i = 1; i < activeStages.size(); ++i) { + activeStages[i - 1]->checkStageIO(*infoSink, *activeStages[i]); + error |= (activeStages[i - 1]->getNumErrors() != 0); + } + + return !error; +} + const char* TProgram::getInfoLog() { return infoSink->info.c_str(); @@ -1962,16 +2151,33 @@ const char* TProgram::getInfoDebugLog() return infoSink->debug.c_str(); } +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + // // Reflection implementation. // -bool TProgram::buildReflection() +bool TProgram::buildReflection(int opts) { - if (! linked || reflection) + if (! linked || reflection != nullptr) return false; - reflection = new TReflection; + int firstStage = EShLangVertex, lastStage = EShLangFragment; + + if (opts & EShReflectionIntermediateIO) { + // if we're reflecting intermediate I/O, determine the first and last stage linked and use those as the + // boundaries for which stages generate pipeline inputs/outputs + firstStage = EShLangCount; + lastStage = 0; + for (int s = 0; s < EShLangCount; ++s) { + if (intermediate[s]) { + firstStage = std::min(firstStage, s); + lastStage = std::max(lastStage, s); + } + } + } + + reflection = new TReflection((EShReflectionOptions)opts, (EShLanguage)firstStage, (EShLanguage)lastStage); for (int s = 0; s < EShLangCount; ++s) { if (intermediate[s]) { @@ -1983,48 +2189,50 @@ bool TProgram::buildReflection() return true; } -int TProgram::getNumLiveUniformVariables() const { return reflection->getNumUniforms(); } -int TProgram::getNumLiveUniformBlocks() const { return reflection->getNumUniformBlocks(); } -const char* TProgram::getUniformName(int index) const { return reflection->getUniform(index).name.c_str(); } -const char* TProgram::getUniformBlockName(int index) const { return reflection->getUniformBlock(index).name.c_str(); } -int TProgram::getUniformBlockSize(int index) const { return reflection->getUniformBlock(index).size; } -int TProgram::getUniformIndex(const char* name) const { return reflection->getIndex(name); } -int TProgram::getUniformBinding(int index) const { return reflection->getUniform(index).getBinding(); } -EShLanguageMask TProgram::getUniformStages(int index) const { return reflection->getUniform(index).stages; } -int TProgram::getUniformBlockBinding(int index) const { return reflection->getUniformBlock(index).getBinding(); } -int TProgram::getUniformBlockIndex(int index) const { return reflection->getUniform(index).index; } -int TProgram::getUniformBlockCounterIndex(int index) const { return reflection->getUniformBlock(index).counterIndex; } -int TProgram::getUniformType(int index) const { return reflection->getUniform(index).glDefineType; } -int TProgram::getUniformBufferOffset(int index) const { return reflection->getUniform(index).offset; } -int TProgram::getUniformArraySize(int index) const { return reflection->getUniform(index).size; } -int TProgram::getNumLiveAttributes() const { return reflection->getNumAttributes(); } -const char* TProgram::getAttributeName(int index) const { return reflection->getAttribute(index).name.c_str(); } -int TProgram::getAttributeType(int index) const { return reflection->getAttribute(index).glDefineType; } -const TType* TProgram::getAttributeTType(int index) const { return reflection->getAttribute(index).getType(); } -const TType* TProgram::getUniformTType(int index) const { return reflection->getUniform(index).getType(); } -const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); } -unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); } +unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); } +int TProgram::getReflectionIndex(const char* name) const { return reflection->getIndex(name); } +int TProgram::getReflectionPipeIOIndex(const char* name, const bool inOrOut) const + { return reflection->getPipeIOIndex(name, inOrOut); } -void TProgram::dumpReflection() { reflection->dump(); } +int TProgram::getNumUniformVariables() const { return reflection->getNumUniforms(); } +const TObjectReflection& TProgram::getUniform(int index) const { return reflection->getUniform(index); } +int TProgram::getNumUniformBlocks() const { return reflection->getNumUniformBlocks(); } +const TObjectReflection& TProgram::getUniformBlock(int index) const { return reflection->getUniformBlock(index); } +int TProgram::getNumPipeInputs() const { return reflection->getNumPipeInputs(); } +const TObjectReflection& TProgram::getPipeInput(int index) const { return reflection->getPipeInput(index); } +int TProgram::getNumPipeOutputs() const { return reflection->getNumPipeOutputs(); } +const TObjectReflection& TProgram::getPipeOutput(int index) const { return reflection->getPipeOutput(index); } +int TProgram::getNumBufferVariables() const { return reflection->getNumBufferVariables(); } +const TObjectReflection& TProgram::getBufferVariable(int index) const { return reflection->getBufferVariable(index); } +int TProgram::getNumBufferBlocks() const { return reflection->getNumStorageBuffers(); } +const TObjectReflection& TProgram::getBufferBlock(int index) const { return reflection->getStorageBufferBlock(index); } +int TProgram::getNumAtomicCounters() const { return reflection->getNumAtomicCounters(); } +const TObjectReflection& TProgram::getAtomicCounter(int index) const { return reflection->getAtomicCounter(index); } +void TProgram::dumpReflection() { if (reflection != nullptr) reflection->dump(); } // // I/O mapping implementation. // -bool TProgram::mapIO(TIoMapResolver* resolver) +bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper) { - if (! linked || ioMapper) + if (! linked) return false; - - ioMapper = new TIoMapper; - + TIoMapper* ioMapper = nullptr; + TIoMapper defaultIOMapper; + if (pIoMapper == nullptr) + ioMapper = &defaultIOMapper; + else + ioMapper = pIoMapper; for (int s = 0; s < EShLangCount; ++s) { if (intermediate[s]) { - if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, resolver)) + if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, pResolver)) return false; } } - return true; + return ioMapper->doMap(pResolver, *infoSink); } +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE + } // end namespace glslang diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/SpirvIntrinsics.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/SpirvIntrinsics.cpp new file mode 100644 index 0000000..38094ea --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/SpirvIntrinsics.cpp @@ -0,0 +1,355 @@ +// +// Copyright(C) 2021 Advanced Micro Devices, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef GLSLANG_WEB + +// +// GL_EXT_spirv_intrinsics +// +#include "../Include/intermediate.h" +#include "../Include/SpirvIntrinsics.h" +#include "../Include/Types.h" +#include "ParseHelper.h" + +namespace glslang { + +// +// Handle SPIR-V requirements +// +TSpirvRequirement* TParseContext::makeSpirvRequirement(const TSourceLoc& loc, const TString& name, + const TIntermAggregate* extensions, + const TIntermAggregate* capabilities) +{ + TSpirvRequirement* spirvReq = new TSpirvRequirement; + + if (name == "extensions") { + assert(extensions); + for (auto extension : extensions->getSequence()) { + assert(extension->getAsConstantUnion()); + spirvReq->extensions.insert(*extension->getAsConstantUnion()->getConstArray()[0].getSConst()); + } + } else if (name == "capabilities") { + assert(capabilities); + for (auto capability : capabilities->getSequence()) { + assert(capability->getAsConstantUnion()); + spirvReq->capabilities.insert(capability->getAsConstantUnion()->getConstArray()[0].getIConst()); + } + } else + error(loc, "unknow SPIR-V requirement", name.c_str(), ""); + + return spirvReq; +} + +TSpirvRequirement* TParseContext::mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1, + TSpirvRequirement* spirvReq2) +{ + // Merge the second SPIR-V requirement to the first one + if (!spirvReq2->extensions.empty()) { + if (spirvReq1->extensions.empty()) + spirvReq1->extensions = spirvReq2->extensions; + else + error(loc, "too many SPIR-V requirements", "extensions", ""); + } + + if (!spirvReq2->capabilities.empty()) { + if (spirvReq1->capabilities.empty()) + spirvReq1->capabilities = spirvReq2->capabilities; + else + error(loc, "too many SPIR-V requirements", "capabilities", ""); + } + + return spirvReq1; +} + +void TIntermediate::insertSpirvRequirement(const TSpirvRequirement* spirvReq) +{ + if (!spirvRequirement) + spirvRequirement = new TSpirvRequirement; + + for (auto extension : spirvReq->extensions) + spirvRequirement->extensions.insert(extension); + + for (auto capability : spirvReq->capabilities) + spirvRequirement->capabilities.insert(capability); +} + +// +// Handle SPIR-V execution modes +// +void TIntermediate::insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args) +{ + if (!spirvExecutionMode) + spirvExecutionMode = new TSpirvExecutionMode; + + TVector extraOperands; + if (args) { + for (auto arg : args->getSequence()) { + auto extraOperand = arg->getAsConstantUnion(); + assert(extraOperand != nullptr); + extraOperands.push_back(extraOperand); + } + } + spirvExecutionMode->modes[executionMode] = extraOperands; +} + +void TIntermediate::insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args) +{ + if (!spirvExecutionMode) + spirvExecutionMode = new TSpirvExecutionMode; + + assert(args); + TVector extraOperands; + + for (auto arg : args->getSequence()) { + auto extraOperand = arg->getAsConstantUnion(); + assert(extraOperand != nullptr); + extraOperands.push_back(extraOperand); + } + spirvExecutionMode->modeIds[executionMode] = extraOperands; +} + +// +// Handle SPIR-V decorate qualifiers +// +void TQualifier::setSpirvDecorate(int decoration, const TIntermAggregate* args) +{ + if (!spirvDecorate) + spirvDecorate = new TSpirvDecorate; + + TVector extraOperands; + if (args) { + for (auto arg : args->getSequence()) { + auto extraOperand = arg->getAsConstantUnion(); + assert(extraOperand != nullptr); + extraOperands.push_back(extraOperand); + } + } + spirvDecorate->decorates[decoration] = extraOperands; +} + +void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args) +{ + if (!spirvDecorate) + spirvDecorate = new TSpirvDecorate; + + assert(args); + TVector extraOperands; + for (auto arg : args->getSequence()) { + auto extraOperand = arg->getAsConstantUnion(); + assert(extraOperand != nullptr); + extraOperands.push_back(extraOperand); + } + spirvDecorate->decorateIds[decoration] = extraOperands; +} + +void TQualifier::setSpirvDecorateString(int decoration, const TIntermAggregate* args) +{ + if (!spirvDecorate) + spirvDecorate = new TSpirvDecorate; + + assert(args); + TVector extraOperands; + for (auto arg : args->getSequence()) { + auto extraOperand = arg->getAsConstantUnion(); + assert(extraOperand != nullptr); + extraOperands.push_back(extraOperand); + } + spirvDecorate->decorateStrings[decoration] = extraOperands; +} + +TString TQualifier::getSpirvDecorateQualifierString() const +{ + assert(spirvDecorate); + + TString qualifierString; + + const auto appendFloat = [&](float f) { qualifierString.append(std::to_string(f).c_str()); }; + const auto appendInt = [&](int i) { qualifierString.append(std::to_string(i).c_str()); }; + const auto appendUint = [&](unsigned int u) { qualifierString.append(std::to_string(u).c_str()); }; + const auto appendBool = [&](bool b) { qualifierString.append(std::to_string(b).c_str()); }; + const auto appendStr = [&](const char* s) { qualifierString.append(s); }; + + const auto appendDecorate = [&](const TIntermConstantUnion* constant) { + if (constant->getBasicType() == EbtFloat) { + float value = static_cast(constant->getConstArray()[0].getDConst()); + appendFloat(value); + } + else if (constant->getBasicType() == EbtInt) { + int value = constant->getConstArray()[0].getIConst(); + appendInt(value); + } + else if (constant->getBasicType() == EbtUint) { + unsigned value = constant->getConstArray()[0].getUConst(); + appendUint(value); + } + else if (constant->getBasicType() == EbtBool) { + bool value = constant->getConstArray()[0].getBConst(); + appendBool(value); + } + else if (constant->getBasicType() == EbtString) { + const TString* value = constant->getConstArray()[0].getSConst(); + appendStr(value->c_str()); + } + else + assert(0); + }; + + for (auto& decorate : spirvDecorate->decorates) { + appendStr("spirv_decorate("); + appendInt(decorate.first); + for (auto extraOperand : decorate.second) { + appendStr(", "); + appendDecorate(extraOperand); + } + appendStr(") "); + } + + for (auto& decorateId : spirvDecorate->decorateIds) { + appendStr("spirv_decorate_id("); + appendInt(decorateId.first); + for (auto extraOperand : decorateId.second) { + appendStr(", "); + appendDecorate(extraOperand); + } + appendStr(") "); + } + + for (auto& decorateString : spirvDecorate->decorateStrings) { + appendStr("spirv_decorate_string("); + appendInt(decorateString.first); + for (auto extraOperand : decorateString.second) { + appendStr(", "); + appendDecorate(extraOperand); + } + appendStr(") "); + } + + return qualifierString; +} + +// +// Handle SPIR-V type specifiers +// +void TPublicType::setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams) +{ + if (!spirvType) + spirvType = new TSpirvType; + + basicType = EbtSpirvType; + spirvType->spirvInst = spirvInst; + if (typeParams) + spirvType->typeParams = *typeParams; +} + +TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant) +{ + TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters; + if (constant->getBasicType() != EbtFloat && + constant->getBasicType() != EbtInt && + constant->getBasicType() != EbtUint && + constant->getBasicType() != EbtBool && + constant->getBasicType() != EbtString) + error(loc, "this type not allowed", constant->getType().getBasicString(), ""); + else { + assert(constant); + spirvTypeParams->push_back(TSpirvTypeParameter(constant)); + } + + return spirvTypeParams; +} + +TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TPublicType& type) +{ + TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters; + spirvTypeParams->push_back(TSpirvTypeParameter(new TType(type))); + return spirvTypeParams; +} + +TSpirvTypeParameters* TParseContext::mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2) +{ + // Merge SPIR-V type parameters of the second one to the first one + for (const auto& spirvTypeParam : *spirvTypeParams2) + spirvTypeParams1->push_back(spirvTypeParam); + return spirvTypeParams1; +} + +// +// Handle SPIR-V instruction qualifiers +// +TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value) +{ + TSpirvInstruction* spirvInst = new TSpirvInstruction; + if (name == "set") + spirvInst->set = value; + else + error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), ""); + + return spirvInst; +} + +TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value) +{ + TSpirvInstruction* spirvInstuction = new TSpirvInstruction; + if (name == "id") + spirvInstuction->id = value; + else + error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), ""); + + return spirvInstuction; +} + +TSpirvInstruction* TParseContext::mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1, TSpirvInstruction* spirvInst2) +{ + // Merge qualifiers of the second SPIR-V instruction to those of the first one + if (!spirvInst2->set.empty()) { + if (spirvInst1->set.empty()) + spirvInst1->set = spirvInst2->set; + else + error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(set)"); + } + + if (spirvInst2->id != -1) { + if (spirvInst1->id == -1) + spirvInst1->id = spirvInst2->id; + else + error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(id)"); + } + + return spirvInst1; +} + +} // end namespace glslang + +#endif // GLSLANG_WEB diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/SymbolTable.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/SymbolTable.cpp index d8d6846..747b436 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/SymbolTable.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/SymbolTable.cpp @@ -3,6 +3,7 @@ // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. // Copyright (C) 2015-2018 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -61,63 +62,70 @@ void TType::buildMangledName(TString& mangledName) const switch (basicType) { case EbtFloat: mangledName += 'f'; break; - case EbtDouble: mangledName += 'd'; break; - case EbtFloat16: mangledName += "f16"; break; case EbtInt: mangledName += 'i'; break; case EbtUint: mangledName += 'u'; break; + case EbtBool: mangledName += 'b'; break; +#ifndef GLSLANG_WEB + case EbtDouble: mangledName += 'd'; break; + case EbtFloat16: mangledName += "f16"; break; case EbtInt8: mangledName += "i8"; break; case EbtUint8: mangledName += "u8"; break; case EbtInt16: mangledName += "i16"; break; case EbtUint16: mangledName += "u16"; break; case EbtInt64: mangledName += "i64"; break; case EbtUint64: mangledName += "u64"; break; - case EbtBool: mangledName += 'b'; break; case EbtAtomicUint: mangledName += "au"; break; -#ifdef NV_EXTENSIONS - case EbtAccStructNV: mangledName += "asnv"; break; + case EbtAccStruct: mangledName += "as"; break; + case EbtRayQuery: mangledName += "rq"; break; + case EbtSpirvType: mangledName += "spv-t"; break; #endif case EbtSampler: switch (sampler.type) { -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB case EbtFloat16: mangledName += "f16"; break; #endif case EbtInt: mangledName += "i"; break; case EbtUint: mangledName += "u"; break; + case EbtInt64: mangledName += "i64"; break; + case EbtUint64: mangledName += "u64"; break; default: break; // some compilers want this } - if (sampler.image) - mangledName += "I"; // a normal image - else if (sampler.sampler) + if (sampler.isImageClass()) + mangledName += "I"; // a normal image or subpass + else if (sampler.isPureSampler()) mangledName += "p"; // a "pure" sampler - else if (!sampler.combined) + else if (!sampler.isCombined()) mangledName += "t"; // a "pure" texture else mangledName += "s"; // traditional combined sampler - if (sampler.arrayed) + if (sampler.isArrayed()) mangledName += "A"; - if (sampler.shadow) + if (sampler.isShadow()) mangledName += "S"; - if (sampler.external) + if (sampler.isExternal()) mangledName += "E"; - if (sampler.yuv) + if (sampler.isYuv()) mangledName += "Y"; switch (sampler.dim) { - case Esd1D: mangledName += "1"; break; case Esd2D: mangledName += "2"; break; case Esd3D: mangledName += "3"; break; case EsdCube: mangledName += "C"; break; +#ifndef GLSLANG_WEB + case Esd1D: mangledName += "1"; break; case EsdRect: mangledName += "R2"; break; case EsdBuffer: mangledName += "B"; break; case EsdSubpass: mangledName += "P"; break; +#endif default: break; // some compilers want this } +#ifdef ENABLE_HLSL if (sampler.hasReturnStruct()) { // Name mangle for sampler return struct uses struct table index. mangledName += "-tx-struct"; char text[16]; // plenty enough space for the small integers. - snprintf(text, sizeof(text), "%d-", sampler.structReturnIndex); + snprintf(text, sizeof(text), "%u-", sampler.getStructReturnIndex()); mangledName += text; } else { switch (sampler.getVectorSize()) { @@ -127,8 +135,9 @@ void TType::buildMangledName(TString& mangledName) const case 4: break; // default to prior name mangle behavior } } +#endif - if (sampler.ms) + if (sampler.isMultiSample()) mangledName += "M"; break; case EbtStruct: @@ -140,6 +149,8 @@ void TType::buildMangledName(TString& mangledName) const if (typeName) mangledName += *typeName; for (unsigned int i = 0; i < structure->size(); ++i) { + if ((*structure)[i].type->getBasicType() == EbtVoid) + continue; mangledName += '-'; (*structure)[i].type->buildMangledName(mangledName); } @@ -160,7 +171,7 @@ void TType::buildMangledName(TString& mangledName) const for (int i = 0; i < arraySizes->getNumDims(); ++i) { if (arraySizes->getDimNode(i)) { if (arraySizes->getDimNode(i)->getAsSymbolNode()) - snprintf(buf, maxSize, "s%d", arraySizes->getDimNode(i)->getAsSymbolNode()->getId()); + snprintf(buf, maxSize, "s%lld", arraySizes->getDimNode(i)->getAsSymbolNode()->getId()); else snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i)); } else @@ -172,44 +183,88 @@ void TType::buildMangledName(TString& mangledName) const } } +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + // // Dump functions. // -void TVariable::dump(TInfoSink& infoSink) const +void TSymbol::dumpExtensions(TInfoSink& infoSink) const { - infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicTypeString(); - if (type.isArray()) { - infoSink.debug << "[0]"; + int numExtensions = getNumExtensions(); + if (numExtensions) { + infoSink.debug << " <"; + + for (int i = 0; i < numExtensions; i++) + infoSink.debug << getExtensions()[i] << ","; + + infoSink.debug << ">"; } +} + +void TVariable::dump(TInfoSink& infoSink, bool complete) const +{ + if (complete) { + infoSink.debug << getName().c_str() << ": " << type.getCompleteString(); + dumpExtensions(infoSink); + } else { + infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " + << type.getBasicTypeString(); + + if (type.isArray()) + infoSink.debug << "[0]"; + } + infoSink.debug << "\n"; } -void TFunction::dump(TInfoSink& infoSink) const +void TFunction::dump(TInfoSink& infoSink, bool complete) const { - infoSink.debug << getName().c_str() << ": " << returnType.getBasicTypeString() << " " << getMangledName().c_str() << "\n"; + if (complete) { + infoSink.debug << getName().c_str() << ": " << returnType.getCompleteString() << " " << getName().c_str() + << "("; + + int numParams = getParamCount(); + for (int i = 0; i < numParams; i++) { + const TParameter ¶m = parameters[i]; + infoSink.debug << param.type->getCompleteString() << " " + << (param.type->isStruct() ? "of " + param.type->getTypeName() + " " : "") + << (param.name ? *param.name : "") << (i < numParams - 1 ? "," : ""); + } + + infoSink.debug << ")"; + dumpExtensions(infoSink); + } else { + infoSink.debug << getName().c_str() << ": " << returnType.getBasicTypeString() << " " + << getMangledName().c_str() << "n"; + } + + infoSink.debug << "\n"; } -void TAnonMember::dump(TInfoSink& TInfoSink) const +void TAnonMember::dump(TInfoSink& TInfoSink, bool) const { - TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str() << "\n"; + TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str() + << "\n"; } -void TSymbolTableLevel::dump(TInfoSink &infoSink) const +void TSymbolTableLevel::dump(TInfoSink& infoSink, bool complete) const { tLevel::const_iterator it; for (it = level.begin(); it != level.end(); ++it) - (*it).second->dump(infoSink); + (*it).second->dump(infoSink, complete); } -void TSymbolTable::dump(TInfoSink &infoSink) const +void TSymbolTable::dump(TInfoSink& infoSink, bool complete) const { for (int level = currentLevel(); level >= 0; --level) { infoSink.debug << "LEVEL " << level << "\n"; - table[level]->dump(infoSink); + table[level]->dump(infoSink, complete); } } +#endif + // // Functions have buried pointers to delete. // @@ -336,6 +391,9 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf) implicitThis = copyOf.implicitThis; illegalImplicitThis = copyOf.illegalImplicitThis; defaultParamCount = copyOf.defaultParamCount; +#ifndef GLSLANG_WEB + spirvInst = copyOf.spirvInst; +#endif } TFunction* TFunction::clone() const diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/SymbolTable.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/SymbolTable.h index f9c1903..2196093 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/SymbolTable.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/SymbolTable.h @@ -104,8 +104,8 @@ public: virtual const TAnonMember* getAsAnonMember() const { return 0; } virtual const TType& getType() const = 0; virtual TType& getWritableType() = 0; - virtual void setUniqueId(int id) { uniqueId = id; } - virtual int getUniqueId() const { return uniqueId; } + virtual void setUniqueId(long long id) { uniqueId = id; } + virtual long long getUniqueId() const { return uniqueId; } virtual void setExtensions(int numExts, const char* const exts[]) { assert(extensions == 0); @@ -116,7 +116,11 @@ public: } virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); } virtual const char** getExtensions() const { return extensions->data(); } - virtual void dump(TInfoSink &infoSink) const = 0; + +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0; + void dumpExtensions(TInfoSink& infoSink) const; +#endif virtual bool isReadOnly() const { return ! writable; } virtual void makeReadOnly() { writable = false; } @@ -126,7 +130,7 @@ protected: TSymbol& operator=(const TSymbol&); const TString *name; - unsigned int uniqueId; // For cross-scope comparing during code generation + unsigned long long uniqueId; // For cross-scope comparing during code generation // For tracking what extensions must be present // (don't use if correct version/profile is present). @@ -192,7 +196,9 @@ public: } virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); } - virtual void dump(TInfoSink &infoSink) const; +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + virtual void dump(TInfoSink& infoSink, bool complete = false) const; +#endif protected: explicit TVariable(const TVariable&); @@ -313,7 +319,18 @@ public: virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; } virtual const TParameter& operator[](int i) const { return parameters[i]; } - virtual void dump(TInfoSink &infoSink) const override; +#ifndef GLSLANG_WEB + virtual void setSpirvInstruction(const TSpirvInstruction& inst) + { + relateToOperator(EOpSpirvInst); + spirvInst = inst; + } + virtual const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; } +#endif + +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + virtual void dump(TInfoSink& infoSink, bool complete = false) const override; +#endif protected: explicit TFunction(const TFunction&); @@ -334,6 +351,10 @@ protected: // This is important for a static member function that has member variables in scope, // but is not allowed to use them, or see hidden symbols instead. int defaultParamCount; + +#ifndef GLSLANG_WEB + TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers +#endif }; // @@ -373,7 +394,9 @@ public: virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); } virtual int getAnonId() const { return anonId; } - virtual void dump(TInfoSink &infoSink) const override; +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + virtual void dump(TInfoSink& infoSink, bool complete = false) const override; +#endif protected: explicit TAnonMember(const TAnonMember&); @@ -541,7 +564,9 @@ public: void relateToOperator(const char* name, TOperator op); void setFunctionExtensions(const char* name, int num, const char* const extensions[]); - void dump(TInfoSink &infoSink) const; +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + void dump(TInfoSink& infoSink, bool complete = false) const; +#endif TSymbolTableLevel* clone() const; void readOnly(); @@ -600,21 +625,28 @@ public: // 3: user-shader globals // protected: + static const uint32_t LevelFlagBitOffset = 56; static const int globalLevel = 3; - bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels - bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals - bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals + static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels + static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals + static bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals public: bool isEmpty() { return table.size() == 0; } bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); } bool atGlobalLevel() { return isGlobalLevel(currentLevel()); } - + static bool isBuiltInSymbol(long long uniqueId) { + int level = static_cast(uniqueId >> LevelFlagBitOffset); + return isBuiltInLevel(level); + } + static constexpr uint64_t uniqueIdMask = (1LL << LevelFlagBitOffset) - 1; + static const uint32_t MaxLevelInUniqueID = 127; void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; } void setSeparateNameSpaces() { separateNameSpaces = true; } void push() { table.push_back(new TSymbolTableLevel); + updateUniqueIdLevelFlag(); } // Make a new symbol-table level to represent the scope introduced by a structure @@ -627,6 +659,7 @@ public: { assert(thisSymbol.getName().size() == 0); table.push_back(new TSymbolTableLevel); + updateUniqueIdLevelFlag(); table.back()->setThisLevel(); insert(thisSymbol); } @@ -636,6 +669,7 @@ public: table[currentLevel()]->getPreviousDefaultPrecisions(p); delete table.back(); table.pop_back(); + updateUniqueIdLevelFlag(); } // @@ -673,6 +707,16 @@ public: return table[currentLevel()]->amend(symbol, firstNewMember); } + // Update the level info in symbol's unique ID to current level + void amendSymbolIdLevel(TSymbol& symbol) + { + // clamp level to avoid overflow + uint64_t level = (uint32_t)currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel(); + uint64_t symbolId = symbol.getUniqueId(); + symbolId &= uniqueIdMask; + symbolId |= (level << LevelFlagBitOffset); + symbol.setUniqueId(symbolId); + } // // To allocate an internal temporary, which will need to be uniquely // identified by the consumer of the AST, but never need to @@ -841,8 +885,10 @@ public: } } - int getMaxSymbolId() { return uniqueId; } - void dump(TInfoSink &infoSink) const; + long long getMaxSymbolId() { return uniqueId; } +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + void dump(TInfoSink& infoSink, bool complete = false) const; +#endif void copyTable(const TSymbolTable& copyOf); void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); } @@ -853,14 +899,27 @@ public: table[level]->readOnly(); } + // Add current level in the high-bits of unique id + void updateUniqueIdLevelFlag() { + // clamp level to avoid overflow + uint64_t level = (uint32_t)currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel(); + uniqueId &= uniqueIdMask; + uniqueId |= (level << LevelFlagBitOffset); + } + + void overwriteUniqueId(long long id) + { + uniqueId = id; + updateUniqueIdLevelFlag(); + } + protected: TSymbolTable(TSymbolTable&); TSymbolTable& operator=(TSymbolTableLevel&); int currentLevel() const { return static_cast(table.size()) - 1; } - std::vector table; - int uniqueId; // for unique identification in code generation + long long uniqueId; // for unique identification in code generation bool noBuiltInRedeclarations; bool separateNameSpaces; unsigned int adoptedLevels; diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Versions.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Versions.cpp index 708432d..097ee84 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Versions.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Versions.cpp @@ -2,7 +2,8 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -63,6 +64,7 @@ // checkDeprecated() // requireNotRemoved() // requireExtensions() +// extensionRequires() // // Typically, only the first two calls are needed. They go into a code path that // implements Feature F, and will log the proper error/warning messages. Parsing @@ -77,9 +79,11 @@ // const char* const XXX_extension_X = "XXX_extension_X"; // // 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(), -// the first function below: +// the first function below and optionally a entry to extensionData for additional +// error checks: // // extensionBehavior[XXX_extension_X] = EBhDisable; +// (Optional) exts[] = {XXX_extension_X, EShTargetSpv_1_4} // // 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble(): // @@ -139,12 +143,16 @@ // set of extensions that both enable them and are necessary, given the version of the symbol // table. (There is a different symbol table for each version.) // +// 7) If the extension has additional requirements like minimum SPIR-V version required, add them +// to extensionRequires() #include "parseVersions.h" #include "localintermediate.h" namespace glslang { +#ifndef GLSLANG_WEB + // // Initialize all extensions, almost always to 'disable', as once their features // are incorporated into a core version, their features are supported through allowing that @@ -152,6 +160,22 @@ namespace glslang { // void TParseVersions::initializeExtensionBehavior() { + typedef struct { + const char *const extensionName; + EShTargetLanguageVersion minSpvVersion; + } extensionData; + + const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4}, + {E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4} + }; + + for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) { + // Add only extensions which require > spv1.0 to save space in map + if (exts[ii].minSpvVersion > EShTargetSpv_1_0) { + extensionMinSpv[exts[ii].extensionName] = exts[ii].minSpvVersion; + } + } + extensionBehavior[E_GL_OES_texture_3D] = EBhDisable; extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable; extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable; @@ -170,16 +194,20 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_ARB_tessellation_shader] = EBhDisable; extensionBehavior[E_GL_ARB_enhanced_layouts] = EBhDisable; extensionBehavior[E_GL_ARB_texture_cube_map_array] = EBhDisable; + extensionBehavior[E_GL_ARB_texture_multisample] = EBhDisable; extensionBehavior[E_GL_ARB_shader_texture_lod] = EBhDisable; extensionBehavior[E_GL_ARB_explicit_attrib_location] = EBhDisable; + extensionBehavior[E_GL_ARB_explicit_uniform_location] = EBhDisable; extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable; extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_atomic_counter_ops] = EBhDisable; extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable; extensionBehavior[E_GL_ARB_shader_group_vote] = EBhDisable; extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable; extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable; extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable; extensionBehavior[E_GL_ARB_gpu_shader_int64] = EBhDisable; + extensionBehavior[E_GL_ARB_gpu_shader_fp64] = EBhDisable; extensionBehavior[E_GL_ARB_shader_ballot] = EBhDisable; extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable; extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable; @@ -187,6 +215,16 @@ void TParseVersions::initializeExtensionBehavior() // extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members extensionBehavior[E_GL_ARB_post_depth_coverage] = EBhDisable; extensionBehavior[E_GL_ARB_shader_viewport_layer_array] = EBhDisable; + extensionBehavior[E_GL_ARB_fragment_shader_interlock] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_clock] = EBhDisable; + extensionBehavior[E_GL_ARB_uniform_buffer_object] = EBhDisable; + extensionBehavior[E_GL_ARB_sample_shading] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_bit_encoding] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_image_size] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_storage_buffer_object] = EBhDisable; + extensionBehavior[E_GL_ARB_shading_language_packing] = EBhDisable; + extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable; + extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable; extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable; extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable; @@ -209,15 +247,19 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_scalar_block_layout] = EBhDisable; extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable; extensionBehavior[E_GL_EXT_buffer_reference] = EBhDisable; + extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable; + extensionBehavior[E_GL_EXT_buffer_reference_uvec2] = EBhDisable; + extensionBehavior[E_GL_EXT_demote_to_helper_invocation] = EBhDisable; + extensionBehavior[E_GL_EXT_debug_printf] = EBhDisable; extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable; extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable; + extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable; // #line and #include extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable; extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable; -#ifdef AMD_EXTENSIONS extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable; extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable; extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter] = EBhDisable; @@ -228,9 +270,9 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_AMD_shader_image_load_store_lod] = EBhDisable; extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable; extensionBehavior[E_GL_AMD_gpu_shader_half_float_fetch] = EBhDisable; -#endif -#ifdef NV_EXTENSIONS + extensionBehavior[E_GL_INTEL_shader_integer_functions2] = EBhDisable; + extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable; extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable; extensionBehavior[E_GL_NV_viewport_array2] = EBhDisable; @@ -242,11 +284,15 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable; extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable; extensionBehavior[E_GL_NV_ray_tracing] = EBhDisable; + extensionBehavior[E_GL_NV_ray_tracing_motion_blur] = EBhDisable; extensionBehavior[E_GL_NV_fragment_shader_barycentric] = EBhDisable; extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable; extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable; extensionBehavior[E_GL_NV_mesh_shader] = EBhDisable; -#endif + + extensionBehavior[E_GL_NV_cooperative_matrix] = EBhDisable; + extensionBehavior[E_GL_NV_shader_sm_builtins] = EBhDisable; + extensionBehavior[E_GL_NV_integer_cooperative_matrix] = EBhDisable; // AEP extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable; @@ -264,6 +310,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_tessellation_point_size] = EBhDisable; extensionBehavior[E_GL_EXT_texture_buffer] = EBhDisable; extensionBehavior[E_GL_EXT_texture_cube_map_array] = EBhDisable; + extensionBehavior[E_GL_EXT_null_initializer] = EBhDisable; // OES matching AEP extensionBehavior[E_GL_OES_geometry_shader] = EBhDisable; @@ -275,10 +322,22 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_OES_tessellation_point_size] = EBhDisable; extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable; extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_integer_mix] = EBhDisable; // EXT extensions - extensionBehavior[E_GL_EXT_device_group] = EBhDisable; - extensionBehavior[E_GL_EXT_multiview] = EBhDisable; + extensionBehavior[E_GL_EXT_device_group] = EBhDisable; + extensionBehavior[E_GL_EXT_multiview] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_realtime_clock] = EBhDisable; + extensionBehavior[E_GL_EXT_ray_tracing] = EBhDisable; + extensionBehavior[E_GL_EXT_ray_query] = EBhDisable; + extensionBehavior[E_GL_EXT_ray_flags_primitive_culling] = EBhDisable; + extensionBehavior[E_GL_EXT_blend_func_extended] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_implicit_conversions] = EBhDisable; + extensionBehavior[E_GL_EXT_fragment_shading_rate] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_image_int64] = EBhDisable; + extensionBehavior[E_GL_EXT_terminate_invocation] = EBhDisable; + extensionBehavior[E_GL_EXT_shared_memory_block] = EBhDisable; + extensionBehavior[E_GL_EXT_spirv_intrinsics] = EBhDisable; // OVR extensions extensionBehavior[E_GL_OVR_multiview] = EBhDisable; @@ -293,16 +352,29 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float16] = EBhDisable; extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float32] = EBhDisable; extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float64] = EBhDisable; + + // subgroup extended types + extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int8] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int16] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_atomic_float2] = EBhDisable; } +#endif // GLSLANG_WEB + // Get code that is not part of a shared symbol table, is specific to this shader, // or needed by the preprocessor (which does not use a shared symbol table). void TParseVersions::getPreamble(std::string& preamble) { - if (profile == EEsProfile) { + if (isEsProfile()) { preamble = "#define GL_ES 1\n" "#define GL_FRAGMENT_PRECISION_HIGH 1\n" +#ifdef GLSLANG_WEB + ; +#else "#define GL_OES_texture_3D 1\n" "#define GL_OES_standard_derivatives 1\n" "#define GL_EXT_frag_depth 1\n" @@ -311,10 +383,10 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_YUV_target 1\n" "#define GL_EXT_shader_texture_lod 1\n" "#define GL_EXT_shadow_samplers 1\n" + "#define GL_EXT_fragment_shading_rate 1\n" // AEP "#define GL_ANDROID_extension_pack_es31a 1\n" - "#define GL_KHR_blend_equation_advanced 1\n" "#define GL_OES_sample_variables 1\n" "#define GL_OES_shader_image_atomic 1\n" "#define GL_OES_shader_multisample_interpolation 1\n" @@ -328,6 +400,9 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_tessellation_point_size 1\n" "#define GL_EXT_texture_buffer 1\n" "#define GL_EXT_texture_cube_map_array 1\n" + "#define GL_EXT_shader_implicit_conversions 1\n" + "#define GL_EXT_shader_integer_mix 1\n" + "#define GL_EXT_blend_func_extended 1\n" // OES matching AEP "#define GL_OES_geometry_shader 1\n" @@ -342,13 +417,15 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_shader_non_constant_global_initializers 1\n" ; -#ifdef NV_EXTENSIONS - if (profile == EEsProfile && version >= 300) { + if (version >= 300) { preamble += "#define GL_NV_shader_noperspective_interpolation 1\n"; } -#endif + if (version >= 310) { + preamble += "#define GL_EXT_null_initializer 1\n"; + preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n"; + } - } else { + } else { // !isEsProfile() preamble = "#define GL_FRAGMENT_PRECISION_HIGH 1\n" "#define GL_ARB_texture_rectangle 1\n" @@ -360,8 +437,10 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_ARB_tessellation_shader 1\n" "#define GL_ARB_enhanced_layouts 1\n" "#define GL_ARB_texture_cube_map_array 1\n" + "#define GL_ARB_texture_multisample 1\n" "#define GL_ARB_shader_texture_lod 1\n" "#define GL_ARB_explicit_attrib_location 1\n" + "#define GL_ARB_explicit_uniform_location 1\n" "#define GL_ARB_shader_image_load_store 1\n" "#define GL_ARB_shader_atomic_counters 1\n" "#define GL_ARB_shader_draw_parameters 1\n" @@ -370,12 +449,22 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_ARB_shader_texture_image_samples 1\n" "#define GL_ARB_viewport_array 1\n" "#define GL_ARB_gpu_shader_int64 1\n" + "#define GL_ARB_gpu_shader_fp64 1\n" "#define GL_ARB_shader_ballot 1\n" "#define GL_ARB_sparse_texture2 1\n" "#define GL_ARB_sparse_texture_clamp 1\n" "#define GL_ARB_shader_stencil_export 1\n" + "#define GL_ARB_sample_shading 1\n" + "#define GL_ARB_shader_image_size 1\n" + "#define GL_ARB_shading_language_packing 1\n" // "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members "#define GL_ARB_post_depth_coverage 1\n" + "#define GL_ARB_fragment_shader_interlock 1\n" + "#define GL_ARB_uniform_buffer_object 1\n" + "#define GL_ARB_shader_bit_encoding 1\n" + "#define GL_ARB_shader_storage_buffer_object 1\n" + "#define GL_ARB_texture_query_lod 1\n" + "#define GL_ARB_vertex_attrib_64bit 1\n" "#define GL_EXT_shader_non_constant_global_initializers 1\n" "#define GL_EXT_shader_image_load_formatted 1\n" "#define GL_EXT_post_depth_coverage 1\n" @@ -387,6 +476,12 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_scalar_block_layout 1\n" "#define GL_EXT_fragment_invocation_density 1\n" "#define GL_EXT_buffer_reference 1\n" + "#define GL_EXT_buffer_reference2 1\n" + "#define GL_EXT_buffer_reference_uvec2 1\n" + "#define GL_EXT_demote_to_helper_invocation 1\n" + "#define GL_EXT_debug_printf 1\n" + "#define GL_EXT_fragment_shading_rate 1\n" + "#define GL_EXT_shared_memory_block 1\n" // GL_KHR_shader_subgroup "#define GL_KHR_shader_subgroup_basic 1\n" @@ -398,9 +493,14 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_KHR_shader_subgroup_clustered 1\n" "#define GL_KHR_shader_subgroup_quad 1\n" - "#define E_GL_EXT_shader_atomic_int64 1\n" + "#define GL_EXT_shader_image_int64 1\n" + "#define GL_EXT_shader_atomic_int64 1\n" + "#define GL_EXT_shader_realtime_clock 1\n" + "#define GL_EXT_ray_tracing 1\n" + "#define GL_EXT_ray_query 1\n" + "#define GL_EXT_ray_flags_primitive_culling 1\n" + "#define GL_EXT_spirv_intrinsics 1\n" -#ifdef AMD_EXTENSIONS "#define GL_AMD_shader_ballot 1\n" "#define GL_AMD_shader_trinary_minmax 1\n" "#define GL_AMD_shader_explicit_vertex_parameter 1\n" @@ -411,9 +511,9 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_AMD_shader_image_load_store_lod 1\n" "#define GL_AMD_shader_fragment_mask 1\n" "#define GL_AMD_gpu_shader_half_float_fetch 1\n" -#endif -#ifdef NV_EXTENSIONS + "#define GL_INTEL_shader_integer_functions2 1\n" + "#define GL_NV_sample_mask_override_coverage 1\n" "#define GL_NV_geometry_shader_passthrough 1\n" "#define GL_NV_viewport_array2 1\n" @@ -422,11 +522,14 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_NV_shader_subgroup_partitioned 1\n" "#define GL_NV_shading_rate_image 1\n" "#define GL_NV_ray_tracing 1\n" + "#define GL_NV_ray_tracing_motion_blur 1\n" "#define GL_NV_fragment_shader_barycentric 1\n" "#define GL_NV_compute_shader_derivatives 1\n" "#define GL_NV_shader_texture_footprint 1\n" "#define GL_NV_mesh_shader 1\n" -#endif + "#define GL_NV_cooperative_matrix 1\n" + "#define GL_NV_integer_cooperative_matrix 1\n" + "#define GL_EXT_shader_explicit_arithmetic_types 1\n" "#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n" "#define GL_EXT_shader_explicit_arithmetic_types_int16 1\n" @@ -435,6 +538,14 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_shader_explicit_arithmetic_types_float16 1\n" "#define GL_EXT_shader_explicit_arithmetic_types_float32 1\n" "#define GL_EXT_shader_explicit_arithmetic_types_float64 1\n" + + "#define GL_EXT_shader_subgroup_extended_types_int8 1\n" + "#define GL_EXT_shader_subgroup_extended_types_int16 1\n" + "#define GL_EXT_shader_subgroup_extended_types_int64 1\n" + "#define GL_EXT_shader_subgroup_extended_types_float16 1\n" + + "#define GL_EXT_shader_atomic_float 1\n" + "#define GL_EXT_shader_atomic_float2 1\n" ; if (version >= 150) { @@ -444,13 +555,20 @@ void TParseVersions::getPreamble(std::string& preamble) if (profile == ECompatibilityProfile) preamble += "#define GL_compatibility_profile 1\n"; } + if (version >= 140) { + preamble += "#define GL_EXT_null_initializer 1\n"; + preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n"; + } +#endif // GLSLANG_WEB } - if ((profile != EEsProfile && version >= 140) || - (profile == EEsProfile && version >= 310)) { +#ifndef GLSLANG_WEB + if ((!isEsProfile() && version >= 140) || + (isEsProfile() && version >= 310)) { preamble += "#define GL_EXT_device_group 1\n" "#define GL_EXT_multiview 1\n" + "#define GL_NV_shader_sm_builtins 1\n" ; } @@ -465,8 +583,15 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += "#define GL_GOOGLE_cpp_style_line_directive 1\n" "#define GL_GOOGLE_include_directive 1\n" + "#define GL_KHR_blend_equation_advanced 1\n" ; + // other general extensions + preamble += + "#define GL_EXT_terminate_invocation 1\n" + ; +#endif + // #define VULKAN XXXX const int numberBufSize = 12; char numberBuf[numberBufSize]; @@ -476,6 +601,8 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += numberBuf; preamble += "\n"; } + +#ifndef GLSLANG_WEB // #define GL_SPIRV XXXX if (spvVersion.openGl > 0) { preamble += "#define GL_SPIRV "; @@ -483,22 +610,30 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += numberBuf; preamble += "\n"; } +#endif -} - -// -// When to use requireProfile(): -// -// Use if only some profiles support a feature. However, if within a profile the feature -// is version or extension specific, follow this call with calls to profileRequires(). -// -// Operation: If the current profile is not one of the profileMask, -// give an error message. -// -void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) -{ - if (! (profile & profileMask)) - error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); +#ifndef GLSLANG_WEB + // GL_EXT_spirv_intrinsics + if (!isEsProfile()) { + switch (language) { + case EShLangVertex: preamble += "#define GL_VERTEX_SHADER 1 \n"; break; + case EShLangTessControl: preamble += "#define GL_TESSELLATION_CONTROL_SHADER 1 \n"; break; + case EShLangTessEvaluation: preamble += "#define GL_TESSELLATION_EVALUATION_SHADER 1 \n"; break; + case EShLangGeometry: preamble += "#define GL_GEOMETRY_SHADER 1 \n"; break; + case EShLangFragment: preamble += "#define GL_FRAGMENT_SHADER 1 \n"; break; + case EShLangCompute: preamble += "#define GL_COMPUTE_SHADER 1 \n"; break; + case EShLangRayGen: preamble += "#define GL_RAY_GENERATION_SHADER_EXT 1 \n"; break; + case EShLangIntersect: preamble += "#define GL_INTERSECTION_SHADER_EXT 1 \n"; break; + case EShLangAnyHit: preamble += "#define GL_ANY_HIT_SHADER_EXT 1 \n"; break; + case EShLangClosestHit: preamble += "#define GL_CLOSEST_HIT_SHADER_EXT 1 \n"; break; + case EShLangMiss: preamble += "#define GL_MISS_SHADER_EXT 1 \n"; break; + case EShLangCallable: preamble += "#define GL_CALLABLE_SHADER_EXT 1 \n"; break; + case EShLangTaskNV: preamble += "#define GL_TASK_SHADER_NV 1 \n"; break; + case EShLangMeshNV: preamble += "#define GL_MESH_SHADER_NV 1 \n"; break; + default: break; + } + } +#endif } // @@ -508,18 +643,18 @@ const char* StageName(EShLanguage stage) { switch(stage) { case EShLangVertex: return "vertex"; + case EShLangFragment: return "fragment"; + case EShLangCompute: return "compute"; +#ifndef GLSLANG_WEB case EShLangTessControl: return "tessellation control"; case EShLangTessEvaluation: return "tessellation evaluation"; case EShLangGeometry: return "geometry"; - case EShLangFragment: return "fragment"; - case EShLangCompute: return "compute"; -#ifdef NV_EXTENSIONS - case EShLangRayGenNV: return "ray-generation"; - case EShLangIntersectNV: return "intersection"; - case EShLangAnyHitNV: return "any-hit"; - case EShLangClosestHitNV: return "closest-hit"; - case EShLangMissNV: return "miss"; - case EShLangCallableNV: return "callable"; + case EShLangRayGen: return "ray-generation"; + case EShLangIntersect: return "intersection"; + case EShLangAnyHit: return "any-hit"; + case EShLangClosestHit: return "closest-hit"; + case EShLangMiss: return "miss"; + case EShLangCallable: return "callable"; case EShLangMeshNV: return "mesh"; case EShLangTaskNV: return "task"; #endif @@ -527,53 +662,6 @@ const char* StageName(EShLanguage stage) } } -// -// When to use profileRequires(): -// -// If a set of profiles have the same requirements for what version or extensions -// are needed to support a feature. -// -// It must be called for each profile that needs protection. Use requireProfile() first -// to reduce that set of profiles. -// -// Operation: Will issue warnings/errors based on the current profile, version, and extension -// behaviors. It only checks extensions when the current profile is one of the profileMask. -// -// A minVersion of 0 means no version of the profileMask support this in core, -// the extension must be present. -// - -// entry point that takes multiple extensions -void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc) -{ - if (profile & profileMask) { - bool okay = false; - if (minVersion > 0 && version >= minVersion) - okay = true; - for (int i = 0; i < numExtensions; ++i) { - switch (getExtensionBehavior(extensions[i])) { - case EBhWarn: - infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc); - // fall through - case EBhRequire: - case EBhEnable: - okay = true; - break; - default: break; // some compilers want this - } - } - - if (! okay) - error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); - } -} - -// entry point for the above that takes a single extension -void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, const char* featureDesc) -{ - profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); -} - // // When to use requireStage() // @@ -594,6 +682,75 @@ void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, cons requireStage(loc, static_cast(1 << stage), featureDesc); } +#ifndef GLSLANG_WEB +// +// When to use requireProfile(): +// +// Use if only some profiles support a feature. However, if within a profile the feature +// is version or extension specific, follow this call with calls to profileRequires(). +// +// Operation: If the current profile is not one of the profileMask, +// give an error message. +// +void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) +{ + if (! (profile & profileMask)) + error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); +} + +// +// When to use profileRequires(): +// +// If a set of profiles have the same requirements for what version or extensions +// are needed to support a feature. +// +// It must be called for each profile that needs protection. Use requireProfile() first +// to reduce that set of profiles. +// +// Operation: Will issue warnings/errors based on the current profile, version, and extension +// behaviors. It only checks extensions when the current profile is one of the profileMask. +// +// A minVersion of 0 means no version of the profileMask support this in core, +// the extension must be present. +// + +// entry point that takes multiple extensions +void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, + const char* const extensions[], const char* featureDesc) +{ + if (profile & profileMask) { + bool okay = minVersion > 0 && version >= minVersion; +#ifndef GLSLANG_WEB + for (int i = 0; i < numExtensions; ++i) { + switch (getExtensionBehavior(extensions[i])) { + case EBhWarn: + infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc); + // fall through + case EBhRequire: + case EBhEnable: + okay = true; + break; + default: break; // some compilers want this + } + } +#endif + if (! okay) + error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); + } +} + +// entry point for the above that takes a single extension +void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, + const char* featureDesc) +{ + profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); +} + +void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc) +{ + error(loc, "feature not yet implemented", featureDesc, ""); +} + // // Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether // a future compatibility context is being use. @@ -627,11 +784,6 @@ void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, i } } -void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc) -{ - error(loc, "feature not yet implemented", featureDesc, ""); -} - // Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false. // Warns appropriately if the requested behavior of an extension is "warn". bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) @@ -665,7 +817,8 @@ bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExte // Use when there are no profile/version to check, it's just an error if one of the // extensions is not present. // -void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) +void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], + const char* featureDesc) { if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; @@ -684,7 +837,8 @@ void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, // Use by preprocessor when there are no profile/version to check, it's just an error if one of the // extensions is not present. // -void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) +void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], + const char* featureDesc) { if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; @@ -750,10 +904,14 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co error(getCurrentLoc(), "behavior not supported:", "#extension", behaviorString); return; } + bool on = behavior != EBhDisable; // check if extension is used with correct shader stage checkExtensionStage(getCurrentLoc(), extension); + // check if extension has additional requirements + extensionRequires(getCurrentLoc(), extension, behaviorString); + // update the requested extension updateExtensionBehavior(extension, behavior); @@ -800,10 +958,48 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); else if (strcmp(extension, "GL_KHR_shader_subgroup_quad") == 0) updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); -#ifdef NV_EXTENSIONS else if (strcmp(extension, "GL_NV_shader_subgroup_partitioned") == 0) updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); -#endif + else if (strcmp(extension, "GL_EXT_buffer_reference2") == 0 || + strcmp(extension, "GL_EXT_buffer_reference_uvec2") == 0) + updateExtensionBehavior(line, "GL_EXT_buffer_reference", behaviorString); + else if (strcmp(extension, "GL_NV_integer_cooperative_matrix") == 0) + updateExtensionBehavior(line, "GL_NV_cooperative_matrix", behaviorString); + // subgroup extended types to explicit types + else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int8") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int8", behaviorString); + else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int16") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int16", behaviorString); + else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int64") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int64", behaviorString); + else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_float16") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_float16", behaviorString); + + // see if we need to update the numeric features + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int8") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int8, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int16") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int16, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int32") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int32, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int64") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int64, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_float16") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_float16, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_float32") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_float32, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_float64") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_float64, on); + else if (strcmp(extension, "GL_EXT_shader_implicit_conversions") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_implicit_conversions, on); + else if (strcmp(extension, "GL_ARB_gpu_shader_fp64") == 0) + intermediate.updateNumericFeature(TNumericFeatures::gpu_shader_fp64, on); + else if (strcmp(extension, "GL_AMD_gpu_shader_int16") == 0) + intermediate.updateNumericFeature(TNumericFeatures::gpu_shader_int16, on); + else if (strcmp(extension, "GL_AMD_gpu_shader_half_float") == 0) + intermediate.updateNumericFeature(TNumericFeatures::gpu_shader_half_float, on); } void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior) @@ -839,7 +1035,7 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe } else { if (iter->second == EBhDisablePartial) warn(getCurrentLoc(), "extension is only partially supported:", "#extension", extension); - if (behavior == EBhEnable || behavior == EBhRequire) + if (behavior != EBhDisable) intermediate.addRequestedExtension(extension); iter->second = behavior; } @@ -849,7 +1045,6 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe // Check if extension is used with correct shader stage. void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension) { -#ifdef NV_EXTENSIONS // GL_NV_mesh_shader extension is only allowed in task/mesh shaders if (strcmp(extension, "GL_NV_mesh_shader") == 0) { requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask), @@ -857,7 +1052,24 @@ void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * con profileRequires(loc, ECoreProfile, 450, 0, "#extension GL_NV_mesh_shader"); profileRequires(loc, EEsProfile, 320, 0, "#extension GL_NV_mesh_shader"); } -#endif +} + +// Check if extension has additional requirements +void TParseVersions::extensionRequires(const TSourceLoc &loc, const char * const extension, const char *behaviorString) +{ + bool isEnabled = false; + if (!strcmp("require", behaviorString)) + isEnabled = true; + else if (!strcmp("enable", behaviorString)) + isEnabled = true; + + if (isEnabled) { + unsigned int minSpvVersion = 0; + auto iter = extensionMinSpv.find(TString(extension)); + if (iter != extensionMinSpv.end()) + minSpvVersion = iter->second; + requireSpv(loc, extension, minSpvVersion); + } } // Call for any operation needing full GLSL integer data-type support. @@ -870,8 +1082,13 @@ void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op) // Call for any operation needing GLSL double data-type support. void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op) { - requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op); + + //requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); + if (language == EShLangVertex) { + const char* const f64_Extensions[] = {E_GL_ARB_gpu_shader_fp64, E_GL_ARB_vertex_attrib_64bit}; + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, 2, f64_Extensions, op); + } else + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader_fp64, op); } // Call for any operation needing GLSL float16 data-type support. @@ -879,9 +1096,7 @@ void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool bu { if (!builtIn) { const char* const extensions[] = { -#if AMD_EXTENSIONS E_GL_AMD_gpu_shader_half_float, -#endif E_GL_EXT_shader_explicit_arithmetic_types, E_GL_EXT_shader_explicit_arithmetic_types_float16}; requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); @@ -891,9 +1106,7 @@ void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool bu bool TParseVersions::float16Arithmetic() { const char* const extensions[] = { -#if AMD_EXTENSIONS E_GL_AMD_gpu_shader_half_float, -#endif E_GL_EXT_shader_explicit_arithmetic_types, E_GL_EXT_shader_explicit_arithmetic_types_float16}; return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions); @@ -902,9 +1115,7 @@ bool TParseVersions::float16Arithmetic() bool TParseVersions::int16Arithmetic() { const char* const extensions[] = { -#if AMD_EXTENSIONS E_GL_AMD_gpu_shader_int16, -#endif E_GL_EXT_shader_explicit_arithmetic_types, E_GL_EXT_shader_explicit_arithmetic_types_int16}; return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions); @@ -926,9 +1137,7 @@ void TParseVersions::requireFloat16Arithmetic(const TSourceLoc& loc, const char* combined += featureDesc; const char* const extensions[] = { -#if AMD_EXTENSIONS E_GL_AMD_gpu_shader_half_float, -#endif E_GL_EXT_shader_explicit_arithmetic_types, E_GL_EXT_shader_explicit_arithmetic_types_float16}; requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str()); @@ -942,9 +1151,7 @@ void TParseVersions::requireInt16Arithmetic(const TSourceLoc& loc, const char* o combined += featureDesc; const char* const extensions[] = { -#if AMD_EXTENSIONS E_GL_AMD_gpu_shader_int16, -#endif E_GL_EXT_shader_explicit_arithmetic_types, E_GL_EXT_shader_explicit_arithmetic_types_int16}; requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str()); @@ -967,9 +1174,7 @@ void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char* { if (!builtIn) { const char* const extensions[] = { -#if AMD_EXTENSIONS E_GL_AMD_gpu_shader_half_float, -#endif E_GL_EXT_shader_16bit_storage, E_GL_EXT_shader_explicit_arithmetic_types, E_GL_EXT_shader_explicit_arithmetic_types_float16}; @@ -1009,7 +1214,6 @@ void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bo } } -#ifdef AMD_EXTENSIONS // Call for any operation needing GLSL float16 opaque-type support void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, bool builtIn) { @@ -1019,16 +1223,13 @@ void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, b profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op); } } -#endif // Call for any operation needing GLSL explicit int16 data-type support. void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn) { if (! builtIn) { - const char* const extensions[] = { -#if AMD_EXTENSIONS + const char* const extensions[] = { E_GL_AMD_gpu_shader_int16, -#endif E_GL_EXT_shader_explicit_arithmetic_types, E_GL_EXT_shader_explicit_arithmetic_types_int16}; requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); @@ -1039,9 +1240,7 @@ void TParseVersions::int16ScalarVectorCheck(const TSourceLoc& loc, const char* o { if (! builtIn) { const char* const extensions[] = { -#if AMD_EXTENSIONS E_GL_AMD_gpu_shader_int16, -#endif E_GL_EXT_shader_16bit_storage, E_GL_EXT_shader_explicit_arithmetic_types, E_GL_EXT_shader_explicit_arithmetic_types_int16}; @@ -1083,6 +1282,22 @@ void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool buil } } +void TParseVersions::fcoopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (!builtIn) { + const char* const extensions[] = {E_GL_NV_cooperative_matrix}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); + } +} + +void TParseVersions::intcoopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (!builtIn) { + const char* const extensions[] = {E_GL_NV_integer_cooperative_matrix}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); + } +} +#endif // GLSLANG_WEB // Call for any operation removed because SPIR-V is in use. void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op) { @@ -1093,22 +1308,33 @@ void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op) // Call for any operation removed because Vulkan SPIR-V is being generated. void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op) { - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0 && !spvVersion.vulkanRelaxed) error(loc, "not allowed when using GLSL for Vulkan", op, ""); } // Call for any operation that requires Vulkan. void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op) { +#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0) error(loc, "only allowed when using GLSL for Vulkan", op, ""); +#endif } // Call for any operation that requires SPIR-V. void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op) { +#ifndef GLSLANG_WEB if (spvVersion.spv == 0) error(loc, "only allowed when generating SPIR-V", op, ""); +#endif +} +void TParseVersions::requireSpv(const TSourceLoc& loc, const char *op, unsigned int version) +{ +#ifndef GLSLANG_WEB + if (spvVersion.spv < version) + error(loc, "not supported for current targeted SPIR-V version", op, ""); +#endif } } // end namespace glslang diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Versions.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Versions.h index 72018d8..949a7a1 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/Versions.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/Versions.h @@ -3,6 +3,7 @@ // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. // Copyright (C) 2015-2018 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -35,9 +36,12 @@ // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // + #ifndef _VERSIONS_INCLUDED_ #define _VERSIONS_INCLUDED_ +#define LAST_ELEMENT_MARKER(x) x + // // Help manage multiple profiles, versions, extensions etc. // @@ -49,12 +53,13 @@ // Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible // defects from mixing the two different forms. // -typedef enum { +typedef enum : unsigned { EBadProfile = 0, ENoProfile = (1 << 0), // only for desktop, before profiles showed up ECoreProfile = (1 << 1), ECompatibilityProfile = (1 << 2), - EEsProfile = (1 << 3) + EEsProfile = (1 << 3), + LAST_ELEMENT_MARKER(EProfileCount), } EProfile; namespace glslang { @@ -82,11 +87,12 @@ inline const char* ProfileName(EProfile profile) // The union of all requested rule sets will be applied. // struct SpvVersion { - SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0) {} + SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0), vulkanRelaxed(false) {} unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX" int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX" + bool vulkanRelaxed; // relax changes to GLSL for Vulkan, allowing some GL-specific to be compiled to Vulkan SPIR-V target }; // @@ -124,16 +130,20 @@ const char* const E_GL_ARB_compute_shader = "GL_ARB_compute_shader const char* const E_GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader"; const char* const E_GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts"; const char* const E_GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_array"; +const char* const E_GL_ARB_texture_multisample = "GL_ARB_texture_multisample"; const char* const E_GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod"; const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location"; +const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location"; const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store"; const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters"; +const char* const E_GL_ARB_shader_atomic_counter_ops = "GL_ARB_shader_atomic_counter_ops"; const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters"; const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote"; const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control"; const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture_image_samples"; const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array"; const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64"; +const char* const E_GL_ARB_gpu_shader_fp64 = "GL_ARB_gpu_shader_fp64"; const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot"; const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2"; const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp"; @@ -141,6 +151,16 @@ const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil // const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage"; const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array"; +const char* const E_GL_ARB_fragment_shader_interlock = "GL_ARB_fragment_shader_interlock"; +const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock"; +const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object"; +const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading"; +const char* const E_GL_ARB_shader_bit_encoding = "GL_ARB_shader_bit_encoding"; +const char* const E_GL_ARB_shader_image_size = "GL_ARB_shader_image_size"; +const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage_buffer_object"; +const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_language_packing"; +const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_lod"; +const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit"; const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic"; const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote"; @@ -171,6 +191,22 @@ const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerles const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout"; const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density"; const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference"; +const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_reference2"; +const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2"; +const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation"; +const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock"; +const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_printf"; +const char* const E_GL_EXT_ray_tracing = "GL_EXT_ray_tracing"; +const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query"; +const char* const E_GL_EXT_ray_flags_primitive_culling = "GL_EXT_ray_flags_primitive_culling"; +const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func_extended"; +const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions"; +const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate"; +const char* const E_GL_EXT_shader_image_int64 = "GL_EXT_shader_image_int64"; +const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initializer"; +const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block"; +const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow"; +const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intrinsics"; // Arrays of extensions for the above viewportEXTs duplications @@ -188,7 +224,6 @@ const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multi const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive"; const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive"; -#ifdef AMD_EXTENSIONS const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot"; const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax"; const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter"; @@ -199,9 +234,8 @@ const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_sh const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod"; const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask"; const char* const E_GL_AMD_gpu_shader_half_float_fetch = "GL_AMD_gpu_shader_half_float_fetch"; -#endif -#ifdef NV_EXTENSIONS +const char* const E_GL_INTEL_shader_integer_functions2 = "GL_INTEL_shader_integer_functions2"; const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage"; const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough"; @@ -214,6 +248,7 @@ const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_ const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned"; const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image"; const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing"; +const char* const E_GL_NV_ray_tracing_motion_blur = "GL_NV_ray_tracing_motion_blur"; const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric"; const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives"; const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint"; @@ -223,7 +258,10 @@ const char* const E_GL_NV_mesh_shader = "GL_NV_mesh_sh const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 }; const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]); -#endif + +const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix"; +const char* const E_GL_NV_shader_sm_builtins = "GL_NV_shader_sm_builtins"; +const char* const E_GL_NV_integer_cooperative_matrix = "GL_NV_integer_cooperative_matrix"; // AEP const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a"; @@ -241,6 +279,7 @@ const char* const E_GL_EXT_tessellation_shader = "GL_EXT_tessel const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size"; const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer"; const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array"; +const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix"; // OES matching AEP const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader"; @@ -253,7 +292,7 @@ const char* const E_GL_OES_tessellation_point_size = "GL_OES_tessel const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer"; const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array"; -// KHX +// EXT const char* const E_GL_EXT_shader_explicit_arithmetic_types = "GL_EXT_shader_explicit_arithmetic_types"; const char* const E_GL_EXT_shader_explicit_arithmetic_types_int8 = "GL_EXT_shader_explicit_arithmetic_types_int8"; const char* const E_GL_EXT_shader_explicit_arithmetic_types_int16 = "GL_EXT_shader_explicit_arithmetic_types_int16"; @@ -263,6 +302,15 @@ const char* const E_GL_EXT_shader_explicit_arithmetic_types_float16 = "GL_EXT_s const char* const E_GL_EXT_shader_explicit_arithmetic_types_float32 = "GL_EXT_shader_explicit_arithmetic_types_float32"; const char* const E_GL_EXT_shader_explicit_arithmetic_types_float64 = "GL_EXT_shader_explicit_arithmetic_types_float64"; +const char* const E_GL_EXT_shader_subgroup_extended_types_int8 = "GL_EXT_shader_subgroup_extended_types_int8"; +const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shader_subgroup_extended_types_int16"; +const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64"; +const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16"; +const char* const E_GL_EXT_terminate_invocation = "GL_EXT_terminate_invocation"; + +const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float"; +const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2"; + // Arrays of extensions for the above AEP duplications const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader }; diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/attribute.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/attribute.cpp index 73b665d..8a92f6a 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/attribute.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/attribute.cpp @@ -34,6 +34,8 @@ // POSSIBILITY OF SUCH DAMAGE. // +#ifndef GLSLANG_WEB + #include "attribute.h" #include "../Include/intermediate.h" #include "ParseHelper.h" @@ -52,6 +54,7 @@ bool TAttributeArgs::getInt(int& value, int argNum) const return true; } + // extract strings out of attribute arguments stored in attribute aggregate. // convert to lower case if converToLower is true (for case-insensitive compare convenience) bool TAttributeArgs::getString(TString& value, int argNum, bool convertToLower) const @@ -85,6 +88,9 @@ const TConstUnion* TAttributeArgs::getConstUnion(TBasicType basicType, int argNu if (argNum >= (int)args->getSequence().size()) return nullptr; + if (args->getSequence()[argNum]->getAsConstantUnion() == nullptr) + return nullptr; + const TConstUnion* constVal = &args->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0]; if (constVal == nullptr || constVal->getType() != basicType) return nullptr; @@ -107,6 +113,18 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const return EatDependencyInfinite; else if (name == "dependency_length") return EatDependencyLength; + else if (name == "min_iterations") + return EatMinIterations; + else if (name == "max_iterations") + return EatMaxIterations; + else if (name == "iteration_multiple") + return EatIterationMultiple; + else if (name == "peel_count") + return EatPeelCount; + else if (name == "partial_count") + return EatPartialCount; + else if (name == "subgroup_uniform_control_flow") + return EatSubgroupUniformControlFlow; else return EatNone; } @@ -222,29 +240,101 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN } for (auto it = attributes.begin(); it != attributes.end(); ++it) { - if (it->name != EatDependencyLength && it->size() > 0) { - warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", ""); - continue; - } - int value; + const auto noArgument = [&](const char* feature) { + if (it->size() > 0) { + warn(node->getLoc(), "expected no arguments", feature, ""); + return false; + } + return true; + }; + + const auto positiveSignedArgument = [&](const char* feature, int& value) { + if (it->size() == 1 && it->getInt(value)) { + if (value <= 0) { + error(node->getLoc(), "must be positive", feature, ""); + return false; + } + } else { + warn(node->getLoc(), "expected a single integer argument", feature, ""); + return false; + } + return true; + }; + + const auto unsignedArgument = [&](const char* feature, unsigned int& uiValue) { + int value; + if (!(it->size() == 1 && it->getInt(value))) { + warn(node->getLoc(), "expected a single integer argument", feature, ""); + return false; + } + uiValue = (unsigned int)value; + return true; + }; + + const auto positiveUnsignedArgument = [&](const char* feature, unsigned int& uiValue) { + int value; + if (it->size() == 1 && it->getInt(value)) { + if (value == 0) { + error(node->getLoc(), "must be greater than or equal to 1", feature, ""); + return false; + } + } else { + warn(node->getLoc(), "expected a single integer argument", feature, ""); + return false; + } + uiValue = (unsigned int)value; + return true; + }; + + const auto spirv14 = [&](const char* feature) { + if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_4) + warn(node->getLoc(), "attribute requires a SPIR-V 1.4 target-env", feature, ""); + }; + + int value = 0; + unsigned uiValue = 0; switch (it->name) { case EatUnroll: - loop->setUnroll(); + if (noArgument("unroll")) + loop->setUnroll(); break; case EatLoop: - loop->setDontUnroll(); + if (noArgument("dont_unroll")) + loop->setDontUnroll(); break; case EatDependencyInfinite: - loop->setLoopDependency(TIntermLoop::dependencyInfinite); + if (noArgument("dependency_infinite")) + loop->setLoopDependency(TIntermLoop::dependencyInfinite); break; case EatDependencyLength: - if (it->size() == 1 && it->getInt(value)) { - if (value <= 0) - error(node->getLoc(), "must be positive", "dependency_length", ""); + if (positiveSignedArgument("dependency_length", value)) loop->setLoopDependency(value); - } else - warn(node->getLoc(), "expected a single integer argument", "dependency_length", ""); + break; + case EatMinIterations: + spirv14("min_iterations"); + if (unsignedArgument("min_iterations", uiValue)) + loop->setMinIterations(uiValue); + break; + case EatMaxIterations: + spirv14("max_iterations"); + if (unsignedArgument("max_iterations", uiValue)) + loop->setMaxIterations(uiValue); + break; + case EatIterationMultiple: + spirv14("iteration_multiple"); + if (positiveUnsignedArgument("iteration_multiple", uiValue)) + loop->setIterationMultiple(uiValue); + break; + case EatPeelCount: + spirv14("peel_count"); + if (unsignedArgument("peel_count", uiValue)) + loop->setPeelCount(uiValue); + break; + case EatPartialCount: + spirv14("partial_count"); + if (unsignedArgument("partial_count", uiValue)) + loop->setPartialCount(uiValue); break; default: warn(node->getLoc(), "attribute does not apply to a loop", "", ""); @@ -254,4 +344,28 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN } +// +// Function attributes +// +void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes, TFunction* function) +{ + for (auto it = attributes.begin(); it != attributes.end(); ++it) { + if (it->size() > 0) { + warn(loc, "attribute with arguments not recognized, skipping", "", ""); + continue; + } + + switch (it->name) { + case EatSubgroupUniformControlFlow: + intermediate.setSubgroupUniformControlFlow(); + break; + default: + warn(loc, "attribute does not apply to a function", "", ""); + break; + } + } +} + } // end namespace glslang + +#endif // GLSLANG_WEB diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/attribute.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/attribute.h index 8d0c5bc..c5b2917 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/attribute.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/attribute.h @@ -71,7 +71,55 @@ namespace glslang { EatPushConstant, EatConstantId, EatDependencyInfinite, - EatDependencyLength + EatDependencyLength, + EatMinIterations, + EatMaxIterations, + EatIterationMultiple, + EatPeelCount, + EatPartialCount, + EatFormatRgba32f, + EatFormatRgba16f, + EatFormatR32f, + EatFormatRgba8, + EatFormatRgba8Snorm, + EatFormatRg32f, + EatFormatRg16f, + EatFormatR11fG11fB10f, + EatFormatR16f, + EatFormatRgba16, + EatFormatRgb10A2, + EatFormatRg16, + EatFormatRg8, + EatFormatR16, + EatFormatR8, + EatFormatRgba16Snorm, + EatFormatRg16Snorm, + EatFormatRg8Snorm, + EatFormatR16Snorm, + EatFormatR8Snorm, + EatFormatRgba32i, + EatFormatRgba16i, + EatFormatRgba8i, + EatFormatR32i, + EatFormatRg32i, + EatFormatRg16i, + EatFormatRg8i, + EatFormatR16i, + EatFormatR8i, + EatFormatRgba32ui, + EatFormatRgba16ui, + EatFormatRgba8ui, + EatFormatR32ui, + EatFormatRgb10a2ui, + EatFormatRg32ui, + EatFormatRg16ui, + EatFormatRg8ui, + EatFormatR16ui, + EatFormatR8ui, + EatFormatUnknown, + EatNonWritable, + EatNonReadable, + EatSubgroupUniformControlFlow, }; class TIntermAggregate; diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/gl_types.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/gl_types.h index c9fee9e..d6c9393 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/gl_types.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/gl_types.h @@ -49,9 +49,17 @@ #define GL_INT64_VEC4_ARB 0x8FEB #define GL_UNSIGNED_INT64_ARB 0x140F -#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FE5 -#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FE6 -#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FE7 +#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 + +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 #define GL_BOOL 0x8B56 #define GL_BOOL_VEC2 0x8B57 @@ -78,7 +86,6 @@ #define GL_DOUBLE_MAT4x2 0x8F4D #define GL_DOUBLE_MAT4x3 0x8F4E -#ifdef AMD_EXTENSIONS // Those constants are borrowed from extension NV_gpu_shader5 #define GL_FLOAT16_NV 0x8FF8 #define GL_FLOAT16_VEC2_NV 0x8FF9 @@ -94,7 +101,6 @@ #define GL_FLOAT16_MAT3x4_AMD 0x91CB #define GL_FLOAT16_MAT4x2_AMD 0x91CC #define GL_FLOAT16_MAT4x3_AMD 0x91CD -#endif #define GL_SAMPLER_1D 0x8B5D #define GL_SAMPLER_2D 0x8B5E @@ -117,7 +123,6 @@ #define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D -#ifdef AMD_EXTENSIONS #define GL_FLOAT16_SAMPLER_1D_AMD 0x91CE #define GL_FLOAT16_SAMPLER_2D_AMD 0x91CF #define GL_FLOAT16_SAMPLER_3D_AMD 0x91D0 @@ -149,7 +154,6 @@ #define GL_FLOAT16_IMAGE_BUFFER_AMD 0x91E8 #define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD 0x91E9 #define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD 0x91EA -#endif #define GL_INT_SAMPLER_1D 0x8DC9 #define GL_INT_SAMPLER_2D 0x8DCA diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang.m4 b/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang.m4 new file mode 100644 index 0000000..93041ce --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang.m4 @@ -0,0 +1,4398 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2015-2019 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Do not edit the .y file, only edit the .m4 file. +// The .y bison file is not a source file, it is a derivative of the .m4 file. +// The m4 file needs to be processed by m4 to generate the .y bison file. +// +// Code sandwiched between a pair: +// +// GLSLANG_WEB_EXCLUDE_ON +// ... +// ... +// ... +// GLSLANG_WEB_EXCLUDE_OFF +// +// Will be excluded from the grammar when m4 is executed as: +// +// m4 -P -DGLSLANG_WEB +// +// It will be included when m4 is executed as: +// +// m4 -P +// + +m4_define(`GLSLANG_WEB_EXCLUDE_ON', `m4_ifdef(`GLSLANG_WEB', `m4_divert(`-1')')') +m4_define(`GLSLANG_WEB_EXCLUDE_OFF', `m4_ifdef(`GLSLANG_WEB', `m4_divert')') + +/** + * This is bison grammar and productions for parsing all versions of the + * GLSL shading languages. + */ +%{ + +/* Based on: +ANSI C Yacc grammar + +In 1985, Jeff Lee published his Yacc grammar (which is accompanied by a +matching Lex specification) for the April 30, 1985 draft version of the +ANSI C standard. Tom Stockfisch reposted it to net.sources in 1987; that +original, as mentioned in the answer to question 17.25 of the comp.lang.c +FAQ, can be ftp'ed from ftp.uu.net, file usenet/net.sources/ansi.c.grammar.Z. + +I intend to keep this version as close to the current C Standard grammar as +possible; please let me know if you discover discrepancies. + +Jutta Degener, 1995 +*/ + +#include "SymbolTable.h" +#include "ParseHelper.h" +#include "../Public/ShaderLang.h" +#include "attribute.h" + +using namespace glslang; + +%} + +%define parse.error verbose + +%union { + struct { + glslang::TSourceLoc loc; + union { + glslang::TString *string; + int i; + unsigned int u; + long long i64; + unsigned long long u64; + bool b; + double d; + }; + glslang::TSymbol* symbol; + } lex; + struct { + glslang::TSourceLoc loc; + glslang::TOperator op; + union { + TIntermNode* intermNode; + glslang::TIntermNodePair nodePair; + glslang::TIntermTyped* intermTypedNode; + glslang::TAttributes* attributes; + glslang::TSpirvRequirement* spirvReq; + glslang::TSpirvInstruction* spirvInst; + glslang::TSpirvTypeParameters* spirvTypeParams; + }; + union { + glslang::TPublicType type; + glslang::TFunction* function; + glslang::TParameter param; + glslang::TTypeLoc typeLine; + glslang::TTypeList* typeList; + glslang::TArraySizes* arraySizes; + glslang::TIdentifierList* identifierList; + }; + glslang::TArraySizes* typeParameters; + } interm; +} + +%{ + +/* windows only pragma */ +#ifdef _MSC_VER + #pragma warning(disable : 4065) + #pragma warning(disable : 4127) + #pragma warning(disable : 4244) +#endif + +#define parseContext (*pParseContext) +#define yyerror(context, msg) context->parserError(msg) + +extern int yylex(YYSTYPE*, TParseContext&); + +%} + +%parse-param {glslang::TParseContext* pParseContext} +%lex-param {parseContext} +%pure-parser // enable thread safety +%expect 1 // One shift reduce conflict because of if | else + +%token CONST BOOL INT UINT FLOAT +%token BVEC2 BVEC3 BVEC4 +%token IVEC2 IVEC3 IVEC4 +%token UVEC2 UVEC3 UVEC4 +%token VEC2 VEC3 VEC4 +%token MAT2 MAT3 MAT4 +%token MAT2X2 MAT2X3 MAT2X4 +%token MAT3X2 MAT3X3 MAT3X4 +%token MAT4X2 MAT4X3 MAT4X4 + +// combined image/sampler +%token SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER2DSHADOW +%token SAMPLERCUBESHADOW SAMPLER2DARRAY +%token SAMPLER2DARRAYSHADOW ISAMPLER2D ISAMPLER3D ISAMPLERCUBE +%token ISAMPLER2DARRAY USAMPLER2D USAMPLER3D +%token USAMPLERCUBE USAMPLER2DARRAY + +// separate image/sampler +%token SAMPLER SAMPLERSHADOW +%token TEXTURE2D TEXTURE3D TEXTURECUBE TEXTURE2DARRAY +%token ITEXTURE2D ITEXTURE3D ITEXTURECUBE ITEXTURE2DARRAY +%token UTEXTURE2D UTEXTURE3D UTEXTURECUBE UTEXTURE2DARRAY + +GLSLANG_WEB_EXCLUDE_ON + +%token ATTRIBUTE VARYING +%token FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T +%token INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T +%token I64VEC2 I64VEC3 I64VEC4 +%token U64VEC2 U64VEC3 U64VEC4 +%token I32VEC2 I32VEC3 I32VEC4 +%token U32VEC2 U32VEC3 U32VEC4 +%token I16VEC2 I16VEC3 I16VEC4 +%token U16VEC2 U16VEC3 U16VEC4 +%token I8VEC2 I8VEC3 I8VEC4 +%token U8VEC2 U8VEC3 U8VEC4 +%token DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4 +%token F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4 +%token F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4 +%token F64VEC2 F64VEC3 F64VEC4 F64MAT2 F64MAT3 F64MAT4 +%token DMAT2X2 DMAT2X3 DMAT2X4 +%token DMAT3X2 DMAT3X3 DMAT3X4 +%token DMAT4X2 DMAT4X3 DMAT4X4 +%token F16MAT2X2 F16MAT2X3 F16MAT2X4 +%token F16MAT3X2 F16MAT3X3 F16MAT3X4 +%token F16MAT4X2 F16MAT4X3 F16MAT4X4 +%token F32MAT2X2 F32MAT2X3 F32MAT2X4 +%token F32MAT3X2 F32MAT3X3 F32MAT3X4 +%token F32MAT4X2 F32MAT4X3 F32MAT4X4 +%token F64MAT2X2 F64MAT2X3 F64MAT2X4 +%token F64MAT3X2 F64MAT3X3 F64MAT3X4 +%token F64MAT4X2 F64MAT4X3 F64MAT4X4 +%token ATOMIC_UINT +%token ACCSTRUCTNV +%token ACCSTRUCTEXT +%token RAYQUERYEXT +%token FCOOPMATNV ICOOPMATNV UCOOPMATNV + +// combined image/sampler +%token SAMPLERCUBEARRAY SAMPLERCUBEARRAYSHADOW +%token ISAMPLERCUBEARRAY USAMPLERCUBEARRAY +%token SAMPLER1D SAMPLER1DARRAY SAMPLER1DARRAYSHADOW ISAMPLER1D SAMPLER1DSHADOW +%token SAMPLER2DRECT SAMPLER2DRECTSHADOW ISAMPLER2DRECT USAMPLER2DRECT +%token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER +%token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS +%token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY +%token SAMPLEREXTERNALOES +%token SAMPLEREXTERNAL2DY2YEXT +%token ISAMPLER1DARRAY USAMPLER1D USAMPLER1DARRAY +%token F16SAMPLER1D F16SAMPLER2D F16SAMPLER3D F16SAMPLER2DRECT F16SAMPLERCUBE +%token F16SAMPLER1DARRAY F16SAMPLER2DARRAY F16SAMPLERCUBEARRAY +%token F16SAMPLERBUFFER F16SAMPLER2DMS F16SAMPLER2DMSARRAY +%token F16SAMPLER1DSHADOW F16SAMPLER2DSHADOW F16SAMPLER1DARRAYSHADOW F16SAMPLER2DARRAYSHADOW +%token F16SAMPLER2DRECTSHADOW F16SAMPLERCUBESHADOW F16SAMPLERCUBEARRAYSHADOW + +// images +%token IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D +%token UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D +%token IMAGE2DRECT IIMAGE2DRECT UIMAGE2DRECT +%token IMAGECUBE IIMAGECUBE UIMAGECUBE +%token IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER +%token IMAGE1DARRAY IIMAGE1DARRAY UIMAGE1DARRAY +%token IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY +%token IMAGECUBEARRAY IIMAGECUBEARRAY UIMAGECUBEARRAY +%token IMAGE2DMS IIMAGE2DMS UIMAGE2DMS +%token IMAGE2DMSARRAY IIMAGE2DMSARRAY UIMAGE2DMSARRAY + +%token F16IMAGE1D F16IMAGE2D F16IMAGE3D F16IMAGE2DRECT +%token F16IMAGECUBE F16IMAGE1DARRAY F16IMAGE2DARRAY F16IMAGECUBEARRAY +%token F16IMAGEBUFFER F16IMAGE2DMS F16IMAGE2DMSARRAY + +%token I64IMAGE1D U64IMAGE1D +%token I64IMAGE2D U64IMAGE2D +%token I64IMAGE3D U64IMAGE3D +%token I64IMAGE2DRECT U64IMAGE2DRECT +%token I64IMAGECUBE U64IMAGECUBE +%token I64IMAGEBUFFER U64IMAGEBUFFER +%token I64IMAGE1DARRAY U64IMAGE1DARRAY +%token I64IMAGE2DARRAY U64IMAGE2DARRAY +%token I64IMAGECUBEARRAY U64IMAGECUBEARRAY +%token I64IMAGE2DMS U64IMAGE2DMS +%token I64IMAGE2DMSARRAY U64IMAGE2DMSARRAY + +// texture without sampler +%token TEXTURECUBEARRAY ITEXTURECUBEARRAY UTEXTURECUBEARRAY +%token TEXTURE1D ITEXTURE1D UTEXTURE1D +%token TEXTURE1DARRAY ITEXTURE1DARRAY UTEXTURE1DARRAY +%token TEXTURE2DRECT ITEXTURE2DRECT UTEXTURE2DRECT +%token TEXTUREBUFFER ITEXTUREBUFFER UTEXTUREBUFFER +%token TEXTURE2DMS ITEXTURE2DMS UTEXTURE2DMS +%token TEXTURE2DMSARRAY ITEXTURE2DMSARRAY UTEXTURE2DMSARRAY + +%token F16TEXTURE1D F16TEXTURE2D F16TEXTURE3D F16TEXTURE2DRECT F16TEXTURECUBE +%token F16TEXTURE1DARRAY F16TEXTURE2DARRAY F16TEXTURECUBEARRAY +%token F16TEXTUREBUFFER F16TEXTURE2DMS F16TEXTURE2DMSARRAY + +// input attachments +%token SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS +%token F16SUBPASSINPUT F16SUBPASSINPUTMS + +// spirv intrinsics +%token SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID +%token SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING +%token SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL + +GLSLANG_WEB_EXCLUDE_OFF + +%token LEFT_OP RIGHT_OP +%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP +%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN +%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN +%token SUB_ASSIGN +%token STRING_LITERAL + +%token LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT +%token COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT +%token LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION + +%token INVARIANT +%token HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION +%token PACKED RESOURCE SUPERP + +%token FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token IDENTIFIER TYPE_NAME +%token CENTROID IN OUT INOUT +%token STRUCT VOID WHILE +%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token TERMINATE_INVOCATION +%token TERMINATE_RAY IGNORE_INTERSECTION +%token UNIFORM SHARED BUFFER +%token FLAT SMOOTH LAYOUT + +GLSLANG_WEB_EXCLUDE_ON +%token DOUBLECONSTANT INT16CONSTANT UINT16CONSTANT FLOAT16CONSTANT INT32CONSTANT UINT32CONSTANT +%token INT64CONSTANT UINT64CONSTANT +%token SUBROUTINE DEMOTE +%token PAYLOADNV PAYLOADINNV HITATTRNV CALLDATANV CALLDATAINNV +%token PAYLOADEXT PAYLOADINEXT HITATTREXT CALLDATAEXT CALLDATAINEXT +%token PATCH SAMPLE NONUNIFORM +%token COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT +%token SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT +%token NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV +%token PRECISE +GLSLANG_WEB_EXCLUDE_OFF + +%type assignment_operator unary_operator +%type variable_identifier primary_expression postfix_expression +%type expression integer_expression assignment_expression +%type unary_expression multiplicative_expression additive_expression +%type relational_expression equality_expression +%type conditional_expression constant_expression +%type logical_or_expression logical_xor_expression logical_and_expression +%type shift_expression and_expression exclusive_or_expression inclusive_or_expression +%type function_call initializer condition conditionopt + +%type translation_unit function_definition +%type statement simple_statement +%type statement_list switch_statement_list compound_statement +%type declaration_statement selection_statement selection_statement_nonattributed expression_statement +%type switch_statement switch_statement_nonattributed case_label +%type declaration external_declaration +%type for_init_statement compound_statement_no_new_scope +%type selection_rest_statement for_rest_statement +%type iteration_statement iteration_statement_nonattributed jump_statement statement_no_new_scope statement_scoped +%type single_declaration init_declarator_list + +%type parameter_declaration parameter_declarator parameter_type_specifier + +%type array_specifier +%type invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier +%type layout_qualifier layout_qualifier_id_list layout_qualifier_id + +%type type_parameter_specifier +%type type_parameter_specifier_opt +%type type_parameter_specifier_list + +%type type_qualifier fully_specified_type type_specifier +%type single_type_qualifier +%type type_specifier_nonarray +%type struct_specifier +%type struct_declarator +%type struct_declarator_list struct_declaration struct_declaration_list +%type block_structure +%type function_header function_declarator +%type function_header_with_parameters +%type function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype +%type function_call_or_method function_identifier function_call_header + +%type identifier_list + +GLSLANG_WEB_EXCLUDE_ON +%type precise_qualifier non_uniform_qualifier +%type type_name_list +%type attribute attribute_list single_attribute +%type demote_statement +%type initializer_list +%type spirv_requirements_list spirv_requirements_parameter +%type spirv_extension_list spirv_capability_list +%type spirv_execution_mode_qualifier +%type spirv_execution_mode_parameter_list spirv_execution_mode_parameter spirv_execution_mode_id_parameter_list +%type spirv_storage_class_qualifier +%type spirv_decorate_qualifier +%type spirv_decorate_parameter_list spirv_decorate_parameter +%type spirv_decorate_id_parameter_list +%type spirv_decorate_string_parameter_list +%type spirv_type_specifier +%type spirv_type_parameter_list spirv_type_parameter +%type spirv_instruction_qualifier +%type spirv_instruction_qualifier_list spirv_instruction_qualifier_id +GLSLANG_WEB_EXCLUDE_OFF + +%start translation_unit +%% + +variable_identifier + : IDENTIFIER { + $$ = parseContext.handleVariable($1.loc, $1.symbol, $1.string); + } + ; + +primary_expression + : variable_identifier { + $$ = $1; + } + | LEFT_PAREN expression RIGHT_PAREN { + $$ = $2; + if ($$->getAsConstantUnion()) + $$->getAsConstantUnion()->setExpression(); + } + | FLOATCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); + } + | INTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINTCONSTANT { + parseContext.fullIntegerCheck($1.loc, "unsigned literal"); + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } + | BOOLCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); + } +GLSLANG_WEB_EXCLUDE_ON + | STRING_LITERAL { + $$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true); + } + | INT32CONSTANT { + parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINT32CONSTANT { + parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } + | INT64CONSTANT { + parseContext.int64Check($1.loc, "64-bit integer literal"); + $$ = parseContext.intermediate.addConstantUnion($1.i64, $1.loc, true); + } + | UINT64CONSTANT { + parseContext.int64Check($1.loc, "64-bit unsigned integer literal"); + $$ = parseContext.intermediate.addConstantUnion($1.u64, $1.loc, true); + } + | INT16CONSTANT { + parseContext.explicitInt16Check($1.loc, "16-bit integer literal"); + $$ = parseContext.intermediate.addConstantUnion((short)$1.i, $1.loc, true); + } + | UINT16CONSTANT { + parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer literal"); + $$ = parseContext.intermediate.addConstantUnion((unsigned short)$1.u, $1.loc, true); + } + | DOUBLECONSTANT { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double literal"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double literal"); + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtDouble, $1.loc, true); + } + | FLOAT16CONSTANT { + parseContext.float16Check($1.loc, "half float literal"); + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat16, $1.loc, true); + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +postfix_expression + : primary_expression { + $$ = $1; + } + | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { + $$ = parseContext.handleBracketDereference($2.loc, $1, $3); + } + | function_call { + $$ = $1; + } + | postfix_expression DOT IDENTIFIER { + $$ = parseContext.handleDotDereference($3.loc, $1, *$3.string); + } + | postfix_expression INC_OP { + parseContext.variableCheck($1); + parseContext.lValueErrorCheck($2.loc, "++", $1); + $$ = parseContext.handleUnaryMath($2.loc, "++", EOpPostIncrement, $1); + } + | postfix_expression DEC_OP { + parseContext.variableCheck($1); + parseContext.lValueErrorCheck($2.loc, "--", $1); + $$ = parseContext.handleUnaryMath($2.loc, "--", EOpPostDecrement, $1); + } + ; + +integer_expression + : expression { + parseContext.integerCheck($1, "[]"); + $$ = $1; + } + ; + +function_call + : function_call_or_method { + $$ = parseContext.handleFunctionCall($1.loc, $1.function, $1.intermNode); + delete $1.function; + } + ; + +function_call_or_method + : function_call_generic { + $$ = $1; + } + ; + +function_call_generic + : function_call_header_with_parameters RIGHT_PAREN { + $$ = $1; + $$.loc = $2.loc; + } + | function_call_header_no_parameters RIGHT_PAREN { + $$ = $1; + $$.loc = $2.loc; + } + ; + +function_call_header_no_parameters + : function_call_header VOID { + $$ = $1; + } + | function_call_header { + $$ = $1; + } + ; + +function_call_header_with_parameters + : function_call_header assignment_expression { + TParameter param = { 0, new TType }; + param.type->shallowCopy($2->getType()); + $1.function->addParameter(param); + $$.function = $1.function; + $$.intermNode = $2; + } + | function_call_header_with_parameters COMMA assignment_expression { + TParameter param = { 0, new TType }; + param.type->shallowCopy($3->getType()); + $1.function->addParameter(param); + $$.function = $1.function; + $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc); + } + ; + +function_call_header + : function_identifier LEFT_PAREN { + $$ = $1; + } + ; + +// Grammar Note: Constructors look like functions, but are recognized as types. + +function_identifier + : type_specifier { + // Constructor + $$.intermNode = 0; + $$.function = parseContext.handleConstructorCall($1.loc, $1); + } + | postfix_expression { + // + // Should be a method or subroutine call, but we haven't recognized the arguments yet. + // + $$.function = 0; + $$.intermNode = 0; + + TIntermMethod* method = $1->getAsMethodNode(); + if (method) { + $$.function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength); + $$.intermNode = method->getObject(); + } else { + TIntermSymbol* symbol = $1->getAsSymbolNode(); + if (symbol) { + parseContext.reservedErrorCheck(symbol->getLoc(), symbol->getName()); + TFunction *function = new TFunction(&symbol->getName(), TType(EbtVoid)); + $$.function = function; + } else + parseContext.error($1->getLoc(), "function call, method, or subroutine call expected", "", ""); + } + + if ($$.function == 0) { + // error recover + TString* empty = NewPoolTString(""); + $$.function = new TFunction(empty, TType(EbtVoid), EOpNull); + } + } +GLSLANG_WEB_EXCLUDE_ON + | non_uniform_qualifier { + // Constructor + $$.intermNode = 0; + $$.function = parseContext.handleConstructorCall($1.loc, $1); + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +unary_expression + : postfix_expression { + parseContext.variableCheck($1); + $$ = $1; + if (TIntermMethod* method = $1->getAsMethodNode()) + parseContext.error($1->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); + } + | INC_OP unary_expression { + parseContext.lValueErrorCheck($1.loc, "++", $2); + $$ = parseContext.handleUnaryMath($1.loc, "++", EOpPreIncrement, $2); + } + | DEC_OP unary_expression { + parseContext.lValueErrorCheck($1.loc, "--", $2); + $$ = parseContext.handleUnaryMath($1.loc, "--", EOpPreDecrement, $2); + } + | unary_operator unary_expression { + if ($1.op != EOpNull) { + char errorOp[2] = {0, 0}; + switch($1.op) { + case EOpNegative: errorOp[0] = '-'; break; + case EOpLogicalNot: errorOp[0] = '!'; break; + case EOpBitwiseNot: errorOp[0] = '~'; break; + default: break; // some compilers want this + } + $$ = parseContext.handleUnaryMath($1.loc, errorOp, $1.op, $2); + } else { + $$ = $2; + if ($$->getAsConstantUnion()) + $$->getAsConstantUnion()->setExpression(); + } + } + ; +// Grammar Note: No traditional style type casts. + +unary_operator + : PLUS { $$.loc = $1.loc; $$.op = EOpNull; } + | DASH { $$.loc = $1.loc; $$.op = EOpNegative; } + | BANG { $$.loc = $1.loc; $$.op = EOpLogicalNot; } + | TILDE { $$.loc = $1.loc; $$.op = EOpBitwiseNot; + parseContext.fullIntegerCheck($1.loc, "bitwise not"); } + ; +// Grammar Note: No '*' or '&' unary ops. Pointers are not supported. + +multiplicative_expression + : unary_expression { $$ = $1; } + | multiplicative_expression STAR unary_expression { + $$ = parseContext.handleBinaryMath($2.loc, "*", EOpMul, $1, $3); + if ($$ == 0) + $$ = $1; + } + | multiplicative_expression SLASH unary_expression { + $$ = parseContext.handleBinaryMath($2.loc, "/", EOpDiv, $1, $3); + if ($$ == 0) + $$ = $1; + } + | multiplicative_expression PERCENT unary_expression { + parseContext.fullIntegerCheck($2.loc, "%"); + $$ = parseContext.handleBinaryMath($2.loc, "%", EOpMod, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +additive_expression + : multiplicative_expression { $$ = $1; } + | additive_expression PLUS multiplicative_expression { + $$ = parseContext.handleBinaryMath($2.loc, "+", EOpAdd, $1, $3); + if ($$ == 0) + $$ = $1; + } + | additive_expression DASH multiplicative_expression { + $$ = parseContext.handleBinaryMath($2.loc, "-", EOpSub, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +shift_expression + : additive_expression { $$ = $1; } + | shift_expression LEFT_OP additive_expression { + parseContext.fullIntegerCheck($2.loc, "bit shift left"); + $$ = parseContext.handleBinaryMath($2.loc, "<<", EOpLeftShift, $1, $3); + if ($$ == 0) + $$ = $1; + } + | shift_expression RIGHT_OP additive_expression { + parseContext.fullIntegerCheck($2.loc, "bit shift right"); + $$ = parseContext.handleBinaryMath($2.loc, ">>", EOpRightShift, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +relational_expression + : shift_expression { $$ = $1; } + | relational_expression LEFT_ANGLE shift_expression { + $$ = parseContext.handleBinaryMath($2.loc, "<", EOpLessThan, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + | relational_expression RIGHT_ANGLE shift_expression { + $$ = parseContext.handleBinaryMath($2.loc, ">", EOpGreaterThan, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + | relational_expression LE_OP shift_expression { + $$ = parseContext.handleBinaryMath($2.loc, "<=", EOpLessThanEqual, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + | relational_expression GE_OP shift_expression { + $$ = parseContext.handleBinaryMath($2.loc, ">=", EOpGreaterThanEqual, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +equality_expression + : relational_expression { $$ = $1; } + | equality_expression EQ_OP relational_expression { + parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison"); + parseContext.opaqueCheck($2.loc, $1->getType(), "=="); + parseContext.specializationCheck($2.loc, $1->getType(), "=="); + parseContext.referenceCheck($2.loc, $1->getType(), "=="); + $$ = parseContext.handleBinaryMath($2.loc, "==", EOpEqual, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + | equality_expression NE_OP relational_expression { + parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison"); + parseContext.opaqueCheck($2.loc, $1->getType(), "!="); + parseContext.specializationCheck($2.loc, $1->getType(), "!="); + parseContext.referenceCheck($2.loc, $1->getType(), "!="); + $$ = parseContext.handleBinaryMath($2.loc, "!=", EOpNotEqual, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +and_expression + : equality_expression { $$ = $1; } + | and_expression AMPERSAND equality_expression { + parseContext.fullIntegerCheck($2.loc, "bitwise and"); + $$ = parseContext.handleBinaryMath($2.loc, "&", EOpAnd, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +exclusive_or_expression + : and_expression { $$ = $1; } + | exclusive_or_expression CARET and_expression { + parseContext.fullIntegerCheck($2.loc, "bitwise exclusive or"); + $$ = parseContext.handleBinaryMath($2.loc, "^", EOpExclusiveOr, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +inclusive_or_expression + : exclusive_or_expression { $$ = $1; } + | inclusive_or_expression VERTICAL_BAR exclusive_or_expression { + parseContext.fullIntegerCheck($2.loc, "bitwise inclusive or"); + $$ = parseContext.handleBinaryMath($2.loc, "|", EOpInclusiveOr, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +logical_and_expression + : inclusive_or_expression { $$ = $1; } + | logical_and_expression AND_OP inclusive_or_expression { + $$ = parseContext.handleBinaryMath($2.loc, "&&", EOpLogicalAnd, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +logical_xor_expression + : logical_and_expression { $$ = $1; } + | logical_xor_expression XOR_OP logical_and_expression { + $$ = parseContext.handleBinaryMath($2.loc, "^^", EOpLogicalXor, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +logical_or_expression + : logical_xor_expression { $$ = $1; } + | logical_or_expression OR_OP logical_xor_expression { + $$ = parseContext.handleBinaryMath($2.loc, "||", EOpLogicalOr, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +conditional_expression + : logical_or_expression { $$ = $1; } + | logical_or_expression QUESTION { + ++parseContext.controlFlowNestingLevel; + } + expression COLON assignment_expression { + --parseContext.controlFlowNestingLevel; + parseContext.boolCheck($2.loc, $1); + parseContext.rValueErrorCheck($2.loc, "?", $1); + parseContext.rValueErrorCheck($5.loc, ":", $4); + parseContext.rValueErrorCheck($5.loc, ":", $6); + $$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc); + if ($$ == 0) { + parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(), $6->getCompleteString()); + $$ = $6; + } + } + ; + +assignment_expression + : conditional_expression { $$ = $1; } + | unary_expression assignment_operator assignment_expression { + parseContext.arrayObjectCheck($2.loc, $1->getType(), "array assignment"); + parseContext.opaqueCheck($2.loc, $1->getType(), "="); + parseContext.storage16BitAssignmentCheck($2.loc, $1->getType(), "="); + parseContext.specializationCheck($2.loc, $1->getType(), "="); + parseContext.lValueErrorCheck($2.loc, "assign", $1); + parseContext.rValueErrorCheck($2.loc, "assign", $3); + $$ = parseContext.addAssign($2.loc, $2.op, $1, $3); + if ($$ == 0) { + parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString()); + $$ = $1; + } + } + ; + +assignment_operator + : EQUAL { + $$.loc = $1.loc; + $$.op = EOpAssign; + } + | MUL_ASSIGN { + $$.loc = $1.loc; + $$.op = EOpMulAssign; + } + | DIV_ASSIGN { + $$.loc = $1.loc; + $$.op = EOpDivAssign; + } + | MOD_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "%="); + $$.loc = $1.loc; + $$.op = EOpModAssign; + } + | ADD_ASSIGN { + $$.loc = $1.loc; + $$.op = EOpAddAssign; + } + | SUB_ASSIGN { + $$.loc = $1.loc; + $$.op = EOpSubAssign; + } + | LEFT_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bit-shift left assign"); + $$.loc = $1.loc; $$.op = EOpLeftShiftAssign; + } + | RIGHT_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bit-shift right assign"); + $$.loc = $1.loc; $$.op = EOpRightShiftAssign; + } + | AND_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bitwise-and assign"); + $$.loc = $1.loc; $$.op = EOpAndAssign; + } + | XOR_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bitwise-xor assign"); + $$.loc = $1.loc; $$.op = EOpExclusiveOrAssign; + } + | OR_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bitwise-or assign"); + $$.loc = $1.loc; $$.op = EOpInclusiveOrAssign; + } + ; + +expression + : assignment_expression { + $$ = $1; + } + | expression COMMA assignment_expression { + parseContext.samplerConstructorLocationCheck($2.loc, ",", $3); + $$ = parseContext.intermediate.addComma($1, $3, $2.loc); + if ($$ == 0) { + parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString()); + $$ = $3; + } + } + ; + +constant_expression + : conditional_expression { + parseContext.constantValueCheck($1, ""); + $$ = $1; + } + ; + +declaration + : function_prototype SEMICOLON { + parseContext.handleFunctionDeclarator($1.loc, *$1.function, true /* prototype */); + $$ = 0; + // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature + } +GLSLANG_WEB_EXCLUDE_ON + | spirv_instruction_qualifier function_prototype SEMICOLON { + parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier"); + $2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier + parseContext.handleFunctionDeclarator($2.loc, *$2.function, true /* prototype */); + $$ = 0; + // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature + } + | spirv_execution_mode_qualifier SEMICOLON { + parseContext.globalCheck($2.loc, "SPIR-V execution mode qualifier"); + parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier"); + $$ = 0; + } +GLSLANG_WEB_EXCLUDE_OFF + | init_declarator_list SEMICOLON { + if ($1.intermNode && $1.intermNode->getAsAggregate()) + $1.intermNode->getAsAggregate()->setOperator(EOpSequence); + $$ = $1.intermNode; + } + | PRECISION precision_qualifier type_specifier SEMICOLON { + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "precision statement"); + // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope + parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]); + parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision); + $$ = 0; + } + | block_structure SEMICOLON { + parseContext.declareBlock($1.loc, *$1.typeList); + $$ = 0; + } + | block_structure IDENTIFIER SEMICOLON { + parseContext.declareBlock($1.loc, *$1.typeList, $2.string); + $$ = 0; + } + | block_structure IDENTIFIER array_specifier SEMICOLON { + parseContext.declareBlock($1.loc, *$1.typeList, $2.string, $3.arraySizes); + $$ = 0; + } + | type_qualifier SEMICOLON { + parseContext.globalQualifierFixCheck($1.loc, $1.qualifier); + parseContext.updateStandaloneQualifierDefaults($1.loc, $1); + $$ = 0; + } + | type_qualifier IDENTIFIER SEMICOLON { + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string); + $$ = 0; + } + | type_qualifier IDENTIFIER identifier_list SEMICOLON { + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + $3->push_back($2.string); + parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3); + $$ = 0; + } + ; + +block_structure + : type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.loc); } struct_declaration_list RIGHT_BRACE { + --parseContext.blockNestingLevel; + parseContext.blockName = $2.string; + parseContext.globalQualifierFixCheck($1.loc, $1.qualifier); + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + parseContext.currentBlockQualifier = $1.qualifier; + $$.loc = $1.loc; + $$.typeList = $5; + } + +identifier_list + : COMMA IDENTIFIER { + $$ = new TIdentifierList; + $$->push_back($2.string); + } + | identifier_list COMMA IDENTIFIER { + $$ = $1; + $$->push_back($3.string); + } + ; + +function_prototype + : function_declarator RIGHT_PAREN { + $$.function = $1; + $$.loc = $2.loc; + } + | function_declarator RIGHT_PAREN attribute { + $$.function = $1; + $$.loc = $2.loc; + parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); + parseContext.handleFunctionAttributes($2.loc, *$3, $$.function); + } + | attribute function_declarator RIGHT_PAREN { + $$.function = $2; + $$.loc = $3.loc; + parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); + parseContext.handleFunctionAttributes($3.loc, *$1, $$.function); + } + | attribute function_declarator RIGHT_PAREN attribute { + $$.function = $2; + $$.loc = $3.loc; + parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); + parseContext.handleFunctionAttributes($3.loc, *$1, $$.function); + parseContext.handleFunctionAttributes($3.loc, *$4, $$.function); + } + ; + +function_declarator + : function_header { + $$ = $1; + } + | function_header_with_parameters { + $$ = $1; + } + ; + + +function_header_with_parameters + : function_header parameter_declaration { + // Add the parameter + $$ = $1; + if ($2.param.type->getBasicType() != EbtVoid) + $1->addParameter($2.param); + else + delete $2.param.type; + } + | function_header_with_parameters COMMA parameter_declaration { + // + // Only first parameter of one-parameter functions can be void + // The check for named parameters not being void is done in parameter_declarator + // + if ($3.param.type->getBasicType() == EbtVoid) { + // + // This parameter > first is void + // + parseContext.error($2.loc, "cannot be an argument type except for '(void)'", "void", ""); + delete $3.param.type; + } else { + // Add the parameter + $$ = $1; + $1->addParameter($3.param); + } + } + ; + +function_header + : fully_specified_type IDENTIFIER LEFT_PAREN { + if ($1.qualifier.storage != EvqGlobal && $1.qualifier.storage != EvqTemporary) { + parseContext.error($2.loc, "no qualifiers allowed for function return", + GetStorageQualifierString($1.qualifier.storage), ""); + } + if ($1.arraySizes) + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + + // Add the function as a prototype after parsing it (we do not support recursion) + TFunction *function; + TType type($1); + + // Potentially rename shader entry point function. No-op most of the time. + parseContext.renameShaderFunction($2.string); + + // Make the function + function = new TFunction($2.string, type); + $$ = function; + } + ; + +parameter_declarator + // Type + name + : type_specifier IDENTIFIER { + if ($1.arraySizes) { + parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + } + if ($1.basicType == EbtVoid) { + parseContext.error($2.loc, "illegal use of type 'void'", $2.string->c_str(), ""); + } + parseContext.reservedErrorCheck($2.loc, *$2.string); + + TParameter param = {$2.string, new TType($1)}; + $$.loc = $2.loc; + $$.param = param; + } + | type_specifier IDENTIFIER array_specifier { + if ($1.arraySizes) { + parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + } + TType* type = new TType($1); + type->transferArraySizes($3.arraySizes); + type->copyArrayInnerSizes($1.arraySizes); + + parseContext.arrayOfArrayVersionCheck($2.loc, type->getArraySizes()); + parseContext.arraySizeRequiredCheck($3.loc, *$3.arraySizes); + parseContext.reservedErrorCheck($2.loc, *$2.string); + + TParameter param = { $2.string, type }; + + $$.loc = $2.loc; + $$.param = param; + } + ; + +parameter_declaration + // + // With name + // + : type_qualifier parameter_declarator { + $$ = $2; + if ($1.qualifier.precision != EpqNone) + $$.param.type->getQualifier().precision = $1.qualifier.precision; + parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier()); + + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + parseContext.parameterTypeCheck($2.loc, $1.qualifier.storage, *$$.param.type); + parseContext.paramCheckFix($1.loc, $1.qualifier, *$$.param.type); + + } + | parameter_declarator { + $$ = $1; + + parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type); + parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type); + parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier()); + } + // + // Without name + // + | type_qualifier parameter_type_specifier { + $$ = $2; + if ($1.qualifier.precision != EpqNone) + $$.param.type->getQualifier().precision = $1.qualifier.precision; + parseContext.precisionQualifierCheck($1.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier()); + + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + parseContext.parameterTypeCheck($2.loc, $1.qualifier.storage, *$$.param.type); + parseContext.paramCheckFix($1.loc, $1.qualifier, *$$.param.type); + } + | parameter_type_specifier { + $$ = $1; + + parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type); + parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type); + parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier()); + } + ; + +parameter_type_specifier + : type_specifier { + TParameter param = { 0, new TType($1) }; + $$.param = param; + if ($1.arraySizes) + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + } + ; + +init_declarator_list + : single_declaration { + $$ = $1; + } + | init_declarator_list COMMA IDENTIFIER { + $$ = $1; + parseContext.declareVariable($3.loc, *$3.string, $1.type); + } + | init_declarator_list COMMA IDENTIFIER array_specifier { + $$ = $1; + parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes); + } + | init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer { + $$.type = $1.type; + TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes, $6); + $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, initNode, $5.loc); + } + | init_declarator_list COMMA IDENTIFIER EQUAL initializer { + $$.type = $1.type; + TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, 0, $5); + $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, initNode, $4.loc); + } + ; + +single_declaration + : fully_specified_type { + $$.type = $1; + $$.intermNode = 0; +GLSLANG_WEB_EXCLUDE_ON + parseContext.declareTypeDefaults($$.loc, $$.type); +GLSLANG_WEB_EXCLUDE_OFF + } + | fully_specified_type IDENTIFIER { + $$.type = $1; + $$.intermNode = 0; + parseContext.declareVariable($2.loc, *$2.string, $1); + } + | fully_specified_type IDENTIFIER array_specifier { + $$.type = $1; + $$.intermNode = 0; + parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes); + } + | fully_specified_type IDENTIFIER array_specifier EQUAL initializer { + $$.type = $1; + TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes, $5); + $$.intermNode = parseContext.intermediate.growAggregate(0, initNode, $4.loc); + } + | fully_specified_type IDENTIFIER EQUAL initializer { + $$.type = $1; + TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4); + $$.intermNode = parseContext.intermediate.growAggregate(0, initNode, $3.loc); + } + +// Grammar Note: No 'enum', or 'typedef'. + +fully_specified_type + : type_specifier { + $$ = $1; + + parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $$); + if ($1.arraySizes) { + parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + } + parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier); + } + | type_qualifier type_specifier { + parseContext.globalQualifierFixCheck($1.loc, $1.qualifier); + parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $2); + + if ($2.arraySizes) { + parseContext.profileRequires($2.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); + } + + if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1.qualifier)) + $2.arraySizes = nullptr; + + parseContext.checkNoShaderLayouts($2.loc, $1.shaderQualifiers); + $2.shaderQualifiers.merge($1.shaderQualifiers); + parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true); + parseContext.precisionQualifierCheck($2.loc, $2.basicType, $2.qualifier); + + $$ = $2; + + if (! $$.qualifier.isInterpolation() && + ((parseContext.language == EShLangVertex && $$.qualifier.storage == EvqVaryingOut) || + (parseContext.language == EShLangFragment && $$.qualifier.storage == EvqVaryingIn))) + $$.qualifier.smooth = true; + } + ; + +invariant_qualifier + : INVARIANT { + parseContext.globalCheck($1.loc, "invariant"); + parseContext.profileRequires($$.loc, ENoProfile, 120, 0, "invariant"); + $$.init($1.loc); + $$.qualifier.invariant = true; + } + ; + +interpolation_qualifier + : SMOOTH { + parseContext.globalCheck($1.loc, "smooth"); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "smooth"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "smooth"); + $$.init($1.loc); + $$.qualifier.smooth = true; + } + | FLAT { + parseContext.globalCheck($1.loc, "flat"); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "flat"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "flat"); + $$.init($1.loc); + $$.qualifier.flat = true; + } +GLSLANG_WEB_EXCLUDE_ON + | NOPERSPECTIVE { + parseContext.globalCheck($1.loc, "noperspective"); + parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective"); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "noperspective"); + $$.init($1.loc); + $$.qualifier.nopersp = true; + } + | EXPLICITINTERPAMD { + parseContext.globalCheck($1.loc, "__explicitInterpAMD"); + parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); + parseContext.profileRequires($1.loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); + $$.init($1.loc); + $$.qualifier.explicitInterp = true; + } + | PERVERTEXNV { + parseContext.globalCheck($1.loc, "pervertexNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires($1.loc, ECompatibilityProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + $$.init($1.loc); + $$.qualifier.pervertexNV = true; + } + | PERPRIMITIVENV { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck($1.loc, "perprimitiveNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV"); + // Fragment shader stage doesn't check for extension. So we explicitly add below extension check. + if (parseContext.language == EShLangFragment) + parseContext.requireExtensions($1.loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV"); + $$.init($1.loc); + $$.qualifier.perPrimitiveNV = true; + } + | PERVIEWNV { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck($1.loc, "perviewNV"); + parseContext.requireStage($1.loc, EShLangMeshNV, "perviewNV"); + $$.init($1.loc); + $$.qualifier.perViewNV = true; + } + | PERTASKNV { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck($1.loc, "taskNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV"); + $$.init($1.loc); + $$.qualifier.perTaskNV = true; + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +layout_qualifier + : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN { + $$ = $3; + } + ; + +layout_qualifier_id_list + : layout_qualifier_id { + $$ = $1; + } + | layout_qualifier_id_list COMMA layout_qualifier_id { + $$ = $1; + $$.shaderQualifiers.merge($3.shaderQualifiers); + parseContext.mergeObjectLayoutQualifiers($$.qualifier, $3.qualifier, false); + } + +layout_qualifier_id + : IDENTIFIER { + $$.init($1.loc); + parseContext.setLayoutQualifier($1.loc, $$, *$1.string); + } + | IDENTIFIER EQUAL constant_expression { + $$.init($1.loc); + parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3); + } + | SHARED { // because "shared" is both an identifier and a keyword + $$.init($1.loc); + TString strShared("shared"); + parseContext.setLayoutQualifier($1.loc, $$, strShared); + } + ; + +GLSLANG_WEB_EXCLUDE_ON +precise_qualifier + : PRECISE { + parseContext.profileRequires($$.loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); + parseContext.profileRequires($1.loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "precise"); + $$.init($1.loc); + $$.qualifier.noContraction = true; + } + ; +GLSLANG_WEB_EXCLUDE_OFF + +type_qualifier + : single_type_qualifier { + $$ = $1; + } + | type_qualifier single_type_qualifier { + $$ = $1; + if ($$.basicType == EbtVoid) + $$.basicType = $2.basicType; + + $$.shaderQualifiers.merge($2.shaderQualifiers); + parseContext.mergeQualifiers($$.loc, $$.qualifier, $2.qualifier, false); + } + ; + +single_type_qualifier + : storage_qualifier { + $$ = $1; + } + | layout_qualifier { + $$ = $1; + } + | precision_qualifier { + parseContext.checkPrecisionQualifier($1.loc, $1.qualifier.precision); + $$ = $1; + } + | interpolation_qualifier { + // allow inheritance of storage qualifier from block declaration + $$ = $1; + } + | invariant_qualifier { + // allow inheritance of storage qualifier from block declaration + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | precise_qualifier { + // allow inheritance of storage qualifier from block declaration + $$ = $1; + } + | non_uniform_qualifier { + $$ = $1; + } + | spirv_storage_class_qualifier { + parseContext.globalCheck($1.loc, "spirv_storage_class"); + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier"); + $$ = $1; + } + | spirv_decorate_qualifier { + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier"); + $$ = $1; + } + | SPIRV_BY_REFERENCE { + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference"); + $$.init($1.loc); + $$.qualifier.setSpirvByReference(); + } + | SPIRV_LITERAL { + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal"); + $$.init($1.loc); + $$.qualifier.setSpirvLiteral(); + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +storage_qualifier + : CONST { + $$.init($1.loc); + $$.qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant + } + | INOUT { + parseContext.globalCheck($1.loc, "inout"); + $$.init($1.loc); + $$.qualifier.storage = EvqInOut; + } + | IN { + parseContext.globalCheck($1.loc, "in"); + $$.init($1.loc); + // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later + $$.qualifier.storage = EvqIn; + } + | OUT { + parseContext.globalCheck($1.loc, "out"); + $$.init($1.loc); + // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later + $$.qualifier.storage = EvqOut; + } + | CENTROID { + parseContext.profileRequires($1.loc, ENoProfile, 120, 0, "centroid"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "centroid"); + parseContext.globalCheck($1.loc, "centroid"); + $$.init($1.loc); + $$.qualifier.centroid = true; + } + | UNIFORM { + parseContext.globalCheck($1.loc, "uniform"); + $$.init($1.loc); + $$.qualifier.storage = EvqUniform; + } + | SHARED { + parseContext.globalCheck($1.loc, "shared"); + parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); + parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); + $$.init($1.loc); + $$.qualifier.storage = EvqShared; + } + | BUFFER { + parseContext.globalCheck($1.loc, "buffer"); + $$.init($1.loc); + $$.qualifier.storage = EvqBuffer; + } +GLSLANG_WEB_EXCLUDE_ON + | ATTRIBUTE { + parseContext.requireStage($1.loc, EShLangVertex, "attribute"); + parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute"); + parseContext.checkDeprecated($1.loc, ENoProfile, 130, "attribute"); + parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "attribute"); + parseContext.requireNotRemoved($1.loc, EEsProfile, 300, "attribute"); + + parseContext.globalCheck($1.loc, "attribute"); + + $$.init($1.loc); + $$.qualifier.storage = EvqVaryingIn; + } + | VARYING { + parseContext.checkDeprecated($1.loc, ENoProfile, 130, "varying"); + parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "varying"); + parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "varying"); + parseContext.requireNotRemoved($1.loc, EEsProfile, 300, "varying"); + + parseContext.globalCheck($1.loc, "varying"); + + $$.init($1.loc); + if (parseContext.language == EShLangVertex) + $$.qualifier.storage = EvqVaryingOut; + else + $$.qualifier.storage = EvqVaryingIn; + } + | PATCH { + parseContext.globalCheck($1.loc, "patch"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); + $$.init($1.loc); + $$.qualifier.patch = true; + } + | SAMPLE { + parseContext.globalCheck($1.loc, "sample"); + $$.init($1.loc); + $$.qualifier.sample = true; + } + | HITATTRNV { + parseContext.globalCheck($1.loc, "hitAttributeNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask + | EShLangAnyHitMask), "hitAttributeNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqHitAttr; + } + | HITATTREXT { + parseContext.globalCheck($1.loc, "hitAttributeEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask + | EShLangAnyHitMask), "hitAttributeEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "hitAttributeNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqHitAttr; + } + | PAYLOADNV { + parseContext.globalCheck($1.loc, "rayPayloadNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqPayload; + } + | PAYLOADEXT { + parseContext.globalCheck($1.loc, "rayPayloadEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "rayPayloadEXT"); + $$.init($1.loc); + $$.qualifier.storage = EvqPayload; + } + | PAYLOADINNV { + parseContext.globalCheck($1.loc, "rayPayloadInNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadInNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqPayloadIn; + } + | PAYLOADINEXT { + parseContext.globalCheck($1.loc, "rayPayloadInEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadInEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "rayPayloadInEXT"); + $$.init($1.loc); + $$.qualifier.storage = EvqPayloadIn; + } + | CALLDATANV { + parseContext.globalCheck($1.loc, "callableDataNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | + EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqCallableData; + } + | CALLDATAEXT { + parseContext.globalCheck($1.loc, "callableDataEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | + EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "callableDataEXT"); + $$.init($1.loc); + $$.qualifier.storage = EvqCallableData; + } + | CALLDATAINNV { + parseContext.globalCheck($1.loc, "callableDataInNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqCallableDataIn; + } + | CALLDATAINEXT { + parseContext.globalCheck($1.loc, "callableDataInEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "callableDataInEXT"); + $$.init($1.loc); + $$.qualifier.storage = EvqCallableDataIn; + } + | COHERENT { + $$.init($1.loc); + $$.qualifier.coherent = true; + } + | DEVICECOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent"); + $$.qualifier.devicecoherent = true; + } + | QUEUEFAMILYCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent"); + $$.qualifier.queuefamilycoherent = true; + } + | WORKGROUPCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent"); + $$.qualifier.workgroupcoherent = true; + } + | SUBGROUPCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent"); + $$.qualifier.subgroupcoherent = true; + } + | NONPRIVATE { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate"); + $$.qualifier.nonprivate = true; + } + | SHADERCALLCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_ray_tracing, "shadercallcoherent"); + $$.qualifier.shadercallcoherent = true; + } + | VOLATILE { + $$.init($1.loc); + $$.qualifier.volatil = true; + } + | RESTRICT { + $$.init($1.loc); + $$.qualifier.restrict = true; + } + | READONLY { + $$.init($1.loc); + $$.qualifier.readonly = true; + } + | WRITEONLY { + $$.init($1.loc); + $$.qualifier.writeonly = true; + } + | SUBROUTINE { + parseContext.spvRemoved($1.loc, "subroutine"); + parseContext.globalCheck($1.loc, "subroutine"); + parseContext.unimplemented($1.loc, "subroutine"); + $$.init($1.loc); + } + | SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN { + parseContext.spvRemoved($1.loc, "subroutine"); + parseContext.globalCheck($1.loc, "subroutine"); + parseContext.unimplemented($1.loc, "subroutine"); + $$.init($1.loc); + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +GLSLANG_WEB_EXCLUDE_ON +non_uniform_qualifier + : NONUNIFORM { + $$.init($1.loc); + $$.qualifier.nonUniform = true; + } + ; + +type_name_list + : IDENTIFIER { + // TODO + } + | type_name_list COMMA IDENTIFIER { + // TODO: 4.0 semantics: subroutines + // 1) make sure each identifier is a type declared earlier with SUBROUTINE + // 2) save all of the identifiers for future comparison with the declared function + } + ; +GLSLANG_WEB_EXCLUDE_OFF + +type_specifier + : type_specifier_nonarray type_parameter_specifier_opt { + $$ = $1; + $$.qualifier.precision = parseContext.getDefaultPrecision($$); + $$.typeParameters = $2; + } + | type_specifier_nonarray type_parameter_specifier_opt array_specifier { + parseContext.arrayOfArrayVersionCheck($3.loc, $3.arraySizes); + $$ = $1; + $$.qualifier.precision = parseContext.getDefaultPrecision($$); + $$.typeParameters = $2; + $$.arraySizes = $3.arraySizes; + } + ; + +array_specifier + : LEFT_BRACKET RIGHT_BRACKET { + $$.loc = $1.loc; + $$.arraySizes = new TArraySizes; + $$.arraySizes->addInnerSize(); + } + | LEFT_BRACKET conditional_expression RIGHT_BRACKET { + $$.loc = $1.loc; + $$.arraySizes = new TArraySizes; + + TArraySize size; + parseContext.arraySizeCheck($2->getLoc(), $2, size, "array size"); + $$.arraySizes->addInnerSize(size); + } + | array_specifier LEFT_BRACKET RIGHT_BRACKET { + $$ = $1; + $$.arraySizes->addInnerSize(); + } + | array_specifier LEFT_BRACKET conditional_expression RIGHT_BRACKET { + $$ = $1; + + TArraySize size; + parseContext.arraySizeCheck($3->getLoc(), $3, size, "array size"); + $$.arraySizes->addInnerSize(size); + } + ; + +type_parameter_specifier_opt + : type_parameter_specifier { + $$ = $1; + } + | /* May be null */ { + $$ = 0; + } + ; + +type_parameter_specifier + : LEFT_ANGLE type_parameter_specifier_list RIGHT_ANGLE { + $$ = $2; + } + ; + +type_parameter_specifier_list + : unary_expression { + $$ = new TArraySizes; + + TArraySize size; + parseContext.arraySizeCheck($1->getLoc(), $1, size, "type parameter"); + $$->addInnerSize(size); + } + | type_parameter_specifier_list COMMA unary_expression { + $$ = $1; + + TArraySize size; + parseContext.arraySizeCheck($3->getLoc(), $3, size, "type parameter"); + $$->addInnerSize(size); + } + ; + +type_specifier_nonarray + : VOID { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtVoid; + } + | FLOAT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + } + | INT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + } + | UINT { + parseContext.fullIntegerCheck($1.loc, "unsigned integer"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + } + | BOOL { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + } + | VEC2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(2); + } + | VEC3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(3); + } + | VEC4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(4); + } + | BVEC2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + $$.setVector(2); + } + | BVEC3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + $$.setVector(3); + } + | BVEC4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + $$.setVector(4); + } + | IVEC2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(2); + } + | IVEC3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(3); + } + | IVEC4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(4); + } + | UVEC2 { + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(2); + } + | UVEC3 { + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(3); + } + | UVEC4 { + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(4); + } + | MAT2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | MAT3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | MAT4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } + | MAT2X2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | MAT2X3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 3); + } + | MAT2X4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 4); + } + | MAT3X2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 2); + } + | MAT3X3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | MAT3X4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 4); + } + | MAT4X2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 2); + } + | MAT4X3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 3); + } + | MAT4X4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } +GLSLANG_WEB_EXCLUDE_ON + | DOUBLE { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + } + | FLOAT16_T { + parseContext.float16ScalarVectorCheck($1.loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + } + | FLOAT32_T { + parseContext.explicitFloat32Check($1.loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + } + | FLOAT64_T { + parseContext.explicitFloat64Check($1.loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + } + | INT8_T { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + } + | UINT8_T { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + } + | INT16_T { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + } + | UINT16_T { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + } + | INT32_T { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + } + | UINT32_T { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + } + | INT64_T { + parseContext.int64Check($1.loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + } + | UINT64_T { + parseContext.int64Check($1.loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + } + | DVEC2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(2); + } + | DVEC3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(3); + } + | DVEC4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(4); + } + | F16VEC2 { + parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setVector(2); + } + | F16VEC3 { + parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setVector(3); + } + | F16VEC4 { + parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setVector(4); + } + | F32VEC2 { + parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(2); + } + | F32VEC3 { + parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(3); + } + | F32VEC4 { + parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(4); + } + | F64VEC2 { + parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(2); + } + | F64VEC3 { + parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(3); + } + | F64VEC4 { + parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(4); + } + | I8VEC2 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + $$.setVector(2); + } + | I8VEC3 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + $$.setVector(3); + } + | I8VEC4 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + $$.setVector(4); + } + | I16VEC2 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + $$.setVector(2); + } + | I16VEC3 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + $$.setVector(3); + } + | I16VEC4 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + $$.setVector(4); + } + | I32VEC2 { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(2); + } + | I32VEC3 { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(3); + } + | I32VEC4 { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(4); + } + | I64VEC2 { + parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + $$.setVector(2); + } + | I64VEC3 { + parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + $$.setVector(3); + } + | I64VEC4 { + parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + $$.setVector(4); + } + | U8VEC2 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + $$.setVector(2); + } + | U8VEC3 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + $$.setVector(3); + } + | U8VEC4 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + $$.setVector(4); + } + | U16VEC2 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + $$.setVector(2); + } + | U16VEC3 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + $$.setVector(3); + } + | U16VEC4 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + $$.setVector(4); + } + | U32VEC2 { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(2); + } + | U32VEC3 { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(3); + } + | U32VEC4 { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(4); + } + | U64VEC2 { + parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + $$.setVector(2); + } + | U64VEC3 { + parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + $$.setVector(3); + } + | U64VEC4 { + parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + $$.setVector(4); + } + | DMAT2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 2); + } + | DMAT3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 3); + } + | DMAT4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 4); + } + | DMAT2X2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 2); + } + | DMAT2X3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 3); + } + | DMAT2X4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 4); + } + | DMAT3X2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 2); + } + | DMAT3X3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 3); + } + | DMAT3X4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 4); + } + | DMAT4X2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 2); + } + | DMAT4X3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 3); + } + | DMAT4X4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 4); + } + | F16MAT2 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(2, 2); + } + | F16MAT3 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(3, 3); + } + | F16MAT4 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(4, 4); + } + | F16MAT2X2 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(2, 2); + } + | F16MAT2X3 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(2, 3); + } + | F16MAT2X4 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(2, 4); + } + | F16MAT3X2 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(3, 2); + } + | F16MAT3X3 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(3, 3); + } + | F16MAT3X4 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(3, 4); + } + | F16MAT4X2 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(4, 2); + } + | F16MAT4X3 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(4, 3); + } + | F16MAT4X4 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(4, 4); + } + | F32MAT2 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | F32MAT3 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | F32MAT4 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } + | F32MAT2X2 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | F32MAT2X3 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 3); + } + | F32MAT2X4 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 4); + } + | F32MAT3X2 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 2); + } + | F32MAT3X3 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | F32MAT3X4 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 4); + } + | F32MAT4X2 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 2); + } + | F32MAT4X3 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 3); + } + | F32MAT4X4 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } + | F64MAT2 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 2); + } + | F64MAT3 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 3); + } + | F64MAT4 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 4); + } + | F64MAT2X2 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 2); + } + | F64MAT2X3 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 3); + } + | F64MAT2X4 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 4); + } + | F64MAT3X2 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 2); + } + | F64MAT3X3 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 3); + } + | F64MAT3X4 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 4); + } + | F64MAT4X2 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 2); + } + | F64MAT4X3 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 3); + } + | F64MAT4X4 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 4); + } + | ACCSTRUCTNV { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtAccStruct; + } + | ACCSTRUCTEXT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtAccStruct; + } + | RAYQUERYEXT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtRayQuery; + } + | ATOMIC_UINT { + parseContext.vulkanRemoved($1.loc, "atomic counter types"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtAtomicUint; + } + | SAMPLER1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D); + } +GLSLANG_WEB_EXCLUDE_OFF + | SAMPLER2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D); + } + | SAMPLER3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd3D); + } + | SAMPLERCUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdCube); + } + | SAMPLER2DSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, false, true); + } + | SAMPLERCUBESHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdCube, false, true); + } + | SAMPLER2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, true); + } + | SAMPLER2DARRAYSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, true, true); + } +GLSLANG_WEB_EXCLUDE_ON + | SAMPLER1DSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, false, true); + } + | SAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, true); + } + | SAMPLER1DARRAYSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, true, true); + } + | SAMPLERCUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdCube, true); + } + | SAMPLERCUBEARRAYSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdCube, true, true); + } + | F16SAMPLER1D { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd1D); + } + | F16SAMPLER2D { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D); + } + | F16SAMPLER3D { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd3D); + } + | F16SAMPLERCUBE { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdCube); + } + | F16SAMPLER1DSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd1D, false, true); + } + | F16SAMPLER2DSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, false, true); + } + | F16SAMPLERCUBESHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdCube, false, true); + } + | F16SAMPLER1DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd1D, true); + } + | F16SAMPLER2DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, true); + } + | F16SAMPLER1DARRAYSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd1D, true, true); + } + | F16SAMPLER2DARRAYSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, true, true); + } + | F16SAMPLERCUBEARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdCube, true); + } + | F16SAMPLERCUBEARRAYSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdCube, true, true); + } + | ISAMPLER1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd1D); + } +GLSLANG_WEB_EXCLUDE_OFF + | ISAMPLER2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd2D); + } + | ISAMPLER3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd3D); + } + | ISAMPLERCUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdCube); + } + | ISAMPLER2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd2D, true); + } + | USAMPLER2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D); + } + | USAMPLER3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd3D); + } + | USAMPLERCUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, EsdCube); + } +GLSLANG_WEB_EXCLUDE_ON + | ISAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd1D, true); + } + | ISAMPLERCUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdCube, true); + } + | USAMPLER1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd1D); + } + | USAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd1D, true); + } + | USAMPLERCUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, EsdCube, true); + } + | TEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdCube, true); + } + | ITEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdCube, true); + } + | UTEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdCube, true); + } +GLSLANG_WEB_EXCLUDE_OFF + | USAMPLER2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D, true); + } + | TEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D); + } + | TEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd3D); + } + | TEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D, true); + } + | TEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdCube); + } + | ITEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D); + } + | ITEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd3D); + } + | ITEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdCube); + } + | ITEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D, true); + } + | UTEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D); + } + | UTEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd3D); + } + | UTEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdCube); + } + | UTEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D, true); + } + | SAMPLER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setPureSampler(false); + } + | SAMPLERSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setPureSampler(true); + } +GLSLANG_WEB_EXCLUDE_ON + | SAMPLER2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdRect); + } + | SAMPLER2DRECTSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdRect, false, true); + } + | F16SAMPLER2DRECT { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdRect); + } + | F16SAMPLER2DRECTSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdRect, false, true); + } + | ISAMPLER2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdRect); + } + | USAMPLER2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, EsdRect); + } + | SAMPLERBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdBuffer); + } + | F16SAMPLERBUFFER { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdBuffer); + } + | ISAMPLERBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdBuffer); + } + | USAMPLERBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, EsdBuffer); + } + | SAMPLER2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, false, false, true); + } + | F16SAMPLER2DMS { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, false, false, true); + } + | ISAMPLER2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd2D, false, false, true); + } + | USAMPLER2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D, false, false, true); + } + | SAMPLER2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, true, false, true); + } + | F16SAMPLER2DMSARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, true, false, true); + } + | ISAMPLER2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd2D, true, false, true); + } + | USAMPLER2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D, true, false, true); + } + | TEXTURE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd1D); + } + | F16TEXTURE1D { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd1D); + } + | F16TEXTURE2D { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd2D); + } + | F16TEXTURE3D { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd3D); + } + | F16TEXTURECUBE { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, EsdCube); + } + | TEXTURE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd1D, true); + } + | F16TEXTURE1DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd1D, true); + } + | F16TEXTURE2DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd2D, true); + } + | F16TEXTURECUBEARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, EsdCube, true); + } + | ITEXTURE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd1D); + } + | ITEXTURE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd1D, true); + } + | UTEXTURE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd1D); + } + | UTEXTURE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd1D, true); + } + | TEXTURE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdRect); + } + | F16TEXTURE2DRECT { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, EsdRect); + } + | ITEXTURE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdRect); + } + | UTEXTURE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdRect); + } + | TEXTUREBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdBuffer); + } + | F16TEXTUREBUFFER { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, EsdBuffer); + } + | ITEXTUREBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdBuffer); + } + | UTEXTUREBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdBuffer); + } + | TEXTURE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D, false, false, true); + } + | F16TEXTURE2DMS { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd2D, false, false, true); + } + | ITEXTURE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D, false, false, true); + } + | UTEXTURE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D, false, false, true); + } + | TEXTURE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D, true, false, true); + } + | F16TEXTURE2DMSARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd2D, true, false, true); + } + | ITEXTURE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D, true, false, true); + } + | UTEXTURE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D, true, false, true); + } + | IMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd1D); + } + | F16IMAGE1D { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd1D); + } + | IIMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd1D); + } + | UIMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd1D); + } + | IMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd2D); + } + | F16IMAGE2D { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd2D); + } + | IIMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd2D); + } + | UIMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd2D); + } + | IMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd3D); + } + | F16IMAGE3D { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd3D); + } + | IIMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd3D); + } + | UIMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd3D); + } + | IMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, EsdRect); + } + | F16IMAGE2DRECT { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, EsdRect); + } + | IIMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, EsdRect); + } + | UIMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, EsdRect); + } + | IMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, EsdCube); + } + | F16IMAGECUBE { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, EsdCube); + } + | IIMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, EsdCube); + } + | UIMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, EsdCube); + } + | IMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, EsdBuffer); + } + | F16IMAGEBUFFER { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, EsdBuffer); + } + | IIMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, EsdBuffer); + } + | UIMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, EsdBuffer); + } + | IMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd1D, true); + } + | F16IMAGE1DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd1D, true); + } + | IIMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd1D, true); + } + | UIMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd1D, true); + } + | IMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd2D, true); + } + | F16IMAGE2DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd2D, true); + } + | IIMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd2D, true); + } + | UIMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd2D, true); + } + | IMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, EsdCube, true); + } + | F16IMAGECUBEARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, EsdCube, true); + } + | IIMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, EsdCube, true); + } + | UIMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, EsdCube, true); + } + | IMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd2D, false, false, true); + } + | F16IMAGE2DMS { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd2D, false, false, true); + } + | IIMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd2D, false, false, true); + } + | UIMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd2D, false, false, true); + } + | IMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd2D, true, false, true); + } + | F16IMAGE2DMSARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd2D, true, false, true); + } + | IIMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd2D, true, false, true); + } + | UIMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd2D, true, false, true); + } + | I64IMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd1D); + } + | U64IMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd1D); + } + | I64IMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd2D); + } + | U64IMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd2D); + } + | I64IMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd3D); + } + | U64IMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd3D); + } + | I64IMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, EsdRect); + } + | U64IMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, EsdRect); + } + | I64IMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, EsdCube); + } + | U64IMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, EsdCube); + } + | I64IMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, EsdBuffer); + } + | U64IMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, EsdBuffer); + } + | I64IMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd1D, true); + } + | U64IMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd1D, true); + } + | I64IMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd2D, true); + } + | U64IMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd2D, true); + } + | I64IMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, EsdCube, true); + } + | U64IMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, EsdCube, true); + } + | I64IMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd2D, false, false, true); + } + | U64IMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd2D, false, false, true); + } + | I64IMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd2D, true, false, true); + } + | U64IMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd2D, true, false, true); + } + | SAMPLEREXTERNALOES { // GL_OES_EGL_image_external + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D); + $$.sampler.external = true; + } + | SAMPLEREXTERNAL2DY2YEXT { // GL_EXT_YUV_target + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D); + $$.sampler.yuv = true; + } + | SUBPASSINPUT { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtFloat); + } + | SUBPASSINPUTMS { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtFloat, true); + } + | F16SUBPASSINPUT { + parseContext.float16OpaqueCheck($1.loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtFloat16); + } + | F16SUBPASSINPUTMS { + parseContext.float16OpaqueCheck($1.loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtFloat16, true); + } + | ISUBPASSINPUT { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtInt); + } + | ISUBPASSINPUTMS { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtInt, true); + } + | USUBPASSINPUT { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtUint); + } + | USUBPASSINPUTMS { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtUint, true); + } + | FCOOPMATNV { + parseContext.fcoopmatCheck($1.loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.coopmat = true; + } + | ICOOPMATNV { + parseContext.intcoopmatCheck($1.loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.coopmat = true; + } + | UCOOPMATNV { + parseContext.intcoopmatCheck($1.loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.coopmat = true; + } + | spirv_type_specifier { + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier"); + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_OFF + | struct_specifier { + $$ = $1; + $$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + parseContext.structTypeCheck($$.loc, $$); + } + | TYPE_NAME { + // + // This is for user defined type names. The lexical phase looked up the + // type. + // + if (const TVariable* variable = ($1.symbol)->getAsVariable()) { + const TType& structure = variable->getType(); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtStruct; + $$.userDef = &structure; + } else + parseContext.error($1.loc, "expected type name", $1.string->c_str(), ""); + } + ; + +precision_qualifier + : HIGH_PRECISION { + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "highp precision qualifier"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.handlePrecisionQualifier($1.loc, $$.qualifier, EpqHigh); + } + | MEDIUM_PRECISION { + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "mediump precision qualifier"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.handlePrecisionQualifier($1.loc, $$.qualifier, EpqMedium); + } + | LOW_PRECISION { + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "lowp precision qualifier"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.handlePrecisionQualifier($1.loc, $$.qualifier, EpqLow); + } + ; + +struct_specifier + : STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE { + TType* structure = new TType($5, *$2.string); + parseContext.structArrayCheck($2.loc, *structure); + TVariable* userTypeDef = new TVariable($2.string, *structure, true); + if (! parseContext.symbolTable.insert(*userTypeDef)) + parseContext.error($2.loc, "redefinition", $2.string->c_str(), "struct"); + $$.init($1.loc); + $$.basicType = EbtStruct; + $$.userDef = structure; + --parseContext.structNestingLevel; + } + | STRUCT LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE { + TType* structure = new TType($4, TString("")); + $$.init($1.loc); + $$.basicType = EbtStruct; + $$.userDef = structure; + --parseContext.structNestingLevel; + } + ; + +struct_declaration_list + : struct_declaration { + $$ = $1; + } + | struct_declaration_list struct_declaration { + $$ = $1; + for (unsigned int i = 0; i < $2->size(); ++i) { + for (unsigned int j = 0; j < $$->size(); ++j) { + if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) + parseContext.error((*$2)[i].loc, "duplicate member name:", "", (*$2)[i].type->getFieldName().c_str()); + } + $$->push_back((*$2)[i]); + } + } + ; + +struct_declaration + : type_specifier struct_declarator_list SEMICOLON { + if ($1.arraySizes) { + parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + if (parseContext.isEsProfile()) + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + } + + $$ = $2; + + parseContext.voidErrorCheck($1.loc, (*$2)[0].type->getFieldName(), $1.basicType); + parseContext.precisionQualifierCheck($1.loc, $1.basicType, $1.qualifier); + + for (unsigned int i = 0; i < $$->size(); ++i) { + TType type($1); + type.setFieldName((*$$)[i].type->getFieldName()); + type.transferArraySizes((*$$)[i].type->getArraySizes()); + type.copyArrayInnerSizes($1.arraySizes); + parseContext.arrayOfArrayVersionCheck((*$$)[i].loc, type.getArraySizes()); + (*$$)[i].type->shallowCopy(type); + } + } + | type_qualifier type_specifier struct_declarator_list SEMICOLON { + if ($2.arraySizes) { + parseContext.profileRequires($2.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); + if (parseContext.isEsProfile()) + parseContext.arraySizeRequiredCheck($2.loc, *$2.arraySizes); + } + + $$ = $3; + + parseContext.memberQualifierCheck($1); + parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2.basicType); + parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true); + parseContext.precisionQualifierCheck($2.loc, $2.basicType, $2.qualifier); + + for (unsigned int i = 0; i < $$->size(); ++i) { + TType type($2); + type.setFieldName((*$$)[i].type->getFieldName()); + type.transferArraySizes((*$$)[i].type->getArraySizes()); + type.copyArrayInnerSizes($2.arraySizes); + parseContext.arrayOfArrayVersionCheck((*$$)[i].loc, type.getArraySizes()); + (*$$)[i].type->shallowCopy(type); + } + } + ; + +struct_declarator_list + : struct_declarator { + $$ = new TTypeList; + $$->push_back($1); + } + | struct_declarator_list COMMA struct_declarator { + $$->push_back($3); + } + ; + +struct_declarator + : IDENTIFIER { + $$.type = new TType(EbtVoid); + $$.loc = $1.loc; + $$.type->setFieldName(*$1.string); + } + | IDENTIFIER array_specifier { + parseContext.arrayOfArrayVersionCheck($1.loc, $2.arraySizes); + + $$.type = new TType(EbtVoid); + $$.loc = $1.loc; + $$.type->setFieldName(*$1.string); + $$.type->transferArraySizes($2.arraySizes); + } + ; + +initializer + : assignment_expression { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | LEFT_BRACE initializer_list RIGHT_BRACE { + const char* initFeature = "{ } style initializers"; + parseContext.requireProfile($1.loc, ~EEsProfile, initFeature); + parseContext.profileRequires($1.loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); + $$ = $2; + } + | LEFT_BRACE initializer_list COMMA RIGHT_BRACE { + const char* initFeature = "{ } style initializers"; + parseContext.requireProfile($1.loc, ~EEsProfile, initFeature); + parseContext.profileRequires($1.loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); + $$ = $2; + } + | LEFT_BRACE RIGHT_BRACE { + const char* initFeature = "empty { } initializer"; + parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); + parseContext.profileRequires($1.loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); + $$ = parseContext.intermediate.makeAggregate($1.loc); + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +GLSLANG_WEB_EXCLUDE_ON +initializer_list + : initializer { + $$ = parseContext.intermediate.growAggregate(0, $1, $1->getLoc()); + } + | initializer_list COMMA initializer { + $$ = parseContext.intermediate.growAggregate($1, $3); + } + ; +GLSLANG_WEB_EXCLUDE_OFF + +declaration_statement + : declaration { $$ = $1; } + ; + +statement + : compound_statement { $$ = $1; } + | simple_statement { $$ = $1; } + ; + +// Grammar Note: labeled statements for switch statements only; 'goto' is not supported. + +simple_statement + : declaration_statement { $$ = $1; } + | expression_statement { $$ = $1; } + | selection_statement { $$ = $1; } + | switch_statement { $$ = $1; } + | case_label { $$ = $1; } + | iteration_statement { $$ = $1; } + | jump_statement { $$ = $1; } +GLSLANG_WEB_EXCLUDE_ON + | demote_statement { $$ = $1; } +GLSLANG_WEB_EXCLUDE_OFF + ; + +GLSLANG_WEB_EXCLUDE_ON +demote_statement + : DEMOTE SEMICOLON { + parseContext.requireStage($1.loc, EShLangFragment, "demote"); + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote"); + $$ = parseContext.intermediate.addBranch(EOpDemote, $1.loc); + } + ; +GLSLANG_WEB_EXCLUDE_OFF + +compound_statement + : LEFT_BRACE RIGHT_BRACE { $$ = 0; } + | LEFT_BRACE { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + } + statement_list { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + } + RIGHT_BRACE { + if ($3 && $3->getAsAggregate()) + $3->getAsAggregate()->setOperator(EOpSequence); + $$ = $3; + } + ; + +statement_no_new_scope + : compound_statement_no_new_scope { $$ = $1; } + | simple_statement { $$ = $1; } + ; + +statement_scoped + : { + ++parseContext.controlFlowNestingLevel; + } + compound_statement { + --parseContext.controlFlowNestingLevel; + $$ = $2; + } + | { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } + simple_statement { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + $$ = $2; + } + +compound_statement_no_new_scope + // Statement that doesn't create a new scope, for selection_statement, iteration_statement + : LEFT_BRACE RIGHT_BRACE { + $$ = 0; + } + | LEFT_BRACE statement_list RIGHT_BRACE { + if ($2 && $2->getAsAggregate()) + $2->getAsAggregate()->setOperator(EOpSequence); + $$ = $2; + } + ; + +statement_list + : statement { + $$ = parseContext.intermediate.makeAggregate($1); + if ($1 && $1->getAsBranchNode() && ($1->getAsBranchNode()->getFlowOp() == EOpCase || + $1->getAsBranchNode()->getFlowOp() == EOpDefault)) { + parseContext.wrapupSwitchSubsequence(0, $1); + $$ = 0; // start a fresh subsequence for what's after this case + } + } + | statement_list statement { + if ($2 && $2->getAsBranchNode() && ($2->getAsBranchNode()->getFlowOp() == EOpCase || + $2->getAsBranchNode()->getFlowOp() == EOpDefault)) { + parseContext.wrapupSwitchSubsequence($1 ? $1->getAsAggregate() : 0, $2); + $$ = 0; // start a fresh subsequence for what's after this case + } else + $$ = parseContext.intermediate.growAggregate($1, $2); + } + ; + +expression_statement + : SEMICOLON { $$ = 0; } + | expression SEMICOLON { $$ = static_cast($1); } + ; + +selection_statement + : selection_statement_nonattributed { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | attribute selection_statement_nonattributed { + parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); + parseContext.handleSelectionAttributes(*$1, $2); + $$ = $2; + } +GLSLANG_WEB_EXCLUDE_OFF + +selection_statement_nonattributed + : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { + parseContext.boolCheck($1.loc, $3); + $$ = parseContext.intermediate.addSelection($3, $5, $1.loc); + } + ; + +selection_rest_statement + : statement_scoped ELSE statement_scoped { + $$.node1 = $1; + $$.node2 = $3; + } + | statement_scoped { + $$.node1 = $1; + $$.node2 = 0; + } + ; + +condition + // In 1996 c++ draft, conditions can include single declarations + : expression { + $$ = $1; + parseContext.boolCheck($1->getLoc(), $1); + } + | fully_specified_type IDENTIFIER EQUAL initializer { + parseContext.boolCheck($2.loc, $1); + + TType type($1); + TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4); + if (initNode) + $$ = initNode->getAsTyped(); + else + $$ = 0; + } + ; + +switch_statement + : switch_statement_nonattributed { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | attribute switch_statement_nonattributed { + parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); + parseContext.handleSwitchAttributes(*$1, $2); + $$ = $2; + } +GLSLANG_WEB_EXCLUDE_OFF + +switch_statement_nonattributed + : SWITCH LEFT_PAREN expression RIGHT_PAREN { + // start new switch sequence on the switch stack + ++parseContext.controlFlowNestingLevel; + ++parseContext.statementNestingLevel; + parseContext.switchSequenceStack.push_back(new TIntermSequence); + parseContext.switchLevel.push_back(parseContext.statementNestingLevel); + parseContext.symbolTable.push(); + } + LEFT_BRACE switch_statement_list RIGHT_BRACE { + $$ = parseContext.addSwitch($1.loc, $3, $7 ? $7->getAsAggregate() : 0); + delete parseContext.switchSequenceStack.back(); + parseContext.switchSequenceStack.pop_back(); + parseContext.switchLevel.pop_back(); + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } + ; + +switch_statement_list + : /* nothing */ { + $$ = 0; + } + | statement_list { + $$ = $1; + } + ; + +case_label + : CASE expression COLON { + $$ = 0; + if (parseContext.switchLevel.size() == 0) + parseContext.error($1.loc, "cannot appear outside switch statement", "case", ""); + else if (parseContext.switchLevel.back() != parseContext.statementNestingLevel) + parseContext.error($1.loc, "cannot be nested inside control flow", "case", ""); + else { + parseContext.constantValueCheck($2, "case"); + parseContext.integerCheck($2, "case"); + $$ = parseContext.intermediate.addBranch(EOpCase, $2, $1.loc); + } + } + | DEFAULT COLON { + $$ = 0; + if (parseContext.switchLevel.size() == 0) + parseContext.error($1.loc, "cannot appear outside switch statement", "default", ""); + else if (parseContext.switchLevel.back() != parseContext.statementNestingLevel) + parseContext.error($1.loc, "cannot be nested inside control flow", "default", ""); + else + $$ = parseContext.intermediate.addBranch(EOpDefault, $1.loc); + } + ; + +iteration_statement + : iteration_statement_nonattributed { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | attribute iteration_statement_nonattributed { + parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); + parseContext.handleLoopAttributes(*$1, $2); + $$ = $2; + } +GLSLANG_WEB_EXCLUDE_OFF + +iteration_statement_nonattributed + : WHILE LEFT_PAREN { + if (! parseContext.limits.whileLoops) + parseContext.error($1.loc, "while loops not available", "limitation", ""); + parseContext.symbolTable.push(); + ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } + condition RIGHT_PAREN statement_no_new_scope { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + $$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.loc); + --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } + | DO { + ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } + statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { + if (! parseContext.limits.whileLoops) + parseContext.error($1.loc, "do-while loops not available", "limitation", ""); + + parseContext.boolCheck($8.loc, $6); + + $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc); + --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } + | FOR LEFT_PAREN { + parseContext.symbolTable.push(); + ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } + for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + $$ = parseContext.intermediate.makeAggregate($4, $2.loc); + TIntermLoop* forLoop = parseContext.intermediate.addLoop($7, reinterpret_cast($5.node1), reinterpret_cast($5.node2), true, $1.loc); + if (! parseContext.limits.nonInductiveForLoops) + parseContext.inductiveLoopCheck($1.loc, $4, forLoop); + $$ = parseContext.intermediate.growAggregate($$, forLoop, $1.loc); + $$->getAsAggregate()->setOperator(EOpSequence); + --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } + ; + +for_init_statement + : expression_statement { + $$ = $1; + } + | declaration_statement { + $$ = $1; + } + ; + +conditionopt + : condition { + $$ = $1; + } + | /* May be null */ { + $$ = 0; + } + ; + +for_rest_statement + : conditionopt SEMICOLON { + $$.node1 = $1; + $$.node2 = 0; + } + | conditionopt SEMICOLON expression { + $$.node1 = $1; + $$.node2 = $3; + } + ; + +jump_statement + : CONTINUE SEMICOLON { + if (parseContext.loopNestingLevel <= 0) + parseContext.error($1.loc, "continue statement only allowed in loops", "", ""); + $$ = parseContext.intermediate.addBranch(EOpContinue, $1.loc); + } + | BREAK SEMICOLON { + if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) + parseContext.error($1.loc, "break statement only allowed in switch and loops", "", ""); + $$ = parseContext.intermediate.addBranch(EOpBreak, $1.loc); + } + | RETURN SEMICOLON { + $$ = parseContext.intermediate.addBranch(EOpReturn, $1.loc); + if (parseContext.currentFunctionType->getBasicType() != EbtVoid) + parseContext.error($1.loc, "non-void function must return a value", "return", ""); + if (parseContext.inMain) + parseContext.postEntryPointReturn = true; + } + | RETURN expression SEMICOLON { + $$ = parseContext.handleReturnValue($1.loc, $2); + } + | DISCARD SEMICOLON { + parseContext.requireStage($1.loc, EShLangFragment, "discard"); + $$ = parseContext.intermediate.addBranch(EOpKill, $1.loc); + } + | TERMINATE_INVOCATION SEMICOLON { + parseContext.requireStage($1.loc, EShLangFragment, "terminateInvocation"); + $$ = parseContext.intermediate.addBranch(EOpTerminateInvocation, $1.loc); + } +GLSLANG_WEB_EXCLUDE_ON + | TERMINATE_RAY SEMICOLON { + parseContext.requireStage($1.loc, EShLangAnyHit, "terminateRayEXT"); + $$ = parseContext.intermediate.addBranch(EOpTerminateRayKHR, $1.loc); + } + | IGNORE_INTERSECTION SEMICOLON { + parseContext.requireStage($1.loc, EShLangAnyHit, "ignoreIntersectionEXT"); + $$ = parseContext.intermediate.addBranch(EOpIgnoreIntersectionKHR, $1.loc); + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +// Grammar Note: No 'goto'. Gotos are not supported. + +translation_unit + : external_declaration { + $$ = $1; + parseContext.intermediate.setTreeRoot($$); + } + | translation_unit external_declaration { + if ($2 != nullptr) { + $$ = parseContext.intermediate.growAggregate($1, $2); + parseContext.intermediate.setTreeRoot($$); + } + } + ; + +external_declaration + : function_definition { + $$ = $1; + } + | declaration { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | SEMICOLON { + parseContext.requireProfile($1.loc, ~EEsProfile, "extraneous semicolon"); + parseContext.profileRequires($1.loc, ~EEsProfile, 460, nullptr, "extraneous semicolon"); + $$ = nullptr; + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +function_definition + : function_prototype { + $1.function = parseContext.handleFunctionDeclarator($1.loc, *$1.function, false /* not prototype */); + $1.intermNode = parseContext.handleFunctionDefinition($1.loc, *$1.function); + + // For ES 100 only, according to ES shading language 100 spec: A function + // body has a scope nested inside the function's definition. + if (parseContext.profile == EEsProfile && parseContext.version == 100) + { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + } + } + compound_statement_no_new_scope { + // May be best done as post process phase on intermediate code + if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) + parseContext.error($1.loc, "function does not return a value:", "", $1.function->getName().c_str()); + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + $$ = parseContext.intermediate.growAggregate($1.intermNode, $3); + parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.function->getType(), $1.loc); + $$->getAsAggregate()->setName($1.function->getMangledName().c_str()); + + // store the pragma information for debug and optimize and other vendor specific + // information. This information can be queried from the parse tree + $$->getAsAggregate()->setOptimize(parseContext.contextPragma.optimize); + $$->getAsAggregate()->setDebug(parseContext.contextPragma.debug); + $$->getAsAggregate()->setPragmaTable(parseContext.contextPragma.pragmaTable); + + // Set currentFunctionType to empty pointer when goes outside of the function + parseContext.currentFunctionType = nullptr; + + // For ES 100 only, according to ES shading language 100 spec: A function + // body has a scope nested inside the function's definition. + if (parseContext.profile == EEsProfile && parseContext.version == 100) + { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + } + } + ; + +GLSLANG_WEB_EXCLUDE_ON +attribute + : LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET { + $$ = $3; + } + +attribute_list + : single_attribute { + $$ = $1; + } + | attribute_list COMMA single_attribute { + $$ = parseContext.mergeAttributes($1, $3); + } + +single_attribute + : IDENTIFIER { + $$ = parseContext.makeAttributes(*$1.string); + } + | IDENTIFIER LEFT_PAREN constant_expression RIGHT_PAREN { + $$ = parseContext.makeAttributes(*$1.string, $3); + } +GLSLANG_WEB_EXCLUDE_OFF + +GLSLANG_WEB_EXCLUDE_ON +spirv_requirements_list + : spirv_requirements_parameter { + $$ = $1; + } + | spirv_requirements_list COMMA spirv_requirements_parameter { + $$ = parseContext.mergeSpirvRequirements($2.loc, $1, $3); + } + +spirv_requirements_parameter + : IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET { + $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, $4->getAsAggregate(), nullptr); + } + | IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET { + $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, nullptr, $4->getAsAggregate()); + } + +spirv_extension_list + : STRING_LITERAL { + $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.string, $1.loc, true)); + } + | spirv_extension_list COMMA STRING_LITERAL { + $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true)); + } + +spirv_capability_list + : INTCONSTANT { + $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.i, $1.loc, true)); + } + | spirv_capability_list COMMA INTCONSTANT { + $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.i, $3.loc, true)); + } + +spirv_execution_mode_qualifier + : SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN { + parseContext.intermediate.insertSpirvExecutionMode($3.i); + $$ = 0; + } + | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN { + parseContext.intermediate.insertSpirvRequirement($3); + parseContext.intermediate.insertSpirvExecutionMode($5.i); + $$ = 0; + } + | SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvExecutionMode($3.i, $5->getAsAggregate()); + $$ = 0; + } + | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvRequirement($3); + parseContext.intermediate.insertSpirvExecutionMode($5.i, $7->getAsAggregate()); + $$ = 0; + } + | SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvExecutionModeId($3.i, $5->getAsAggregate()); + $$ = 0; + } + | SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvRequirement($3); + parseContext.intermediate.insertSpirvExecutionModeId($5.i, $7->getAsAggregate()); + $$ = 0; + } + +spirv_execution_mode_parameter_list + : spirv_execution_mode_parameter { + $$ = parseContext.intermediate.makeAggregate($1); + } + | spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter { + $$ = parseContext.intermediate.growAggregate($1, $3); + } + +spirv_execution_mode_parameter + : FLOATCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); + } + | INTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } + | BOOLCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); + } + | STRING_LITERAL { + $$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true); + } + +spirv_execution_mode_id_parameter_list + : constant_expression { + if ($1->getBasicType() != EbtFloat && + $1->getBasicType() != EbtInt && + $1->getBasicType() != EbtUint && + $1->getBasicType() != EbtBool && + $1->getBasicType() != EbtString) + parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), ""); + $$ = parseContext.intermediate.makeAggregate($1); + } + | spirv_execution_mode_id_parameter_list COMMA constant_expression { + if ($3->getBasicType() != EbtFloat && + $3->getBasicType() != EbtInt && + $3->getBasicType() != EbtUint && + $3->getBasicType() != EbtBool && + $3->getBasicType() != EbtString) + parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), ""); + $$ = parseContext.intermediate.growAggregate($1, $3); + } + +spirv_storage_class_qualifier + : SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN { + $$.init($1.loc); + $$.qualifier.storage = EvqSpirvStorageClass; + $$.qualifier.spirvStorageClass = $3.i; + } + | SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN { + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.storage = EvqSpirvStorageClass; + $$.qualifier.spirvStorageClass = $5.i; + } + +spirv_decorate_qualifier + : SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN{ + $$.init($1.loc); + $$.qualifier.setSpirvDecorate($3.i); + } + | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN{ + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.setSpirvDecorate($5.i); + } + | SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN { + $$.init($1.loc); + $$.qualifier.setSpirvDecorate($3.i, $5->getAsAggregate()); + } + | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN { + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.setSpirvDecorate($5.i, $7->getAsAggregate()); + } + | SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN { + $$.init($1.loc); + $$.qualifier.setSpirvDecorateId($3.i, $5->getAsAggregate()); + } + | SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN { + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.setSpirvDecorateId($5.i, $7->getAsAggregate()); + } + | SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN { + $$.init($1.loc); + $$.qualifier.setSpirvDecorateString($3.i, $5->getAsAggregate()); + } + | SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN { + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.setSpirvDecorateString($5.i, $7->getAsAggregate()); + } + +spirv_decorate_parameter_list + : spirv_decorate_parameter { + $$ = parseContext.intermediate.makeAggregate($1); + } + | spirv_decorate_parameter_list COMMA spirv_decorate_parameter { + $$ = parseContext.intermediate.growAggregate($1, $3); + } + +spirv_decorate_parameter + : FLOATCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); + } + | INTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } + | BOOLCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); + } + +spirv_decorate_id_parameter_list + : constant_expression { + if ($1->getBasicType() != EbtFloat && + $1->getBasicType() != EbtInt && + $1->getBasicType() != EbtUint && + $1->getBasicType() != EbtBool) + parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), ""); + $$ = parseContext.intermediate.makeAggregate($1); + } + | spirv_decorate_id_parameter_list COMMA constant_expression { + if ($3->getBasicType() != EbtFloat && + $3->getBasicType() != EbtInt && + $3->getBasicType() != EbtUint && + $3->getBasicType() != EbtBool) + parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), ""); + $$ = parseContext.intermediate.growAggregate($1, $3); + } + +spirv_decorate_string_parameter_list + : STRING_LITERAL { + $$ = parseContext.intermediate.makeAggregate( + parseContext.intermediate.addConstantUnion($1.string, $1.loc, true)); + } + | spirv_decorate_string_parameter_list COMMA STRING_LITERAL { + $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true)); + } + +spirv_type_specifier + : SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.setSpirvType(*$3, $5); + } + | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.intermediate.insertSpirvRequirement($3); + $$.setSpirvType(*$5, $7); + } + | SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.setSpirvType(*$3); + } + | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.intermediate.insertSpirvRequirement($3); + $$.setSpirvType(*$5); + } + +spirv_type_parameter_list + : spirv_type_parameter { + $$ = $1; + } + | spirv_type_parameter_list COMMA spirv_type_parameter { + $$ = parseContext.mergeSpirvTypeParameters($1, $3); + } + +spirv_type_parameter + : constant_expression { + $$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion()); + } + | type_specifier { + $$ = parseContext.makeSpirvTypeParameters($1); + } + +spirv_instruction_qualifier + : SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN { + $$ = $3; + } + | SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvRequirement($3); + $$ = $5; + } + +spirv_instruction_qualifier_list + : spirv_instruction_qualifier_id { + $$ = $1; + } + | spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id { + $$ = parseContext.mergeSpirvInstruction($2.loc, $1, $3); + } + +spirv_instruction_qualifier_id + : IDENTIFIER EQUAL STRING_LITERAL { + $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, *$3.string); + } + | IDENTIFIER EQUAL INTCONSTANT { + $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i); + } +GLSLANG_WEB_EXCLUDE_OFF + +%% diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang.y b/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang.y index d6e5091..b77f461 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang.y +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang.y @@ -2,7 +2,8 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2019 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -36,6 +37,31 @@ // POSSIBILITY OF SUCH DAMAGE. // +// +// Do not edit the .y file, only edit the .m4 file. +// The .y bison file is not a source file, it is a derivative of the .m4 file. +// The m4 file needs to be processed by m4 to generate the .y bison file. +// +// Code sandwiched between a pair: +// +// GLSLANG_WEB_EXCLUDE_ON +// ... +// ... +// ... +// GLSLANG_WEB_EXCLUDE_OFF +// +// Will be excluded from the grammar when m4 is executed as: +// +// m4 -P -DGLSLANG_WEB +// +// It will be included when m4 is executed as: +// +// m4 -P +// + + + + /** * This is bison grammar and productions for parsing all versions of the * GLSL shading languages. @@ -90,6 +116,9 @@ using namespace glslang; glslang::TIntermNodePair nodePair; glslang::TIntermTyped* intermTypedNode; glslang::TAttributes* attributes; + glslang::TSpirvRequirement* spirvReq; + glslang::TSpirvInstruction* spirvInst; + glslang::TSpirvTypeParameters* spirvTypeParams; }; union { glslang::TPublicType type; @@ -100,6 +129,7 @@ using namespace glslang; glslang::TArraySizes* arraySizes; glslang::TIdentifierList* identifierList; }; + glslang::TArraySizes* typeParameters; } interm; } @@ -124,13 +154,34 @@ extern int yylex(YYSTYPE*, TParseContext&); %pure-parser // enable thread safety %expect 1 // One shift reduce conflict because of if | else -%token ATTRIBUTE VARYING -%token FLOAT16_T FLOAT FLOAT32_T DOUBLE FLOAT64_T -%token CONST BOOL INT UINT INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T -%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT SUBROUTINE +%token CONST BOOL INT UINT FLOAT %token BVEC2 BVEC3 BVEC4 %token IVEC2 IVEC3 IVEC4 %token UVEC2 UVEC3 UVEC4 +%token VEC2 VEC3 VEC4 +%token MAT2 MAT3 MAT4 +%token MAT2X2 MAT2X3 MAT2X4 +%token MAT3X2 MAT3X3 MAT3X4 +%token MAT4X2 MAT4X3 MAT4X4 + +// combined image/sampler +%token SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER2DSHADOW +%token SAMPLERCUBESHADOW SAMPLER2DARRAY +%token SAMPLER2DARRAYSHADOW ISAMPLER2D ISAMPLER3D ISAMPLERCUBE +%token ISAMPLER2DARRAY USAMPLER2D USAMPLER3D +%token USAMPLERCUBE USAMPLER2DARRAY + +// separate image/sampler +%token SAMPLER SAMPLERSHADOW +%token TEXTURE2D TEXTURE3D TEXTURECUBE TEXTURE2DARRAY +%token ITEXTURE2D ITEXTURE3D ITEXTURECUBE ITEXTURE2DARRAY +%token UTEXTURE2D UTEXTURE3D UTEXTURECUBE UTEXTURE2DARRAY + + + +%token ATTRIBUTE VARYING +%token FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T +%token INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T %token I64VEC2 I64VEC3 I64VEC4 %token U64VEC2 U64VEC3 U64VEC4 %token I32VEC2 I32VEC3 I32VEC4 @@ -139,19 +190,10 @@ extern int yylex(YYSTYPE*, TParseContext&); %token U16VEC2 U16VEC3 U16VEC4 %token I8VEC2 I8VEC3 I8VEC4 %token U8VEC2 U8VEC3 U8VEC4 -%token VEC2 VEC3 VEC4 -%token MAT2 MAT3 MAT4 CENTROID IN OUT INOUT -%token UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM PAYLOADNV PAYLOADINNV HITATTRNV CALLDATANV CALLDATAINNV -%token COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT SUBGROUPCOHERENT NONPRIVATE %token DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4 %token F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4 %token F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4 %token F64VEC2 F64VEC3 F64VEC4 F64MAT2 F64MAT3 F64MAT4 -%token NOPERSPECTIVE FLAT SMOOTH LAYOUT EXPLICITINTERPAMD PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV - -%token MAT2X2 MAT2X3 MAT2X4 -%token MAT3X2 MAT3X3 MAT3X4 -%token MAT4X2 MAT4X3 MAT4X4 %token DMAT2X2 DMAT2X3 DMAT2X4 %token DMAT3X2 DMAT3X3 DMAT3X4 %token DMAT4X2 DMAT4X3 DMAT4X4 @@ -166,51 +208,28 @@ extern int yylex(YYSTYPE*, TParseContext&); %token F64MAT4X2 F64MAT4X3 F64MAT4X4 %token ATOMIC_UINT %token ACCSTRUCTNV +%token ACCSTRUCTEXT +%token RAYQUERYEXT +%token FCOOPMATNV ICOOPMATNV UCOOPMATNV // combined image/sampler -%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW -%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW -%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE -%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D -%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY -%token SAMPLER2DRECT SAMPLER2DRECTSHADOW ISAMPLER2DRECT USAMPLER2DRECT -%token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER %token SAMPLERCUBEARRAY SAMPLERCUBEARRAYSHADOW %token ISAMPLERCUBEARRAY USAMPLERCUBEARRAY +%token SAMPLER1D SAMPLER1DARRAY SAMPLER1DARRAYSHADOW ISAMPLER1D SAMPLER1DSHADOW +%token SAMPLER2DRECT SAMPLER2DRECTSHADOW ISAMPLER2DRECT USAMPLER2DRECT +%token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER %token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS %token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY %token SAMPLEREXTERNALOES %token SAMPLEREXTERNAL2DY2YEXT - +%token ISAMPLER1DARRAY USAMPLER1D USAMPLER1DARRAY %token F16SAMPLER1D F16SAMPLER2D F16SAMPLER3D F16SAMPLER2DRECT F16SAMPLERCUBE %token F16SAMPLER1DARRAY F16SAMPLER2DARRAY F16SAMPLERCUBEARRAY %token F16SAMPLERBUFFER F16SAMPLER2DMS F16SAMPLER2DMSARRAY %token F16SAMPLER1DSHADOW F16SAMPLER2DSHADOW F16SAMPLER1DARRAYSHADOW F16SAMPLER2DARRAYSHADOW %token F16SAMPLER2DRECTSHADOW F16SAMPLERCUBESHADOW F16SAMPLERCUBEARRAYSHADOW -// pure sampler -%token SAMPLER SAMPLERSHADOW - -// texture without sampler -%token TEXTURE1D TEXTURE2D TEXTURE3D TEXTURECUBE -%token TEXTURE1DARRAY TEXTURE2DARRAY -%token ITEXTURE1D ITEXTURE2D ITEXTURE3D ITEXTURECUBE -%token ITEXTURE1DARRAY ITEXTURE2DARRAY UTEXTURE1D UTEXTURE2D UTEXTURE3D -%token UTEXTURECUBE UTEXTURE1DARRAY UTEXTURE2DARRAY -%token TEXTURE2DRECT ITEXTURE2DRECT UTEXTURE2DRECT -%token TEXTUREBUFFER ITEXTUREBUFFER UTEXTUREBUFFER -%token TEXTURECUBEARRAY ITEXTURECUBEARRAY UTEXTURECUBEARRAY -%token TEXTURE2DMS ITEXTURE2DMS UTEXTURE2DMS -%token TEXTURE2DMSARRAY ITEXTURE2DMSARRAY UTEXTURE2DMSARRAY - -%token F16TEXTURE1D F16TEXTURE2D F16TEXTURE3D F16TEXTURE2DRECT F16TEXTURECUBE -%token F16TEXTURE1DARRAY F16TEXTURE2DARRAY F16TEXTURECUBEARRAY -%token F16TEXTUREBUFFER F16TEXTURE2DMS F16TEXTURE2DMSARRAY - -// input attachments -%token SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS -%token F16SUBPASSINPUT F16SUBPASSINPUTMS - +// images %token IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D %token UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D %token IMAGE2DRECT IIMAGE2DRECT UIMAGE2DRECT @@ -226,25 +245,80 @@ extern int yylex(YYSTYPE*, TParseContext&); %token F16IMAGECUBE F16IMAGE1DARRAY F16IMAGE2DARRAY F16IMAGECUBEARRAY %token F16IMAGEBUFFER F16IMAGE2DMS F16IMAGE2DMSARRAY -%token STRUCT VOID WHILE +%token I64IMAGE1D U64IMAGE1D +%token I64IMAGE2D U64IMAGE2D +%token I64IMAGE3D U64IMAGE3D +%token I64IMAGE2DRECT U64IMAGE2DRECT +%token I64IMAGECUBE U64IMAGECUBE +%token I64IMAGEBUFFER U64IMAGEBUFFER +%token I64IMAGE1DARRAY U64IMAGE1DARRAY +%token I64IMAGE2DARRAY U64IMAGE2DARRAY +%token I64IMAGECUBEARRAY U64IMAGECUBEARRAY +%token I64IMAGE2DMS U64IMAGE2DMS +%token I64IMAGE2DMSARRAY U64IMAGE2DMSARRAY + +// texture without sampler +%token TEXTURECUBEARRAY ITEXTURECUBEARRAY UTEXTURECUBEARRAY +%token TEXTURE1D ITEXTURE1D UTEXTURE1D +%token TEXTURE1DARRAY ITEXTURE1DARRAY UTEXTURE1DARRAY +%token TEXTURE2DRECT ITEXTURE2DRECT UTEXTURE2DRECT +%token TEXTUREBUFFER ITEXTUREBUFFER UTEXTUREBUFFER +%token TEXTURE2DMS ITEXTURE2DMS UTEXTURE2DMS +%token TEXTURE2DMSARRAY ITEXTURE2DMSARRAY UTEXTURE2DMSARRAY + +%token F16TEXTURE1D F16TEXTURE2D F16TEXTURE3D F16TEXTURE2DRECT F16TEXTURECUBE +%token F16TEXTURE1DARRAY F16TEXTURE2DARRAY F16TEXTURECUBEARRAY +%token F16TEXTUREBUFFER F16TEXTURE2DMS F16TEXTURE2DMSARRAY + +// input attachments +%token SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS +%token F16SUBPASSINPUT F16SUBPASSINPUTMS + +// spirv intrinsics +%token SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID +%token SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING +%token SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL + + -%token IDENTIFIER TYPE_NAME -%token FLOATCONSTANT DOUBLECONSTANT INT16CONSTANT UINT16CONSTANT INT32CONSTANT UINT32CONSTANT INTCONSTANT UINTCONSTANT INT64CONSTANT UINT64CONSTANT BOOLCONSTANT FLOAT16CONSTANT %token LEFT_OP RIGHT_OP %token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP %token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN %token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN %token SUB_ASSIGN +%token STRING_LITERAL %token LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT %token COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT %token LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION -%token INVARIANT PRECISE +%token INVARIANT %token HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION - %token PACKED RESOURCE SUPERP +%token FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token IDENTIFIER TYPE_NAME +%token CENTROID IN OUT INOUT +%token STRUCT VOID WHILE +%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token TERMINATE_INVOCATION +%token TERMINATE_RAY IGNORE_INTERSECTION +%token UNIFORM SHARED BUFFER +%token FLAT SMOOTH LAYOUT + + +%token DOUBLECONSTANT INT16CONSTANT UINT16CONSTANT FLOAT16CONSTANT INT32CONSTANT UINT32CONSTANT +%token INT64CONSTANT UINT64CONSTANT +%token SUBROUTINE DEMOTE +%token PAYLOADNV PAYLOADINNV HITATTRNV CALLDATANV CALLDATAINNV +%token PAYLOADEXT PAYLOADINEXT HITATTREXT CALLDATAEXT CALLDATAINEXT +%token PATCH SAMPLE NONUNIFORM +%token COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT +%token SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT +%token NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV +%token PRECISE + + %type assignment_operator unary_operator %type variable_identifier primary_expression postfix_expression %type expression integer_expression assignment_expression @@ -253,7 +327,7 @@ extern int yylex(YYSTYPE*, TParseContext&); %type conditional_expression constant_expression %type logical_or_expression logical_xor_expression logical_and_expression %type shift_expression and_expression exclusive_or_expression inclusive_or_expression -%type function_call initializer initializer_list condition conditionopt +%type function_call initializer condition conditionopt %type translation_unit function_definition %type statement simple_statement @@ -269,16 +343,19 @@ extern int yylex(YYSTYPE*, TParseContext&); %type parameter_declaration parameter_declarator parameter_type_specifier %type array_specifier -%type precise_qualifier invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier +%type invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier %type layout_qualifier layout_qualifier_id_list layout_qualifier_id -%type non_uniform_qualifier + +%type type_parameter_specifier +%type type_parameter_specifier_opt +%type type_parameter_specifier_list %type type_qualifier fully_specified_type type_specifier %type single_type_qualifier %type type_specifier_nonarray %type struct_specifier %type struct_declarator -%type struct_declarator_list struct_declaration struct_declaration_list type_name_list +%type struct_declarator_list struct_declaration struct_declaration_list %type block_structure %type function_header function_declarator %type function_header_with_parameters @@ -287,7 +364,26 @@ extern int yylex(YYSTYPE*, TParseContext&); %type identifier_list + +%type precise_qualifier non_uniform_qualifier +%type type_name_list %type attribute attribute_list single_attribute +%type demote_statement +%type initializer_list +%type spirv_requirements_list spirv_requirements_parameter +%type spirv_extension_list spirv_capability_list +%type spirv_execution_mode_qualifier +%type spirv_execution_mode_parameter_list spirv_execution_mode_parameter spirv_execution_mode_id_parameter_list +%type spirv_storage_class_qualifier +%type spirv_decorate_qualifier +%type spirv_decorate_parameter_list spirv_decorate_parameter +%type spirv_decorate_id_parameter_list +%type spirv_decorate_string_parameter_list +%type spirv_type_specifier +%type spirv_type_parameter_list spirv_type_parameter +%type spirv_instruction_qualifier +%type spirv_instruction_qualifier_list spirv_instruction_qualifier_id + %start translation_unit %% @@ -302,13 +398,13 @@ primary_expression : variable_identifier { $$ = $1; } - | INT32CONSTANT { - parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); - $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + | LEFT_PAREN expression RIGHT_PAREN { + $$ = $2; + if ($$->getAsConstantUnion()) + $$->getAsConstantUnion()->setExpression(); } - | UINT32CONSTANT { - parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); - $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + | FLOATCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); } | INTCONSTANT { $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); @@ -317,6 +413,21 @@ primary_expression parseContext.fullIntegerCheck($1.loc, "unsigned literal"); $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); } + | BOOLCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); + } + + | STRING_LITERAL { + $$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true); + } + | INT32CONSTANT { + parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINT32CONSTANT { + parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } | INT64CONSTANT { parseContext.int64Check($1.loc, "64-bit integer literal"); $$ = parseContext.intermediate.addConstantUnion($1.i64, $1.loc, true); @@ -333,25 +444,17 @@ primary_expression parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer literal"); $$ = parseContext.intermediate.addConstantUnion((unsigned short)$1.u, $1.loc, true); } - | FLOATCONSTANT { - $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); - } | DOUBLECONSTANT { - parseContext.doubleCheck($1.loc, "double literal"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double literal"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double literal"); $$ = parseContext.intermediate.addConstantUnion($1.d, EbtDouble, $1.loc, true); } | FLOAT16CONSTANT { parseContext.float16Check($1.loc, "half float literal"); $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat16, $1.loc, true); } - | BOOLCONSTANT { - $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); - } - | LEFT_PAREN expression RIGHT_PAREN { - $$ = $2; - if ($$->getAsConstantUnion()) - $$->getAsConstantUnion()->setExpression(); - } + ; postfix_expression @@ -473,15 +576,17 @@ function_identifier if ($$.function == 0) { // error recover - TString empty(""); - $$.function = new TFunction(&empty, TType(EbtVoid), EOpNull); + TString* empty = NewPoolTString(""); + $$.function = new TFunction(empty, TType(EbtVoid), EOpNull); } } + | non_uniform_qualifier { // Constructor $$.intermNode = 0; $$.function = parseContext.handleConstructorCall($1.loc, $1); } + ; unary_expression @@ -607,6 +712,7 @@ equality_expression parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison"); parseContext.opaqueCheck($2.loc, $1->getType(), "=="); parseContext.specializationCheck($2.loc, $1->getType(), "=="); + parseContext.referenceCheck($2.loc, $1->getType(), "=="); $$ = parseContext.handleBinaryMath($2.loc, "==", EOpEqual, $1, $3); if ($$ == 0) $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); @@ -615,6 +721,7 @@ equality_expression parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison"); parseContext.opaqueCheck($2.loc, $1->getType(), "!="); parseContext.specializationCheck($2.loc, $1->getType(), "!="); + parseContext.referenceCheck($2.loc, $1->getType(), "!="); $$ = parseContext.handleBinaryMath($2.loc, "!=", EOpNotEqual, $1, $3); if ($$ == 0) $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); @@ -706,7 +813,7 @@ assignment_expression parseContext.specializationCheck($2.loc, $1->getType(), "="); parseContext.lValueErrorCheck($2.loc, "assign", $1); parseContext.rValueErrorCheck($2.loc, "assign", $3); - $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.loc); + $$ = parseContext.addAssign($2.loc, $2.op, $1, $3); if ($$ == 0) { parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; @@ -789,6 +896,20 @@ declaration $$ = 0; // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature } + + | spirv_instruction_qualifier function_prototype SEMICOLON { + parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier"); + $2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier + parseContext.handleFunctionDeclarator($2.loc, *$2.function, true /* prototype */); + $$ = 0; + // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature + } + | spirv_execution_mode_qualifier SEMICOLON { + parseContext.globalCheck($2.loc, "SPIR-V execution mode qualifier"); + parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier"); + $$ = 0; + } + | init_declarator_list SEMICOLON { if ($1.intermNode && $1.intermNode->getAsAggregate()) $1.intermNode->getAsAggregate()->setOperator(EOpSequence); @@ -796,7 +917,6 @@ declaration } | PRECISION precision_qualifier type_specifier SEMICOLON { parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "precision statement"); - // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]); parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision); @@ -834,7 +954,7 @@ declaration block_structure : type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.loc); } struct_declaration_list RIGHT_BRACE { - --parseContext.structNestingLevel; + --parseContext.blockNestingLevel; parseContext.blockName = $2.string; parseContext.globalQualifierFixCheck($1.loc, $1.qualifier); parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); @@ -859,6 +979,25 @@ function_prototype $$.function = $1; $$.loc = $2.loc; } + | function_declarator RIGHT_PAREN attribute { + $$.function = $1; + $$.loc = $2.loc; + parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); + parseContext.handleFunctionAttributes($2.loc, *$3, $$.function); + } + | attribute function_declarator RIGHT_PAREN { + $$.function = $2; + $$.loc = $3.loc; + parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); + parseContext.handleFunctionAttributes($3.loc, *$1, $$.function); + } + | attribute function_declarator RIGHT_PAREN attribute { + $$.function = $2; + $$.loc = $3.loc; + parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); + parseContext.handleFunctionAttributes($3.loc, *$1, $$.function); + parseContext.handleFunctionAttributes($3.loc, *$4, $$.function); + } ; function_declarator @@ -1040,7 +1179,9 @@ single_declaration : fully_specified_type { $$.type = $1; $$.intermNode = 0; + parseContext.declareTypeDefaults($$.loc, $$.type); + } | fully_specified_type IDENTIFIER { $$.type = $1; @@ -1074,7 +1215,6 @@ fully_specified_type parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); } - parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier); } | type_qualifier type_specifier { @@ -1127,38 +1267,30 @@ interpolation_qualifier $$.init($1.loc); $$.qualifier.flat = true; } + | NOPERSPECTIVE { parseContext.globalCheck($1.loc, "noperspective"); -#ifdef NV_EXTENSIONS parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective"); -#else - parseContext.requireProfile($1.loc, ~EEsProfile, "noperspective"); -#endif parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "noperspective"); $$.init($1.loc); $$.qualifier.nopersp = true; } | EXPLICITINTERPAMD { -#ifdef AMD_EXTENSIONS parseContext.globalCheck($1.loc, "__explicitInterpAMD"); parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); parseContext.profileRequires($1.loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); $$.init($1.loc); $$.qualifier.explicitInterp = true; -#endif } | PERVERTEXNV { -#ifdef NV_EXTENSIONS parseContext.globalCheck($1.loc, "pervertexNV"); parseContext.profileRequires($1.loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); parseContext.profileRequires($1.loc, ECompatibilityProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); $$.init($1.loc); $$.qualifier.pervertexNV = true; -#endif } | PERPRIMITIVENV { -#ifdef NV_EXTENSIONS // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck($1.loc, "perprimitiveNV"); parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV"); @@ -1167,26 +1299,22 @@ interpolation_qualifier parseContext.requireExtensions($1.loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV"); $$.init($1.loc); $$.qualifier.perPrimitiveNV = true; -#endif } | PERVIEWNV { -#ifdef NV_EXTENSIONS // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck($1.loc, "perviewNV"); parseContext.requireStage($1.loc, EShLangMeshNV, "perviewNV"); $$.init($1.loc); $$.qualifier.perViewNV = true; -#endif } | PERTASKNV { -#ifdef NV_EXTENSIONS // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck($1.loc, "taskNV"); parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV"); $$.init($1.loc); $$.qualifier.perTaskNV = true; -#endif } + ; layout_qualifier @@ -1221,6 +1349,7 @@ layout_qualifier_id } ; + precise_qualifier : PRECISE { parseContext.profileRequires($$.loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); @@ -1230,6 +1359,7 @@ precise_qualifier } ; + type_qualifier : single_type_qualifier { $$ = $1; @@ -1263,6 +1393,7 @@ single_type_qualifier // allow inheritance of storage qualifier from block declaration $$ = $1; } + | precise_qualifier { // allow inheritance of storage qualifier from block declaration $$ = $1; @@ -1270,6 +1401,26 @@ single_type_qualifier | non_uniform_qualifier { $$ = $1; } + | spirv_storage_class_qualifier { + parseContext.globalCheck($1.loc, "spirv_storage_class"); + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier"); + $$ = $1; + } + | spirv_decorate_qualifier { + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier"); + $$ = $1; + } + | SPIRV_BY_REFERENCE { + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference"); + $$.init($1.loc); + $$.qualifier.setSpirvByReference(); + } + | SPIRV_LITERAL { + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal"); + $$.init($1.loc); + $$.qualifier.setSpirvLiteral(); + } + ; storage_qualifier @@ -1277,6 +1428,49 @@ storage_qualifier $$.init($1.loc); $$.qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant } + | INOUT { + parseContext.globalCheck($1.loc, "inout"); + $$.init($1.loc); + $$.qualifier.storage = EvqInOut; + } + | IN { + parseContext.globalCheck($1.loc, "in"); + $$.init($1.loc); + // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later + $$.qualifier.storage = EvqIn; + } + | OUT { + parseContext.globalCheck($1.loc, "out"); + $$.init($1.loc); + // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later + $$.qualifier.storage = EvqOut; + } + | CENTROID { + parseContext.profileRequires($1.loc, ENoProfile, 120, 0, "centroid"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "centroid"); + parseContext.globalCheck($1.loc, "centroid"); + $$.init($1.loc); + $$.qualifier.centroid = true; + } + | UNIFORM { + parseContext.globalCheck($1.loc, "uniform"); + $$.init($1.loc); + $$.qualifier.storage = EvqUniform; + } + | SHARED { + parseContext.globalCheck($1.loc, "shared"); + parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); + parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); + $$.init($1.loc); + $$.qualifier.storage = EvqShared; + } + | BUFFER { + parseContext.globalCheck($1.loc, "buffer"); + $$.init($1.loc); + $$.qualifier.storage = EvqBuffer; + } + | ATTRIBUTE { parseContext.requireStage($1.loc, EShLangVertex, "attribute"); parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute"); @@ -1303,30 +1497,6 @@ storage_qualifier else $$.qualifier.storage = EvqVaryingIn; } - | INOUT { - parseContext.globalCheck($1.loc, "inout"); - $$.init($1.loc); - $$.qualifier.storage = EvqInOut; - } - | IN { - parseContext.globalCheck($1.loc, "in"); - $$.init($1.loc); - // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later - $$.qualifier.storage = EvqIn; - } - | OUT { - parseContext.globalCheck($1.loc, "out"); - $$.init($1.loc); - // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later - $$.qualifier.storage = EvqOut; - } - | CENTROID { - parseContext.profileRequires($1.loc, ENoProfile, 120, 0, "centroid"); - parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "centroid"); - parseContext.globalCheck($1.loc, "centroid"); - $$.init($1.loc); - $$.qualifier.centroid = true; - } | PATCH { parseContext.globalCheck($1.loc, "patch"); parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); @@ -1338,76 +1508,83 @@ storage_qualifier $$.init($1.loc); $$.qualifier.sample = true; } - | UNIFORM { - parseContext.globalCheck($1.loc, "uniform"); - $$.init($1.loc); - $$.qualifier.storage = EvqUniform; - } - | BUFFER { - parseContext.globalCheck($1.loc, "buffer"); - $$.init($1.loc); - $$.qualifier.storage = EvqBuffer; - } | HITATTRNV { -#ifdef NV_EXTENSIONS parseContext.globalCheck($1.loc, "hitAttributeNV"); - parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangClosestHitNVMask - | EShLangAnyHitNVMask), "hitAttributeNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask + | EShLangAnyHitMask), "hitAttributeNV"); parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV"); $$.init($1.loc); - $$.qualifier.storage = EvqHitAttrNV; -#endif + $$.qualifier.storage = EvqHitAttr; + } + | HITATTREXT { + parseContext.globalCheck($1.loc, "hitAttributeEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask + | EShLangAnyHitMask), "hitAttributeEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "hitAttributeNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqHitAttr; } | PAYLOADNV { -#ifdef NV_EXTENSIONS parseContext.globalCheck($1.loc, "rayPayloadNV"); - parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | - EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadNV"); parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV"); $$.init($1.loc); - $$.qualifier.storage = EvqPayloadNV; -#endif + $$.qualifier.storage = EvqPayload; + } + | PAYLOADEXT { + parseContext.globalCheck($1.loc, "rayPayloadEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "rayPayloadEXT"); + $$.init($1.loc); + $$.qualifier.storage = EvqPayload; } | PAYLOADINNV { -#ifdef NV_EXTENSIONS parseContext.globalCheck($1.loc, "rayPayloadInNV"); - parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangClosestHitNVMask | - EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadInNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadInNV"); parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV"); $$.init($1.loc); - $$.qualifier.storage = EvqPayloadInNV; -#endif + $$.qualifier.storage = EvqPayloadIn; + } + | PAYLOADINEXT { + parseContext.globalCheck($1.loc, "rayPayloadInEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadInEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "rayPayloadInEXT"); + $$.init($1.loc); + $$.qualifier.storage = EvqPayloadIn; } | CALLDATANV { -#ifdef NV_EXTENSIONS parseContext.globalCheck($1.loc, "callableDataNV"); - parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenNVMask | - EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), "callableDataNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | + EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataNV"); parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataNV"); $$.init($1.loc); - $$.qualifier.storage = EvqCallableDataNV; -#endif + $$.qualifier.storage = EvqCallableData; + } + | CALLDATAEXT { + parseContext.globalCheck($1.loc, "callableDataEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | + EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "callableDataEXT"); + $$.init($1.loc); + $$.qualifier.storage = EvqCallableData; } | CALLDATAINNV { -#ifdef NV_EXTENSIONS parseContext.globalCheck($1.loc, "callableDataInNV"); - parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV"); parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV"); $$.init($1.loc); - $$.qualifier.storage = EvqCallableDataInNV; -#endif + $$.qualifier.storage = EvqCallableDataIn; } - | SHARED { - parseContext.globalCheck($1.loc, "shared"); - parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); - parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared"); -#ifdef NV_EXTENSIONS - parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); -#else - parseContext.requireStage($1.loc, EShLangCompute, "shared"); -#endif + | CALLDATAINEXT { + parseContext.globalCheck($1.loc, "callableDataInEXT"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInEXT"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "callableDataInEXT"); $$.init($1.loc); - $$.qualifier.storage = EvqShared; + $$.qualifier.storage = EvqCallableDataIn; } | COHERENT { $$.init($1.loc); @@ -1438,6 +1615,11 @@ storage_qualifier parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate"); $$.qualifier.nonprivate = true; } + | SHADERCALLCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_ray_tracing, "shadercallcoherent"); + $$.qualifier.shadercallcoherent = true; + } | VOLATILE { $$.init($1.loc); $$.qualifier.volatil = true; @@ -1466,8 +1648,10 @@ storage_qualifier parseContext.unimplemented($1.loc, "subroutine"); $$.init($1.loc); } + ; + non_uniform_qualifier : NONUNIFORM { $$.init($1.loc); @@ -1486,16 +1670,19 @@ type_name_list } ; + type_specifier - : type_specifier_nonarray { + : type_specifier_nonarray type_parameter_specifier_opt { $$ = $1; $$.qualifier.precision = parseContext.getDefaultPrecision($$); + $$.typeParameters = $2; } - | type_specifier_nonarray array_specifier { - parseContext.arrayOfArrayVersionCheck($2.loc, $2.arraySizes); + | type_specifier_nonarray type_parameter_specifier_opt array_specifier { + parseContext.arrayOfArrayVersionCheck($3.loc, $3.arraySizes); $$ = $1; $$.qualifier.precision = parseContext.getDefaultPrecision($$); - $$.arraySizes = $2.arraySizes; + $$.typeParameters = $2; + $$.arraySizes = $3.arraySizes; } ; @@ -1510,7 +1697,7 @@ array_specifier $$.arraySizes = new TArraySizes; TArraySize size; - parseContext.arraySizeCheck($2->getLoc(), $2, size); + parseContext.arraySizeCheck($2->getLoc(), $2, size, "array size"); $$.arraySizes->addInnerSize(size); } | array_specifier LEFT_BRACKET RIGHT_BRACKET { @@ -1521,11 +1708,43 @@ array_specifier $$ = $1; TArraySize size; - parseContext.arraySizeCheck($3->getLoc(), $3, size); + parseContext.arraySizeCheck($3->getLoc(), $3, size, "array size"); $$.arraySizes->addInnerSize(size); } ; +type_parameter_specifier_opt + : type_parameter_specifier { + $$ = $1; + } + | /* May be null */ { + $$ = 0; + } + ; + +type_parameter_specifier + : LEFT_ANGLE type_parameter_specifier_list RIGHT_ANGLE { + $$ = $2; + } + ; + +type_parameter_specifier_list + : unary_expression { + $$ = new TArraySizes; + + TArraySize size; + parseContext.arraySizeCheck($1->getLoc(), $1, size, "type parameter"); + $$->addInnerSize(size); + } + | type_parameter_specifier_list COMMA unary_expression { + $$ = $1; + + TArraySize size; + parseContext.arraySizeCheck($3->getLoc(), $3, size, "type parameter"); + $$->addInnerSize(size); + } + ; + type_specifier_nonarray : VOID { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -1535,8 +1754,147 @@ type_specifier_nonarray $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; } + | INT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + } + | UINT { + parseContext.fullIntegerCheck($1.loc, "unsigned integer"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + } + | BOOL { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + } + | VEC2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(2); + } + | VEC3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(3); + } + | VEC4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(4); + } + | BVEC2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + $$.setVector(2); + } + | BVEC3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + $$.setVector(3); + } + | BVEC4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + $$.setVector(4); + } + | IVEC2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(2); + } + | IVEC3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(3); + } + | IVEC4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(4); + } + | UVEC2 { + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(2); + } + | UVEC3 { + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(3); + } + | UVEC4 { + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(4); + } + | MAT2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | MAT3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | MAT4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } + | MAT2X2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | MAT2X3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 3); + } + | MAT2X4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 4); + } + | MAT3X2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 2); + } + | MAT3X3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | MAT3X4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 4); + } + | MAT4X2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 2); + } + | MAT4X3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 3); + } + | MAT4X4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } + | DOUBLE { - parseContext.doubleCheck($1.loc, "double"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; } @@ -1555,15 +1913,6 @@ type_specifier_nonarray $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; } - | INT { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt; - } - | UINT { - parseContext.fullIntegerCheck($1.loc, "unsigned integer"); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint; - } | INT8_T { parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -1604,39 +1953,26 @@ type_specifier_nonarray $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtUint64; } - | BOOL { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtBool; - } - | VEC2 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setVector(2); - } - | VEC3 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setVector(3); - } - | VEC4 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setVector(4); - } | DVEC2 { - parseContext.doubleCheck($1.loc, "double vector"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setVector(2); } | DVEC3 { - parseContext.doubleCheck($1.loc, "double vector"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setVector(3); } | DVEC4 { - parseContext.doubleCheck($1.loc, "double vector"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setVector(4); @@ -1695,36 +2031,6 @@ type_specifier_nonarray $$.basicType = EbtDouble; $$.setVector(4); } - | BVEC2 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtBool; - $$.setVector(2); - } - | BVEC3 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtBool; - $$.setVector(3); - } - | BVEC4 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtBool; - $$.setVector(4); - } - | IVEC2 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt; - $$.setVector(2); - } - | IVEC3 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt; - $$.setVector(3); - } - | IVEC4 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt; - $$.setVector(4); - } | I8VEC2 { parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -1797,24 +2103,6 @@ type_specifier_nonarray $$.basicType = EbtInt64; $$.setVector(4); } - | UVEC2 { - parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint; - $$.setVector(2); - } - | UVEC3 { - parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint; - $$.setVector(3); - } - | UVEC4 { - parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint; - $$.setVector(4); - } | U8VEC2 { parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -1887,134 +2175,98 @@ type_specifier_nonarray $$.basicType = EbtUint64; $$.setVector(4); } - | MAT2 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(2, 2); - } - | MAT3 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(3, 3); - } - | MAT4 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(4, 4); - } - | MAT2X2 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(2, 2); - } - | MAT2X3 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(2, 3); - } - | MAT2X4 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(2, 4); - } - | MAT3X2 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(3, 2); - } - | MAT3X3 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(3, 3); - } - | MAT3X4 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(3, 4); - } - | MAT4X2 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(4, 2); - } - | MAT4X3 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(4, 3); - } - | MAT4X4 { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setMatrix(4, 4); - } | DMAT2 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 2); } | DMAT3 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 3); } | DMAT4 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 4); } | DMAT2X2 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 2); } | DMAT2X3 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 3); } | DMAT2X4 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 4); } | DMAT3X2 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 2); } | DMAT3X3 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 3); } | DMAT3X4 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 4); } | DMAT4X2 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 2); } | DMAT4X3 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 3); } | DMAT4X4 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 4); @@ -2236,10 +2488,16 @@ type_specifier_nonarray $$.setMatrix(4, 4); } | ACCSTRUCTNV { -#ifdef NV_EXTENSIONS $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtAccStructNV; -#endif + $$.basicType = EbtAccStruct; + } + | ACCSTRUCTEXT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtAccStruct; + } + | RAYQUERYEXT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtRayQuery; } | ATOMIC_UINT { parseContext.vulkanRemoved($1.loc, "atomic counter types"); @@ -2251,6 +2509,7 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd1D); } + | SAMPLER2D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2266,11 +2525,6 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdCube); } - | SAMPLER1DSHADOW { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtFloat, Esd1D, false, true); - } | SAMPLER2DSHADOW { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2281,26 +2535,32 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdCube, false, true); } - | SAMPLER1DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtFloat, Esd1D, true); - } | SAMPLER2DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D, true); } - | SAMPLER1DARRAYSHADOW { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtFloat, Esd1D, true, true); - } | SAMPLER2DARRAYSHADOW { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D, true, true); } + + | SAMPLER1DSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, false, true); + } + | SAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, true); + } + | SAMPLER1DARRAYSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, true, true); + } | SAMPLERCUBEARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2312,114 +2572,89 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, EsdCube, true, true); } | F16SAMPLER1D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd1D); -#endif } | F16SAMPLER2D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D); -#endif } | F16SAMPLER3D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd3D); -#endif } | F16SAMPLERCUBE { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdCube); -#endif } | F16SAMPLER1DSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd1D, false, true); -#endif } | F16SAMPLER2DSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, false, true); -#endif } | F16SAMPLERCUBESHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdCube, false, true); -#endif } | F16SAMPLER1DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd1D, true); -#endif } | F16SAMPLER2DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, true); -#endif } | F16SAMPLER1DARRAYSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd1D, true, true); -#endif } | F16SAMPLER2DARRAYSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, true, true); -#endif } | F16SAMPLERCUBEARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdCube, true); -#endif } | F16SAMPLERCUBEARRAYSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdCube, true, true); -#endif } | ISAMPLER1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd1D); } + | ISAMPLER2D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2435,26 +2670,11 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtInt, EsdCube); } - | ISAMPLER1DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtInt, Esd1D, true); - } | ISAMPLER2DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd2D, true); } - | ISAMPLERCUBEARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtInt, EsdCube, true); - } - | USAMPLER1D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtUint, Esd1D); - } | USAMPLER2D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2470,21 +2690,124 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtUint, EsdCube); } + + | ISAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd1D, true); + } + | ISAMPLERCUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdCube, true); + } + | USAMPLER1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd1D); + } | USAMPLER1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd1D, true); } - | USAMPLER2DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtUint, Esd2D, true); - } | USAMPLERCUBEARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, EsdCube, true); } + | TEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdCube, true); + } + | ITEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdCube, true); + } + | UTEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdCube, true); + } + + | USAMPLER2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D, true); + } + | TEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D); + } + | TEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd3D); + } + | TEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D, true); + } + | TEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdCube); + } + | ITEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D); + } + | ITEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd3D); + } + | ITEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdCube); + } + | ITEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D, true); + } + | UTEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D); + } + | UTEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd3D); + } + | UTEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdCube); + } + | UTEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D, true); + } + | SAMPLER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setPureSampler(false); + } + | SAMPLERSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setPureSampler(true); + } + | SAMPLER2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2496,20 +2819,16 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, EsdRect, false, true); } | F16SAMPLER2DRECT { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdRect); -#endif } | F16SAMPLER2DRECTSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdRect, false, true); -#endif } | ISAMPLER2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2527,12 +2846,10 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, EsdBuffer); } | F16SAMPLERBUFFER { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdBuffer); -#endif } | ISAMPLERBUFFER { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2550,12 +2867,10 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, Esd2D, false, false, true); } | F16SAMPLER2DMS { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, false, false, true); -#endif } | ISAMPLER2DMS { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2573,12 +2888,10 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, Esd2D, true, false, true); } | F16SAMPLER2DMSARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, true, false, true); -#endif } | ISAMPLER2DMSARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2590,67 +2903,34 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd2D, true, false, true); } - | SAMPLER { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setPureSampler(false); - } - | SAMPLERSHADOW { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setPureSampler(true); - } | TEXTURE1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat, Esd1D); } | F16TEXTURE1D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd1D); -#endif - } - | TEXTURE2D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, Esd2D); } | F16TEXTURE2D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd2D); -#endif - } - | TEXTURE3D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, Esd3D); } | F16TEXTURE3D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd3D); -#endif - } - | TEXTURECUBE { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, EsdCube); } | F16TEXTURECUBE { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, EsdCube); -#endif } | TEXTURE1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2658,121 +2938,53 @@ type_specifier_nonarray $$.sampler.setTexture(EbtFloat, Esd1D, true); } | F16TEXTURE1DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd1D, true); -#endif - } - | TEXTURE2DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, Esd2D, true); } | F16TEXTURE2DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd2D, true); -#endif - } - | TEXTURECUBEARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, EsdCube, true); } | F16TEXTURECUBEARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, EsdCube, true); -#endif } | ITEXTURE1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtInt, Esd1D); } - | ITEXTURE2D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, Esd2D); - } - | ITEXTURE3D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, Esd3D); - } - | ITEXTURECUBE { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, EsdCube); - } | ITEXTURE1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtInt, Esd1D, true); } - | ITEXTURE2DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, Esd2D, true); - } - | ITEXTURECUBEARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, EsdCube, true); - } | UTEXTURE1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtUint, Esd1D); } - | UTEXTURE2D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, Esd2D); - } - | UTEXTURE3D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, Esd3D); - } - | UTEXTURECUBE { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, EsdCube); - } | UTEXTURE1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtUint, Esd1D, true); } - | UTEXTURE2DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, Esd2D, true); - } - | UTEXTURECUBEARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, EsdCube, true); - } | TEXTURE2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat, EsdRect); } | F16TEXTURE2DRECT { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, EsdRect); -#endif } | ITEXTURE2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2790,12 +3002,10 @@ type_specifier_nonarray $$.sampler.setTexture(EbtFloat, EsdBuffer); } | F16TEXTUREBUFFER { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, EsdBuffer); -#endif } | ITEXTUREBUFFER { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2813,12 +3023,10 @@ type_specifier_nonarray $$.sampler.setTexture(EbtFloat, Esd2D, false, false, true); } | F16TEXTURE2DMS { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd2D, false, false, true); -#endif } | ITEXTURE2DMS { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2836,12 +3044,10 @@ type_specifier_nonarray $$.sampler.setTexture(EbtFloat, Esd2D, true, false, true); } | F16TEXTURE2DMSARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd2D, true, false, true); -#endif } | ITEXTURE2DMSARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2859,12 +3065,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd1D); } | F16IMAGE1D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd1D); -#endif } | IIMAGE1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2882,12 +3086,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd2D); } | F16IMAGE2D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd2D); -#endif } | IIMAGE2D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2905,12 +3107,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd3D); } | F16IMAGE3D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd3D); -#endif } | IIMAGE3D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2928,12 +3128,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, EsdRect); } | F16IMAGE2DRECT { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, EsdRect); -#endif } | IIMAGE2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2951,12 +3149,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, EsdCube); } | F16IMAGECUBE { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, EsdCube); -#endif } | IIMAGECUBE { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2974,12 +3170,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, EsdBuffer); } | F16IMAGEBUFFER { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, EsdBuffer); -#endif } | IIMAGEBUFFER { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2997,12 +3191,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd1D, true); } | F16IMAGE1DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd1D, true); -#endif } | IIMAGE1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -3020,12 +3212,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd2D, true); } | F16IMAGE2DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd2D, true); -#endif } | IIMAGE2DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -3043,12 +3233,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, EsdCube, true); } | F16IMAGECUBEARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, EsdCube, true); -#endif } | IIMAGECUBEARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -3066,12 +3254,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd2D, false, false, true); } | F16IMAGE2DMS { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd2D, false, false, true); -#endif } | IIMAGE2DMS { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -3089,12 +3275,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd2D, true, false, true); } | F16IMAGE2DMSARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd2D, true, false, true); -#endif } | IIMAGE2DMSARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -3106,6 +3290,116 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, Esd2D, true, false, true); } + | I64IMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd1D); + } + | U64IMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd1D); + } + | I64IMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd2D); + } + | U64IMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd2D); + } + | I64IMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd3D); + } + | U64IMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd3D); + } + | I64IMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, EsdRect); + } + | U64IMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, EsdRect); + } + | I64IMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, EsdCube); + } + | U64IMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, EsdCube); + } + | I64IMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, EsdBuffer); + } + | U64IMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, EsdBuffer); + } + | I64IMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd1D, true); + } + | U64IMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd1D, true); + } + | I64IMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd2D, true); + } + | U64IMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd2D, true); + } + | I64IMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, EsdCube, true); + } + | U64IMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, EsdCube, true); + } + | I64IMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd2D, false, false, true); + } + | U64IMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd2D, false, false, true); + } + | I64IMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt64, Esd2D, true, false, true); + } + | U64IMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint64, Esd2D, true, false, true); + } | SAMPLEREXTERNALOES { // GL_OES_EGL_image_external $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -3131,22 +3425,18 @@ type_specifier_nonarray $$.sampler.setSubpass(EbtFloat, true); } | F16SUBPASSINPUT { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setSubpass(EbtFloat16); -#endif } | F16SUBPASSINPUTMS { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setSubpass(EbtFloat16, true); -#endif } | ISUBPASSINPUT { parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); @@ -3172,6 +3462,29 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.setSubpass(EbtUint, true); } + | FCOOPMATNV { + parseContext.fcoopmatCheck($1.loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.coopmat = true; + } + | ICOOPMATNV { + parseContext.intcoopmatCheck($1.loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.coopmat = true; + } + | UCOOPMATNV { + parseContext.intcoopmatCheck($1.loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.coopmat = true; + } + | spirv_type_specifier { + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier"); + $$ = $1; + } + | struct_specifier { $$ = $1; $$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3252,7 +3565,7 @@ struct_declaration if ($1.arraySizes) { parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); } @@ -3274,7 +3587,7 @@ struct_declaration if ($2.arraySizes) { parseContext.profileRequires($2.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) parseContext.arraySizeRequiredCheck($2.loc, *$2.arraySizes); } @@ -3326,6 +3639,7 @@ initializer : assignment_expression { $$ = $1; } + | LEFT_BRACE initializer_list RIGHT_BRACE { const char* initFeature = "{ } style initializers"; parseContext.requireProfile($1.loc, ~EEsProfile, initFeature); @@ -3338,8 +3652,16 @@ initializer parseContext.profileRequires($1.loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); $$ = $2; } + | LEFT_BRACE RIGHT_BRACE { + const char* initFeature = "empty { } initializer"; + parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); + parseContext.profileRequires($1.loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); + $$ = parseContext.intermediate.makeAggregate($1.loc); + } + ; + initializer_list : initializer { $$ = parseContext.intermediate.growAggregate(0, $1, $1->getLoc()); @@ -3349,6 +3671,7 @@ initializer_list } ; + declaration_statement : declaration { $$ = $1; } ; @@ -3368,8 +3691,21 @@ simple_statement | case_label { $$ = $1; } | iteration_statement { $$ = $1; } | jump_statement { $$ = $1; } + + | demote_statement { $$ = $1; } + ; + +demote_statement + : DEMOTE SEMICOLON { + parseContext.requireStage($1.loc, EShLangFragment, "demote"); + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote"); + $$ = parseContext.intermediate.addBranch(EOpDemote, $1.loc); + } + ; + + compound_statement : LEFT_BRACE RIGHT_BRACE { $$ = 0; } | LEFT_BRACE { @@ -3452,11 +3788,14 @@ selection_statement : selection_statement_nonattributed { $$ = $1; } + | attribute selection_statement_nonattributed { + parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleSelectionAttributes(*$1, $2); $$ = $2; } + selection_statement_nonattributed : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { parseContext.boolCheck($1.loc, $3); @@ -3497,11 +3836,14 @@ switch_statement : switch_statement_nonattributed { $$ = $1; } + | attribute switch_statement_nonattributed { + parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleSwitchAttributes(*$1, $2); $$ = $2; } + switch_statement_nonattributed : SWITCH LEFT_PAREN expression RIGHT_PAREN { // start new switch sequence on the switch stack @@ -3559,11 +3901,14 @@ iteration_statement : iteration_statement_nonattributed { $$ = $1; } + | attribute iteration_statement_nonattributed { + parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleLoopAttributes(*$1, $2); $$ = $2; } + iteration_statement_nonattributed : WHILE LEFT_PAREN { if (! parseContext.limits.whileLoops) @@ -3670,6 +4015,20 @@ jump_statement parseContext.requireStage($1.loc, EShLangFragment, "discard"); $$ = parseContext.intermediate.addBranch(EOpKill, $1.loc); } + | TERMINATE_INVOCATION SEMICOLON { + parseContext.requireStage($1.loc, EShLangFragment, "terminateInvocation"); + $$ = parseContext.intermediate.addBranch(EOpTerminateInvocation, $1.loc); + } + + | TERMINATE_RAY SEMICOLON { + parseContext.requireStage($1.loc, EShLangAnyHit, "terminateRayEXT"); + $$ = parseContext.intermediate.addBranch(EOpTerminateRayKHR, $1.loc); + } + | IGNORE_INTERSECTION SEMICOLON { + parseContext.requireStage($1.loc, EShLangAnyHit, "ignoreIntersectionEXT"); + $$ = parseContext.intermediate.addBranch(EOpIgnoreIntersectionKHR, $1.loc); + } + ; // Grammar Note: No 'goto'. Gotos are not supported. @@ -3694,17 +4053,27 @@ external_declaration | declaration { $$ = $1; } + | SEMICOLON { parseContext.requireProfile($1.loc, ~EEsProfile, "extraneous semicolon"); parseContext.profileRequires($1.loc, ~EEsProfile, 460, nullptr, "extraneous semicolon"); $$ = nullptr; } + ; function_definition : function_prototype { $1.function = parseContext.handleFunctionDeclarator($1.loc, *$1.function, false /* not prototype */); $1.intermNode = parseContext.handleFunctionDefinition($1.loc, *$1.function); + + // For ES 100 only, according to ES shading language 100 spec: A function + // body has a scope nested inside the function's definition. + if (parseContext.profile == EEsProfile && parseContext.version == 100) + { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + } } compound_statement_no_new_scope { // May be best done as post process phase on intermediate code @@ -3720,13 +4089,24 @@ function_definition $$->getAsAggregate()->setOptimize(parseContext.contextPragma.optimize); $$->getAsAggregate()->setDebug(parseContext.contextPragma.debug); $$->getAsAggregate()->setPragmaTable(parseContext.contextPragma.pragmaTable); + + // Set currentFunctionType to empty pointer when goes outside of the function + parseContext.currentFunctionType = nullptr; + + // For ES 100 only, according to ES shading language 100 spec: A function + // body has a scope nested inside the function's definition. + if (parseContext.profile == EEsProfile && parseContext.version == 100) + { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + } } ; + attribute : LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET { $$ = $3; - parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute"); } attribute_list @@ -3745,4 +4125,274 @@ single_attribute $$ = parseContext.makeAttributes(*$1.string, $3); } + + +spirv_requirements_list + : spirv_requirements_parameter { + $$ = $1; + } + | spirv_requirements_list COMMA spirv_requirements_parameter { + $$ = parseContext.mergeSpirvRequirements($2.loc, $1, $3); + } + +spirv_requirements_parameter + : IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET { + $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, $4->getAsAggregate(), nullptr); + } + | IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET { + $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, nullptr, $4->getAsAggregate()); + } + +spirv_extension_list + : STRING_LITERAL { + $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.string, $1.loc, true)); + } + | spirv_extension_list COMMA STRING_LITERAL { + $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true)); + } + +spirv_capability_list + : INTCONSTANT { + $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.i, $1.loc, true)); + } + | spirv_capability_list COMMA INTCONSTANT { + $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.i, $3.loc, true)); + } + +spirv_execution_mode_qualifier + : SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN { + parseContext.intermediate.insertSpirvExecutionMode($3.i); + $$ = 0; + } + | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN { + parseContext.intermediate.insertSpirvRequirement($3); + parseContext.intermediate.insertSpirvExecutionMode($5.i); + $$ = 0; + } + | SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvExecutionMode($3.i, $5->getAsAggregate()); + $$ = 0; + } + | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvRequirement($3); + parseContext.intermediate.insertSpirvExecutionMode($5.i, $7->getAsAggregate()); + $$ = 0; + } + | SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvExecutionModeId($3.i, $5->getAsAggregate()); + $$ = 0; + } + | SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvRequirement($3); + parseContext.intermediate.insertSpirvExecutionModeId($5.i, $7->getAsAggregate()); + $$ = 0; + } + +spirv_execution_mode_parameter_list + : spirv_execution_mode_parameter { + $$ = parseContext.intermediate.makeAggregate($1); + } + | spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter { + $$ = parseContext.intermediate.growAggregate($1, $3); + } + +spirv_execution_mode_parameter + : FLOATCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); + } + | INTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } + | BOOLCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); + } + | STRING_LITERAL { + $$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true); + } + +spirv_execution_mode_id_parameter_list + : constant_expression { + if ($1->getBasicType() != EbtFloat && + $1->getBasicType() != EbtInt && + $1->getBasicType() != EbtUint && + $1->getBasicType() != EbtBool && + $1->getBasicType() != EbtString) + parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), ""); + $$ = parseContext.intermediate.makeAggregate($1); + } + | spirv_execution_mode_id_parameter_list COMMA constant_expression { + if ($3->getBasicType() != EbtFloat && + $3->getBasicType() != EbtInt && + $3->getBasicType() != EbtUint && + $3->getBasicType() != EbtBool && + $3->getBasicType() != EbtString) + parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), ""); + $$ = parseContext.intermediate.growAggregate($1, $3); + } + +spirv_storage_class_qualifier + : SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN { + $$.init($1.loc); + $$.qualifier.storage = EvqSpirvStorageClass; + $$.qualifier.spirvStorageClass = $3.i; + } + | SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN { + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.storage = EvqSpirvStorageClass; + $$.qualifier.spirvStorageClass = $5.i; + } + +spirv_decorate_qualifier + : SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN{ + $$.init($1.loc); + $$.qualifier.setSpirvDecorate($3.i); + } + | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN{ + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.setSpirvDecorate($5.i); + } + | SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN { + $$.init($1.loc); + $$.qualifier.setSpirvDecorate($3.i, $5->getAsAggregate()); + } + | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN { + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.setSpirvDecorate($5.i, $7->getAsAggregate()); + } + | SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN { + $$.init($1.loc); + $$.qualifier.setSpirvDecorateId($3.i, $5->getAsAggregate()); + } + | SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN { + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.setSpirvDecorateId($5.i, $7->getAsAggregate()); + } + | SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN { + $$.init($1.loc); + $$.qualifier.setSpirvDecorateString($3.i, $5->getAsAggregate()); + } + | SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN { + $$.init($1.loc); + parseContext.intermediate.insertSpirvRequirement($3); + $$.qualifier.setSpirvDecorateString($5.i, $7->getAsAggregate()); + } + +spirv_decorate_parameter_list + : spirv_decorate_parameter { + $$ = parseContext.intermediate.makeAggregate($1); + } + | spirv_decorate_parameter_list COMMA spirv_decorate_parameter { + $$ = parseContext.intermediate.growAggregate($1, $3); + } + +spirv_decorate_parameter + : FLOATCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); + } + | INTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } + | BOOLCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); + } + +spirv_decorate_id_parameter_list + : constant_expression { + if ($1->getBasicType() != EbtFloat && + $1->getBasicType() != EbtInt && + $1->getBasicType() != EbtUint && + $1->getBasicType() != EbtBool) + parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), ""); + $$ = parseContext.intermediate.makeAggregate($1); + } + | spirv_decorate_id_parameter_list COMMA constant_expression { + if ($3->getBasicType() != EbtFloat && + $3->getBasicType() != EbtInt && + $3->getBasicType() != EbtUint && + $3->getBasicType() != EbtBool) + parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), ""); + $$ = parseContext.intermediate.growAggregate($1, $3); + } + +spirv_decorate_string_parameter_list + : STRING_LITERAL { + $$ = parseContext.intermediate.makeAggregate( + parseContext.intermediate.addConstantUnion($1.string, $1.loc, true)); + } + | spirv_decorate_string_parameter_list COMMA STRING_LITERAL { + $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true)); + } + +spirv_type_specifier + : SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.setSpirvType(*$3, $5); + } + | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.intermediate.insertSpirvRequirement($3); + $$.setSpirvType(*$5, $7); + } + | SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.setSpirvType(*$3); + } + | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.intermediate.insertSpirvRequirement($3); + $$.setSpirvType(*$5); + } + +spirv_type_parameter_list + : spirv_type_parameter { + $$ = $1; + } + | spirv_type_parameter_list COMMA spirv_type_parameter { + $$ = parseContext.mergeSpirvTypeParameters($1, $3); + } + +spirv_type_parameter + : constant_expression { + $$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion()); + } + | type_specifier { + $$ = parseContext.makeSpirvTypeParameters($1); + } + +spirv_instruction_qualifier + : SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN { + $$ = $3; + } + | SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN { + parseContext.intermediate.insertSpirvRequirement($3); + $$ = $5; + } + +spirv_instruction_qualifier_list + : spirv_instruction_qualifier_id { + $$ = $1; + } + | spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id { + $$ = parseContext.mergeSpirvInstruction($2.loc, $1, $3); + } + +spirv_instruction_qualifier_id + : IDENTIFIER EQUAL STRING_LITERAL { + $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, *$3.string); + } + | IDENTIFIER EQUAL INTCONSTANT { + $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i); + } + + %% diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang_tab.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang_tab.cpp index 1348c8b..dba06ae 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang_tab.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang_tab.cpp @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.7.4. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,6 +34,10 @@ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. @@ -40,11 +45,11 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ -/* Identify Bison output. */ -#define YYBISON 1 +/* Identify Bison output, and Bison version. */ +#define YYBISON 30704 -/* Bison version. */ -#define YYBISON_VERSION "3.0.4" +/* Bison version string. */ +#define YYBISON_VERSION "3.7.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -61,8 +66,8 @@ -/* Copy the first part of user declarations. */ -#line 43 "MachineIndependent/glslang.y" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 69 "MachineIndependent/glslang.y" /* Based on: @@ -88,504 +93,626 @@ Jutta Degener, 1995 using namespace glslang; -#line 92 "MachineIndependent/glslang_tab.cpp" /* yacc.c:339 */ +#line 97 "MachineIndependent/glslang_tab.cpp" -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else -# define YY_NULLPTR 0 +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) # endif # endif -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "glslang_tab.cpp.h". */ -#ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED -# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 1 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - ATTRIBUTE = 258, - VARYING = 259, - FLOAT16_T = 260, - FLOAT = 261, - FLOAT32_T = 262, - DOUBLE = 263, - FLOAT64_T = 264, - CONST = 265, - BOOL = 266, - INT = 267, - UINT = 268, - INT64_T = 269, - UINT64_T = 270, - INT32_T = 271, - UINT32_T = 272, - INT16_T = 273, - UINT16_T = 274, - INT8_T = 275, - UINT8_T = 276, - BREAK = 277, - CONTINUE = 278, - DO = 279, - ELSE = 280, - FOR = 281, - IF = 282, - DISCARD = 283, - RETURN = 284, - SWITCH = 285, - CASE = 286, - DEFAULT = 287, - SUBROUTINE = 288, - BVEC2 = 289, - BVEC3 = 290, - BVEC4 = 291, - IVEC2 = 292, - IVEC3 = 293, - IVEC4 = 294, - UVEC2 = 295, - UVEC3 = 296, - UVEC4 = 297, - I64VEC2 = 298, - I64VEC3 = 299, - I64VEC4 = 300, - U64VEC2 = 301, - U64VEC3 = 302, - U64VEC4 = 303, - I32VEC2 = 304, - I32VEC3 = 305, - I32VEC4 = 306, - U32VEC2 = 307, - U32VEC3 = 308, - U32VEC4 = 309, - I16VEC2 = 310, - I16VEC3 = 311, - I16VEC4 = 312, - U16VEC2 = 313, - U16VEC3 = 314, - U16VEC4 = 315, - I8VEC2 = 316, - I8VEC3 = 317, - I8VEC4 = 318, - U8VEC2 = 319, - U8VEC3 = 320, - U8VEC4 = 321, - VEC2 = 322, - VEC3 = 323, - VEC4 = 324, - MAT2 = 325, - MAT3 = 326, - MAT4 = 327, - CENTROID = 328, - IN = 329, - OUT = 330, - INOUT = 331, - UNIFORM = 332, - PATCH = 333, - SAMPLE = 334, - BUFFER = 335, - SHARED = 336, - NONUNIFORM = 337, - PAYLOADNV = 338, - PAYLOADINNV = 339, - HITATTRNV = 340, - CALLDATANV = 341, - CALLDATAINNV = 342, - COHERENT = 343, - VOLATILE = 344, - RESTRICT = 345, - READONLY = 346, - WRITEONLY = 347, - DEVICECOHERENT = 348, - QUEUEFAMILYCOHERENT = 349, - WORKGROUPCOHERENT = 350, - SUBGROUPCOHERENT = 351, - NONPRIVATE = 352, - DVEC2 = 353, - DVEC3 = 354, - DVEC4 = 355, - DMAT2 = 356, - DMAT3 = 357, - DMAT4 = 358, - F16VEC2 = 359, - F16VEC3 = 360, - F16VEC4 = 361, - F16MAT2 = 362, - F16MAT3 = 363, - F16MAT4 = 364, - F32VEC2 = 365, - F32VEC3 = 366, - F32VEC4 = 367, - F32MAT2 = 368, - F32MAT3 = 369, - F32MAT4 = 370, - F64VEC2 = 371, - F64VEC3 = 372, - F64VEC4 = 373, - F64MAT2 = 374, - F64MAT3 = 375, - F64MAT4 = 376, - NOPERSPECTIVE = 377, - FLAT = 378, - SMOOTH = 379, - LAYOUT = 380, - EXPLICITINTERPAMD = 381, - PERVERTEXNV = 382, - PERPRIMITIVENV = 383, - PERVIEWNV = 384, - PERTASKNV = 385, - MAT2X2 = 386, - MAT2X3 = 387, - MAT2X4 = 388, - MAT3X2 = 389, - MAT3X3 = 390, - MAT3X4 = 391, - MAT4X2 = 392, - MAT4X3 = 393, - MAT4X4 = 394, - DMAT2X2 = 395, - DMAT2X3 = 396, - DMAT2X4 = 397, - DMAT3X2 = 398, - DMAT3X3 = 399, - DMAT3X4 = 400, - DMAT4X2 = 401, - DMAT4X3 = 402, - DMAT4X4 = 403, - F16MAT2X2 = 404, - F16MAT2X3 = 405, - F16MAT2X4 = 406, - F16MAT3X2 = 407, - F16MAT3X3 = 408, - F16MAT3X4 = 409, - F16MAT4X2 = 410, - F16MAT4X3 = 411, - F16MAT4X4 = 412, - F32MAT2X2 = 413, - F32MAT2X3 = 414, - F32MAT2X4 = 415, - F32MAT3X2 = 416, - F32MAT3X3 = 417, - F32MAT3X4 = 418, - F32MAT4X2 = 419, - F32MAT4X3 = 420, - F32MAT4X4 = 421, - F64MAT2X2 = 422, - F64MAT2X3 = 423, - F64MAT2X4 = 424, - F64MAT3X2 = 425, - F64MAT3X3 = 426, - F64MAT3X4 = 427, - F64MAT4X2 = 428, - F64MAT4X3 = 429, - F64MAT4X4 = 430, - ATOMIC_UINT = 431, - ACCSTRUCTNV = 432, - SAMPLER1D = 433, - SAMPLER2D = 434, - SAMPLER3D = 435, - SAMPLERCUBE = 436, - SAMPLER1DSHADOW = 437, - SAMPLER2DSHADOW = 438, - SAMPLERCUBESHADOW = 439, - SAMPLER1DARRAY = 440, - SAMPLER2DARRAY = 441, - SAMPLER1DARRAYSHADOW = 442, - SAMPLER2DARRAYSHADOW = 443, - ISAMPLER1D = 444, - ISAMPLER2D = 445, - ISAMPLER3D = 446, - ISAMPLERCUBE = 447, - ISAMPLER1DARRAY = 448, - ISAMPLER2DARRAY = 449, - USAMPLER1D = 450, - USAMPLER2D = 451, - USAMPLER3D = 452, - USAMPLERCUBE = 453, - USAMPLER1DARRAY = 454, - USAMPLER2DARRAY = 455, - SAMPLER2DRECT = 456, - SAMPLER2DRECTSHADOW = 457, - ISAMPLER2DRECT = 458, - USAMPLER2DRECT = 459, - SAMPLERBUFFER = 460, - ISAMPLERBUFFER = 461, - USAMPLERBUFFER = 462, - SAMPLERCUBEARRAY = 463, - SAMPLERCUBEARRAYSHADOW = 464, - ISAMPLERCUBEARRAY = 465, - USAMPLERCUBEARRAY = 466, - SAMPLER2DMS = 467, - ISAMPLER2DMS = 468, - USAMPLER2DMS = 469, - SAMPLER2DMSARRAY = 470, - ISAMPLER2DMSARRAY = 471, - USAMPLER2DMSARRAY = 472, - SAMPLEREXTERNALOES = 473, - SAMPLEREXTERNAL2DY2YEXT = 474, - F16SAMPLER1D = 475, - F16SAMPLER2D = 476, - F16SAMPLER3D = 477, - F16SAMPLER2DRECT = 478, - F16SAMPLERCUBE = 479, - F16SAMPLER1DARRAY = 480, - F16SAMPLER2DARRAY = 481, - F16SAMPLERCUBEARRAY = 482, - F16SAMPLERBUFFER = 483, - F16SAMPLER2DMS = 484, - F16SAMPLER2DMSARRAY = 485, - F16SAMPLER1DSHADOW = 486, - F16SAMPLER2DSHADOW = 487, - F16SAMPLER1DARRAYSHADOW = 488, - F16SAMPLER2DARRAYSHADOW = 489, - F16SAMPLER2DRECTSHADOW = 490, - F16SAMPLERCUBESHADOW = 491, - F16SAMPLERCUBEARRAYSHADOW = 492, - SAMPLER = 493, - SAMPLERSHADOW = 494, - TEXTURE1D = 495, - TEXTURE2D = 496, - TEXTURE3D = 497, - TEXTURECUBE = 498, - TEXTURE1DARRAY = 499, - TEXTURE2DARRAY = 500, - ITEXTURE1D = 501, - ITEXTURE2D = 502, - ITEXTURE3D = 503, - ITEXTURECUBE = 504, - ITEXTURE1DARRAY = 505, - ITEXTURE2DARRAY = 506, - UTEXTURE1D = 507, - UTEXTURE2D = 508, - UTEXTURE3D = 509, - UTEXTURECUBE = 510, - UTEXTURE1DARRAY = 511, - UTEXTURE2DARRAY = 512, - TEXTURE2DRECT = 513, - ITEXTURE2DRECT = 514, - UTEXTURE2DRECT = 515, - TEXTUREBUFFER = 516, - ITEXTUREBUFFER = 517, - UTEXTUREBUFFER = 518, - TEXTURECUBEARRAY = 519, - ITEXTURECUBEARRAY = 520, - UTEXTURECUBEARRAY = 521, - TEXTURE2DMS = 522, - ITEXTURE2DMS = 523, - UTEXTURE2DMS = 524, - TEXTURE2DMSARRAY = 525, - ITEXTURE2DMSARRAY = 526, - UTEXTURE2DMSARRAY = 527, - F16TEXTURE1D = 528, - F16TEXTURE2D = 529, - F16TEXTURE3D = 530, - F16TEXTURE2DRECT = 531, - F16TEXTURECUBE = 532, - F16TEXTURE1DARRAY = 533, - F16TEXTURE2DARRAY = 534, - F16TEXTURECUBEARRAY = 535, - F16TEXTUREBUFFER = 536, - F16TEXTURE2DMS = 537, - F16TEXTURE2DMSARRAY = 538, - SUBPASSINPUT = 539, - SUBPASSINPUTMS = 540, - ISUBPASSINPUT = 541, - ISUBPASSINPUTMS = 542, - USUBPASSINPUT = 543, - USUBPASSINPUTMS = 544, - F16SUBPASSINPUT = 545, - F16SUBPASSINPUTMS = 546, - IMAGE1D = 547, - IIMAGE1D = 548, - UIMAGE1D = 549, - IMAGE2D = 550, - IIMAGE2D = 551, - UIMAGE2D = 552, - IMAGE3D = 553, - IIMAGE3D = 554, - UIMAGE3D = 555, - IMAGE2DRECT = 556, - IIMAGE2DRECT = 557, - UIMAGE2DRECT = 558, - IMAGECUBE = 559, - IIMAGECUBE = 560, - UIMAGECUBE = 561, - IMAGEBUFFER = 562, - IIMAGEBUFFER = 563, - UIMAGEBUFFER = 564, - IMAGE1DARRAY = 565, - IIMAGE1DARRAY = 566, - UIMAGE1DARRAY = 567, - IMAGE2DARRAY = 568, - IIMAGE2DARRAY = 569, - UIMAGE2DARRAY = 570, - IMAGECUBEARRAY = 571, - IIMAGECUBEARRAY = 572, - UIMAGECUBEARRAY = 573, - IMAGE2DMS = 574, - IIMAGE2DMS = 575, - UIMAGE2DMS = 576, - IMAGE2DMSARRAY = 577, - IIMAGE2DMSARRAY = 578, - UIMAGE2DMSARRAY = 579, - F16IMAGE1D = 580, - F16IMAGE2D = 581, - F16IMAGE3D = 582, - F16IMAGE2DRECT = 583, - F16IMAGECUBE = 584, - F16IMAGE1DARRAY = 585, - F16IMAGE2DARRAY = 586, - F16IMAGECUBEARRAY = 587, - F16IMAGEBUFFER = 588, - F16IMAGE2DMS = 589, - F16IMAGE2DMSARRAY = 590, - STRUCT = 591, - VOID = 592, - WHILE = 593, - IDENTIFIER = 594, - TYPE_NAME = 595, - FLOATCONSTANT = 596, - DOUBLECONSTANT = 597, - INT16CONSTANT = 598, - UINT16CONSTANT = 599, - INT32CONSTANT = 600, - UINT32CONSTANT = 601, - INTCONSTANT = 602, - UINTCONSTANT = 603, - INT64CONSTANT = 604, - UINT64CONSTANT = 605, - BOOLCONSTANT = 606, - FLOAT16CONSTANT = 607, - LEFT_OP = 608, - RIGHT_OP = 609, - INC_OP = 610, - DEC_OP = 611, - LE_OP = 612, - GE_OP = 613, - EQ_OP = 614, - NE_OP = 615, - AND_OP = 616, - OR_OP = 617, - XOR_OP = 618, - MUL_ASSIGN = 619, - DIV_ASSIGN = 620, - ADD_ASSIGN = 621, - MOD_ASSIGN = 622, - LEFT_ASSIGN = 623, - RIGHT_ASSIGN = 624, - AND_ASSIGN = 625, - XOR_ASSIGN = 626, - OR_ASSIGN = 627, - SUB_ASSIGN = 628, - LEFT_PAREN = 629, - RIGHT_PAREN = 630, - LEFT_BRACKET = 631, - RIGHT_BRACKET = 632, - LEFT_BRACE = 633, - RIGHT_BRACE = 634, - DOT = 635, - COMMA = 636, - COLON = 637, - EQUAL = 638, - SEMICOLON = 639, - BANG = 640, - DASH = 641, - TILDE = 642, - PLUS = 643, - STAR = 644, - SLASH = 645, - PERCENT = 646, - LEFT_ANGLE = 647, - RIGHT_ANGLE = 648, - VERTICAL_BAR = 649, - CARET = 650, - AMPERSAND = 651, - QUESTION = 652, - INVARIANT = 653, - PRECISE = 654, - HIGH_PRECISION = 655, - MEDIUM_PRECISION = 656, - LOW_PRECISION = 657, - PRECISION = 658, - PACKED = 659, - RESOURCE = 660, - SUPERP = 661 - }; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -union YYSTYPE +#include "glslang_tab.cpp.h" +/* Symbol kind. */ +enum yysymbol_kind_t { -#line 71 "MachineIndependent/glslang.y" /* yacc.c:355 */ - - struct { - glslang::TSourceLoc loc; - union { - glslang::TString *string; - int i; - unsigned int u; - long long i64; - unsigned long long u64; - bool b; - double d; - }; - glslang::TSymbol* symbol; - } lex; - struct { - glslang::TSourceLoc loc; - glslang::TOperator op; - union { - TIntermNode* intermNode; - glslang::TIntermNodePair nodePair; - glslang::TIntermTyped* intermTypedNode; - glslang::TAttributes* attributes; - }; - union { - glslang::TPublicType type; - glslang::TFunction* function; - glslang::TParameter param; - glslang::TTypeLoc typeLine; - glslang::TTypeList* typeList; - glslang::TArraySizes* arraySizes; - glslang::TIdentifierList* identifierList; - }; - } interm; - -#line 574 "MachineIndependent/glslang_tab.cpp" /* yacc.c:355 */ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_CONST = 3, /* CONST */ + YYSYMBOL_BOOL = 4, /* BOOL */ + YYSYMBOL_INT = 5, /* INT */ + YYSYMBOL_UINT = 6, /* UINT */ + YYSYMBOL_FLOAT = 7, /* FLOAT */ + YYSYMBOL_BVEC2 = 8, /* BVEC2 */ + YYSYMBOL_BVEC3 = 9, /* BVEC3 */ + YYSYMBOL_BVEC4 = 10, /* BVEC4 */ + YYSYMBOL_IVEC2 = 11, /* IVEC2 */ + YYSYMBOL_IVEC3 = 12, /* IVEC3 */ + YYSYMBOL_IVEC4 = 13, /* IVEC4 */ + YYSYMBOL_UVEC2 = 14, /* UVEC2 */ + YYSYMBOL_UVEC3 = 15, /* UVEC3 */ + YYSYMBOL_UVEC4 = 16, /* UVEC4 */ + YYSYMBOL_VEC2 = 17, /* VEC2 */ + YYSYMBOL_VEC3 = 18, /* VEC3 */ + YYSYMBOL_VEC4 = 19, /* VEC4 */ + YYSYMBOL_MAT2 = 20, /* MAT2 */ + YYSYMBOL_MAT3 = 21, /* MAT3 */ + YYSYMBOL_MAT4 = 22, /* MAT4 */ + YYSYMBOL_MAT2X2 = 23, /* MAT2X2 */ + YYSYMBOL_MAT2X3 = 24, /* MAT2X3 */ + YYSYMBOL_MAT2X4 = 25, /* MAT2X4 */ + YYSYMBOL_MAT3X2 = 26, /* MAT3X2 */ + YYSYMBOL_MAT3X3 = 27, /* MAT3X3 */ + YYSYMBOL_MAT3X4 = 28, /* MAT3X4 */ + YYSYMBOL_MAT4X2 = 29, /* MAT4X2 */ + YYSYMBOL_MAT4X3 = 30, /* MAT4X3 */ + YYSYMBOL_MAT4X4 = 31, /* MAT4X4 */ + YYSYMBOL_SAMPLER2D = 32, /* SAMPLER2D */ + YYSYMBOL_SAMPLER3D = 33, /* SAMPLER3D */ + YYSYMBOL_SAMPLERCUBE = 34, /* SAMPLERCUBE */ + YYSYMBOL_SAMPLER2DSHADOW = 35, /* SAMPLER2DSHADOW */ + YYSYMBOL_SAMPLERCUBESHADOW = 36, /* SAMPLERCUBESHADOW */ + YYSYMBOL_SAMPLER2DARRAY = 37, /* SAMPLER2DARRAY */ + YYSYMBOL_SAMPLER2DARRAYSHADOW = 38, /* SAMPLER2DARRAYSHADOW */ + YYSYMBOL_ISAMPLER2D = 39, /* ISAMPLER2D */ + YYSYMBOL_ISAMPLER3D = 40, /* ISAMPLER3D */ + YYSYMBOL_ISAMPLERCUBE = 41, /* ISAMPLERCUBE */ + YYSYMBOL_ISAMPLER2DARRAY = 42, /* ISAMPLER2DARRAY */ + YYSYMBOL_USAMPLER2D = 43, /* USAMPLER2D */ + YYSYMBOL_USAMPLER3D = 44, /* USAMPLER3D */ + YYSYMBOL_USAMPLERCUBE = 45, /* USAMPLERCUBE */ + YYSYMBOL_USAMPLER2DARRAY = 46, /* USAMPLER2DARRAY */ + YYSYMBOL_SAMPLER = 47, /* SAMPLER */ + YYSYMBOL_SAMPLERSHADOW = 48, /* SAMPLERSHADOW */ + YYSYMBOL_TEXTURE2D = 49, /* TEXTURE2D */ + YYSYMBOL_TEXTURE3D = 50, /* TEXTURE3D */ + YYSYMBOL_TEXTURECUBE = 51, /* TEXTURECUBE */ + YYSYMBOL_TEXTURE2DARRAY = 52, /* TEXTURE2DARRAY */ + YYSYMBOL_ITEXTURE2D = 53, /* ITEXTURE2D */ + YYSYMBOL_ITEXTURE3D = 54, /* ITEXTURE3D */ + YYSYMBOL_ITEXTURECUBE = 55, /* ITEXTURECUBE */ + YYSYMBOL_ITEXTURE2DARRAY = 56, /* ITEXTURE2DARRAY */ + YYSYMBOL_UTEXTURE2D = 57, /* UTEXTURE2D */ + YYSYMBOL_UTEXTURE3D = 58, /* UTEXTURE3D */ + YYSYMBOL_UTEXTURECUBE = 59, /* UTEXTURECUBE */ + YYSYMBOL_UTEXTURE2DARRAY = 60, /* UTEXTURE2DARRAY */ + YYSYMBOL_ATTRIBUTE = 61, /* ATTRIBUTE */ + YYSYMBOL_VARYING = 62, /* VARYING */ + YYSYMBOL_FLOAT16_T = 63, /* FLOAT16_T */ + YYSYMBOL_FLOAT32_T = 64, /* FLOAT32_T */ + YYSYMBOL_DOUBLE = 65, /* DOUBLE */ + YYSYMBOL_FLOAT64_T = 66, /* FLOAT64_T */ + YYSYMBOL_INT64_T = 67, /* INT64_T */ + YYSYMBOL_UINT64_T = 68, /* UINT64_T */ + YYSYMBOL_INT32_T = 69, /* INT32_T */ + YYSYMBOL_UINT32_T = 70, /* UINT32_T */ + YYSYMBOL_INT16_T = 71, /* INT16_T */ + YYSYMBOL_UINT16_T = 72, /* UINT16_T */ + YYSYMBOL_INT8_T = 73, /* INT8_T */ + YYSYMBOL_UINT8_T = 74, /* UINT8_T */ + YYSYMBOL_I64VEC2 = 75, /* I64VEC2 */ + YYSYMBOL_I64VEC3 = 76, /* I64VEC3 */ + YYSYMBOL_I64VEC4 = 77, /* I64VEC4 */ + YYSYMBOL_U64VEC2 = 78, /* U64VEC2 */ + YYSYMBOL_U64VEC3 = 79, /* U64VEC3 */ + YYSYMBOL_U64VEC4 = 80, /* U64VEC4 */ + YYSYMBOL_I32VEC2 = 81, /* I32VEC2 */ + YYSYMBOL_I32VEC3 = 82, /* I32VEC3 */ + YYSYMBOL_I32VEC4 = 83, /* I32VEC4 */ + YYSYMBOL_U32VEC2 = 84, /* U32VEC2 */ + YYSYMBOL_U32VEC3 = 85, /* U32VEC3 */ + YYSYMBOL_U32VEC4 = 86, /* U32VEC4 */ + YYSYMBOL_I16VEC2 = 87, /* I16VEC2 */ + YYSYMBOL_I16VEC3 = 88, /* I16VEC3 */ + YYSYMBOL_I16VEC4 = 89, /* I16VEC4 */ + YYSYMBOL_U16VEC2 = 90, /* U16VEC2 */ + YYSYMBOL_U16VEC3 = 91, /* U16VEC3 */ + YYSYMBOL_U16VEC4 = 92, /* U16VEC4 */ + YYSYMBOL_I8VEC2 = 93, /* I8VEC2 */ + YYSYMBOL_I8VEC3 = 94, /* I8VEC3 */ + YYSYMBOL_I8VEC4 = 95, /* I8VEC4 */ + YYSYMBOL_U8VEC2 = 96, /* U8VEC2 */ + YYSYMBOL_U8VEC3 = 97, /* U8VEC3 */ + YYSYMBOL_U8VEC4 = 98, /* U8VEC4 */ + YYSYMBOL_DVEC2 = 99, /* DVEC2 */ + YYSYMBOL_DVEC3 = 100, /* DVEC3 */ + YYSYMBOL_DVEC4 = 101, /* DVEC4 */ + YYSYMBOL_DMAT2 = 102, /* DMAT2 */ + YYSYMBOL_DMAT3 = 103, /* DMAT3 */ + YYSYMBOL_DMAT4 = 104, /* DMAT4 */ + YYSYMBOL_F16VEC2 = 105, /* F16VEC2 */ + YYSYMBOL_F16VEC3 = 106, /* F16VEC3 */ + YYSYMBOL_F16VEC4 = 107, /* F16VEC4 */ + YYSYMBOL_F16MAT2 = 108, /* F16MAT2 */ + YYSYMBOL_F16MAT3 = 109, /* F16MAT3 */ + YYSYMBOL_F16MAT4 = 110, /* F16MAT4 */ + YYSYMBOL_F32VEC2 = 111, /* F32VEC2 */ + YYSYMBOL_F32VEC3 = 112, /* F32VEC3 */ + YYSYMBOL_F32VEC4 = 113, /* F32VEC4 */ + YYSYMBOL_F32MAT2 = 114, /* F32MAT2 */ + YYSYMBOL_F32MAT3 = 115, /* F32MAT3 */ + YYSYMBOL_F32MAT4 = 116, /* F32MAT4 */ + YYSYMBOL_F64VEC2 = 117, /* F64VEC2 */ + YYSYMBOL_F64VEC3 = 118, /* F64VEC3 */ + YYSYMBOL_F64VEC4 = 119, /* F64VEC4 */ + YYSYMBOL_F64MAT2 = 120, /* F64MAT2 */ + YYSYMBOL_F64MAT3 = 121, /* F64MAT3 */ + YYSYMBOL_F64MAT4 = 122, /* F64MAT4 */ + YYSYMBOL_DMAT2X2 = 123, /* DMAT2X2 */ + YYSYMBOL_DMAT2X3 = 124, /* DMAT2X3 */ + YYSYMBOL_DMAT2X4 = 125, /* DMAT2X4 */ + YYSYMBOL_DMAT3X2 = 126, /* DMAT3X2 */ + YYSYMBOL_DMAT3X3 = 127, /* DMAT3X3 */ + YYSYMBOL_DMAT3X4 = 128, /* DMAT3X4 */ + YYSYMBOL_DMAT4X2 = 129, /* DMAT4X2 */ + YYSYMBOL_DMAT4X3 = 130, /* DMAT4X3 */ + YYSYMBOL_DMAT4X4 = 131, /* DMAT4X4 */ + YYSYMBOL_F16MAT2X2 = 132, /* F16MAT2X2 */ + YYSYMBOL_F16MAT2X3 = 133, /* F16MAT2X3 */ + YYSYMBOL_F16MAT2X4 = 134, /* F16MAT2X4 */ + YYSYMBOL_F16MAT3X2 = 135, /* F16MAT3X2 */ + YYSYMBOL_F16MAT3X3 = 136, /* F16MAT3X3 */ + YYSYMBOL_F16MAT3X4 = 137, /* F16MAT3X4 */ + YYSYMBOL_F16MAT4X2 = 138, /* F16MAT4X2 */ + YYSYMBOL_F16MAT4X3 = 139, /* F16MAT4X3 */ + YYSYMBOL_F16MAT4X4 = 140, /* F16MAT4X4 */ + YYSYMBOL_F32MAT2X2 = 141, /* F32MAT2X2 */ + YYSYMBOL_F32MAT2X3 = 142, /* F32MAT2X3 */ + YYSYMBOL_F32MAT2X4 = 143, /* F32MAT2X4 */ + YYSYMBOL_F32MAT3X2 = 144, /* F32MAT3X2 */ + YYSYMBOL_F32MAT3X3 = 145, /* F32MAT3X3 */ + YYSYMBOL_F32MAT3X4 = 146, /* F32MAT3X4 */ + YYSYMBOL_F32MAT4X2 = 147, /* F32MAT4X2 */ + YYSYMBOL_F32MAT4X3 = 148, /* F32MAT4X3 */ + YYSYMBOL_F32MAT4X4 = 149, /* F32MAT4X4 */ + YYSYMBOL_F64MAT2X2 = 150, /* F64MAT2X2 */ + YYSYMBOL_F64MAT2X3 = 151, /* F64MAT2X3 */ + YYSYMBOL_F64MAT2X4 = 152, /* F64MAT2X4 */ + YYSYMBOL_F64MAT3X2 = 153, /* F64MAT3X2 */ + YYSYMBOL_F64MAT3X3 = 154, /* F64MAT3X3 */ + YYSYMBOL_F64MAT3X4 = 155, /* F64MAT3X4 */ + YYSYMBOL_F64MAT4X2 = 156, /* F64MAT4X2 */ + YYSYMBOL_F64MAT4X3 = 157, /* F64MAT4X3 */ + YYSYMBOL_F64MAT4X4 = 158, /* F64MAT4X4 */ + YYSYMBOL_ATOMIC_UINT = 159, /* ATOMIC_UINT */ + YYSYMBOL_ACCSTRUCTNV = 160, /* ACCSTRUCTNV */ + YYSYMBOL_ACCSTRUCTEXT = 161, /* ACCSTRUCTEXT */ + YYSYMBOL_RAYQUERYEXT = 162, /* RAYQUERYEXT */ + YYSYMBOL_FCOOPMATNV = 163, /* FCOOPMATNV */ + YYSYMBOL_ICOOPMATNV = 164, /* ICOOPMATNV */ + YYSYMBOL_UCOOPMATNV = 165, /* UCOOPMATNV */ + YYSYMBOL_SAMPLERCUBEARRAY = 166, /* SAMPLERCUBEARRAY */ + YYSYMBOL_SAMPLERCUBEARRAYSHADOW = 167, /* SAMPLERCUBEARRAYSHADOW */ + YYSYMBOL_ISAMPLERCUBEARRAY = 168, /* ISAMPLERCUBEARRAY */ + YYSYMBOL_USAMPLERCUBEARRAY = 169, /* USAMPLERCUBEARRAY */ + YYSYMBOL_SAMPLER1D = 170, /* SAMPLER1D */ + YYSYMBOL_SAMPLER1DARRAY = 171, /* SAMPLER1DARRAY */ + YYSYMBOL_SAMPLER1DARRAYSHADOW = 172, /* SAMPLER1DARRAYSHADOW */ + YYSYMBOL_ISAMPLER1D = 173, /* ISAMPLER1D */ + YYSYMBOL_SAMPLER1DSHADOW = 174, /* SAMPLER1DSHADOW */ + YYSYMBOL_SAMPLER2DRECT = 175, /* SAMPLER2DRECT */ + YYSYMBOL_SAMPLER2DRECTSHADOW = 176, /* SAMPLER2DRECTSHADOW */ + YYSYMBOL_ISAMPLER2DRECT = 177, /* ISAMPLER2DRECT */ + YYSYMBOL_USAMPLER2DRECT = 178, /* USAMPLER2DRECT */ + YYSYMBOL_SAMPLERBUFFER = 179, /* SAMPLERBUFFER */ + YYSYMBOL_ISAMPLERBUFFER = 180, /* ISAMPLERBUFFER */ + YYSYMBOL_USAMPLERBUFFER = 181, /* USAMPLERBUFFER */ + YYSYMBOL_SAMPLER2DMS = 182, /* SAMPLER2DMS */ + YYSYMBOL_ISAMPLER2DMS = 183, /* ISAMPLER2DMS */ + YYSYMBOL_USAMPLER2DMS = 184, /* USAMPLER2DMS */ + YYSYMBOL_SAMPLER2DMSARRAY = 185, /* SAMPLER2DMSARRAY */ + YYSYMBOL_ISAMPLER2DMSARRAY = 186, /* ISAMPLER2DMSARRAY */ + YYSYMBOL_USAMPLER2DMSARRAY = 187, /* USAMPLER2DMSARRAY */ + YYSYMBOL_SAMPLEREXTERNALOES = 188, /* SAMPLEREXTERNALOES */ + YYSYMBOL_SAMPLEREXTERNAL2DY2YEXT = 189, /* SAMPLEREXTERNAL2DY2YEXT */ + YYSYMBOL_ISAMPLER1DARRAY = 190, /* ISAMPLER1DARRAY */ + YYSYMBOL_USAMPLER1D = 191, /* USAMPLER1D */ + YYSYMBOL_USAMPLER1DARRAY = 192, /* USAMPLER1DARRAY */ + YYSYMBOL_F16SAMPLER1D = 193, /* F16SAMPLER1D */ + YYSYMBOL_F16SAMPLER2D = 194, /* F16SAMPLER2D */ + YYSYMBOL_F16SAMPLER3D = 195, /* F16SAMPLER3D */ + YYSYMBOL_F16SAMPLER2DRECT = 196, /* F16SAMPLER2DRECT */ + YYSYMBOL_F16SAMPLERCUBE = 197, /* F16SAMPLERCUBE */ + YYSYMBOL_F16SAMPLER1DARRAY = 198, /* F16SAMPLER1DARRAY */ + YYSYMBOL_F16SAMPLER2DARRAY = 199, /* F16SAMPLER2DARRAY */ + YYSYMBOL_F16SAMPLERCUBEARRAY = 200, /* F16SAMPLERCUBEARRAY */ + YYSYMBOL_F16SAMPLERBUFFER = 201, /* F16SAMPLERBUFFER */ + YYSYMBOL_F16SAMPLER2DMS = 202, /* F16SAMPLER2DMS */ + YYSYMBOL_F16SAMPLER2DMSARRAY = 203, /* F16SAMPLER2DMSARRAY */ + YYSYMBOL_F16SAMPLER1DSHADOW = 204, /* F16SAMPLER1DSHADOW */ + YYSYMBOL_F16SAMPLER2DSHADOW = 205, /* F16SAMPLER2DSHADOW */ + YYSYMBOL_F16SAMPLER1DARRAYSHADOW = 206, /* F16SAMPLER1DARRAYSHADOW */ + YYSYMBOL_F16SAMPLER2DARRAYSHADOW = 207, /* F16SAMPLER2DARRAYSHADOW */ + YYSYMBOL_F16SAMPLER2DRECTSHADOW = 208, /* F16SAMPLER2DRECTSHADOW */ + YYSYMBOL_F16SAMPLERCUBESHADOW = 209, /* F16SAMPLERCUBESHADOW */ + YYSYMBOL_F16SAMPLERCUBEARRAYSHADOW = 210, /* F16SAMPLERCUBEARRAYSHADOW */ + YYSYMBOL_IMAGE1D = 211, /* IMAGE1D */ + YYSYMBOL_IIMAGE1D = 212, /* IIMAGE1D */ + YYSYMBOL_UIMAGE1D = 213, /* UIMAGE1D */ + YYSYMBOL_IMAGE2D = 214, /* IMAGE2D */ + YYSYMBOL_IIMAGE2D = 215, /* IIMAGE2D */ + YYSYMBOL_UIMAGE2D = 216, /* UIMAGE2D */ + YYSYMBOL_IMAGE3D = 217, /* IMAGE3D */ + YYSYMBOL_IIMAGE3D = 218, /* IIMAGE3D */ + YYSYMBOL_UIMAGE3D = 219, /* UIMAGE3D */ + YYSYMBOL_IMAGE2DRECT = 220, /* IMAGE2DRECT */ + YYSYMBOL_IIMAGE2DRECT = 221, /* IIMAGE2DRECT */ + YYSYMBOL_UIMAGE2DRECT = 222, /* UIMAGE2DRECT */ + YYSYMBOL_IMAGECUBE = 223, /* IMAGECUBE */ + YYSYMBOL_IIMAGECUBE = 224, /* IIMAGECUBE */ + YYSYMBOL_UIMAGECUBE = 225, /* UIMAGECUBE */ + YYSYMBOL_IMAGEBUFFER = 226, /* IMAGEBUFFER */ + YYSYMBOL_IIMAGEBUFFER = 227, /* IIMAGEBUFFER */ + YYSYMBOL_UIMAGEBUFFER = 228, /* UIMAGEBUFFER */ + YYSYMBOL_IMAGE1DARRAY = 229, /* IMAGE1DARRAY */ + YYSYMBOL_IIMAGE1DARRAY = 230, /* IIMAGE1DARRAY */ + YYSYMBOL_UIMAGE1DARRAY = 231, /* UIMAGE1DARRAY */ + YYSYMBOL_IMAGE2DARRAY = 232, /* IMAGE2DARRAY */ + YYSYMBOL_IIMAGE2DARRAY = 233, /* IIMAGE2DARRAY */ + YYSYMBOL_UIMAGE2DARRAY = 234, /* UIMAGE2DARRAY */ + YYSYMBOL_IMAGECUBEARRAY = 235, /* IMAGECUBEARRAY */ + YYSYMBOL_IIMAGECUBEARRAY = 236, /* IIMAGECUBEARRAY */ + YYSYMBOL_UIMAGECUBEARRAY = 237, /* UIMAGECUBEARRAY */ + YYSYMBOL_IMAGE2DMS = 238, /* IMAGE2DMS */ + YYSYMBOL_IIMAGE2DMS = 239, /* IIMAGE2DMS */ + YYSYMBOL_UIMAGE2DMS = 240, /* UIMAGE2DMS */ + YYSYMBOL_IMAGE2DMSARRAY = 241, /* IMAGE2DMSARRAY */ + YYSYMBOL_IIMAGE2DMSARRAY = 242, /* IIMAGE2DMSARRAY */ + YYSYMBOL_UIMAGE2DMSARRAY = 243, /* UIMAGE2DMSARRAY */ + YYSYMBOL_F16IMAGE1D = 244, /* F16IMAGE1D */ + YYSYMBOL_F16IMAGE2D = 245, /* F16IMAGE2D */ + YYSYMBOL_F16IMAGE3D = 246, /* F16IMAGE3D */ + YYSYMBOL_F16IMAGE2DRECT = 247, /* F16IMAGE2DRECT */ + YYSYMBOL_F16IMAGECUBE = 248, /* F16IMAGECUBE */ + YYSYMBOL_F16IMAGE1DARRAY = 249, /* F16IMAGE1DARRAY */ + YYSYMBOL_F16IMAGE2DARRAY = 250, /* F16IMAGE2DARRAY */ + YYSYMBOL_F16IMAGECUBEARRAY = 251, /* F16IMAGECUBEARRAY */ + YYSYMBOL_F16IMAGEBUFFER = 252, /* F16IMAGEBUFFER */ + YYSYMBOL_F16IMAGE2DMS = 253, /* F16IMAGE2DMS */ + YYSYMBOL_F16IMAGE2DMSARRAY = 254, /* F16IMAGE2DMSARRAY */ + YYSYMBOL_I64IMAGE1D = 255, /* I64IMAGE1D */ + YYSYMBOL_U64IMAGE1D = 256, /* U64IMAGE1D */ + YYSYMBOL_I64IMAGE2D = 257, /* I64IMAGE2D */ + YYSYMBOL_U64IMAGE2D = 258, /* U64IMAGE2D */ + YYSYMBOL_I64IMAGE3D = 259, /* I64IMAGE3D */ + YYSYMBOL_U64IMAGE3D = 260, /* U64IMAGE3D */ + YYSYMBOL_I64IMAGE2DRECT = 261, /* I64IMAGE2DRECT */ + YYSYMBOL_U64IMAGE2DRECT = 262, /* U64IMAGE2DRECT */ + YYSYMBOL_I64IMAGECUBE = 263, /* I64IMAGECUBE */ + YYSYMBOL_U64IMAGECUBE = 264, /* U64IMAGECUBE */ + YYSYMBOL_I64IMAGEBUFFER = 265, /* I64IMAGEBUFFER */ + YYSYMBOL_U64IMAGEBUFFER = 266, /* U64IMAGEBUFFER */ + YYSYMBOL_I64IMAGE1DARRAY = 267, /* I64IMAGE1DARRAY */ + YYSYMBOL_U64IMAGE1DARRAY = 268, /* U64IMAGE1DARRAY */ + YYSYMBOL_I64IMAGE2DARRAY = 269, /* I64IMAGE2DARRAY */ + YYSYMBOL_U64IMAGE2DARRAY = 270, /* U64IMAGE2DARRAY */ + YYSYMBOL_I64IMAGECUBEARRAY = 271, /* I64IMAGECUBEARRAY */ + YYSYMBOL_U64IMAGECUBEARRAY = 272, /* U64IMAGECUBEARRAY */ + YYSYMBOL_I64IMAGE2DMS = 273, /* I64IMAGE2DMS */ + YYSYMBOL_U64IMAGE2DMS = 274, /* U64IMAGE2DMS */ + YYSYMBOL_I64IMAGE2DMSARRAY = 275, /* I64IMAGE2DMSARRAY */ + YYSYMBOL_U64IMAGE2DMSARRAY = 276, /* U64IMAGE2DMSARRAY */ + YYSYMBOL_TEXTURECUBEARRAY = 277, /* TEXTURECUBEARRAY */ + YYSYMBOL_ITEXTURECUBEARRAY = 278, /* ITEXTURECUBEARRAY */ + YYSYMBOL_UTEXTURECUBEARRAY = 279, /* UTEXTURECUBEARRAY */ + YYSYMBOL_TEXTURE1D = 280, /* TEXTURE1D */ + YYSYMBOL_ITEXTURE1D = 281, /* ITEXTURE1D */ + YYSYMBOL_UTEXTURE1D = 282, /* UTEXTURE1D */ + YYSYMBOL_TEXTURE1DARRAY = 283, /* TEXTURE1DARRAY */ + YYSYMBOL_ITEXTURE1DARRAY = 284, /* ITEXTURE1DARRAY */ + YYSYMBOL_UTEXTURE1DARRAY = 285, /* UTEXTURE1DARRAY */ + YYSYMBOL_TEXTURE2DRECT = 286, /* TEXTURE2DRECT */ + YYSYMBOL_ITEXTURE2DRECT = 287, /* ITEXTURE2DRECT */ + YYSYMBOL_UTEXTURE2DRECT = 288, /* UTEXTURE2DRECT */ + YYSYMBOL_TEXTUREBUFFER = 289, /* TEXTUREBUFFER */ + YYSYMBOL_ITEXTUREBUFFER = 290, /* ITEXTUREBUFFER */ + YYSYMBOL_UTEXTUREBUFFER = 291, /* UTEXTUREBUFFER */ + YYSYMBOL_TEXTURE2DMS = 292, /* TEXTURE2DMS */ + YYSYMBOL_ITEXTURE2DMS = 293, /* ITEXTURE2DMS */ + YYSYMBOL_UTEXTURE2DMS = 294, /* UTEXTURE2DMS */ + YYSYMBOL_TEXTURE2DMSARRAY = 295, /* TEXTURE2DMSARRAY */ + YYSYMBOL_ITEXTURE2DMSARRAY = 296, /* ITEXTURE2DMSARRAY */ + YYSYMBOL_UTEXTURE2DMSARRAY = 297, /* UTEXTURE2DMSARRAY */ + YYSYMBOL_F16TEXTURE1D = 298, /* F16TEXTURE1D */ + YYSYMBOL_F16TEXTURE2D = 299, /* F16TEXTURE2D */ + YYSYMBOL_F16TEXTURE3D = 300, /* F16TEXTURE3D */ + YYSYMBOL_F16TEXTURE2DRECT = 301, /* F16TEXTURE2DRECT */ + YYSYMBOL_F16TEXTURECUBE = 302, /* F16TEXTURECUBE */ + YYSYMBOL_F16TEXTURE1DARRAY = 303, /* F16TEXTURE1DARRAY */ + YYSYMBOL_F16TEXTURE2DARRAY = 304, /* F16TEXTURE2DARRAY */ + YYSYMBOL_F16TEXTURECUBEARRAY = 305, /* F16TEXTURECUBEARRAY */ + YYSYMBOL_F16TEXTUREBUFFER = 306, /* F16TEXTUREBUFFER */ + YYSYMBOL_F16TEXTURE2DMS = 307, /* F16TEXTURE2DMS */ + YYSYMBOL_F16TEXTURE2DMSARRAY = 308, /* F16TEXTURE2DMSARRAY */ + YYSYMBOL_SUBPASSINPUT = 309, /* SUBPASSINPUT */ + YYSYMBOL_SUBPASSINPUTMS = 310, /* SUBPASSINPUTMS */ + YYSYMBOL_ISUBPASSINPUT = 311, /* ISUBPASSINPUT */ + YYSYMBOL_ISUBPASSINPUTMS = 312, /* ISUBPASSINPUTMS */ + YYSYMBOL_USUBPASSINPUT = 313, /* USUBPASSINPUT */ + YYSYMBOL_USUBPASSINPUTMS = 314, /* USUBPASSINPUTMS */ + YYSYMBOL_F16SUBPASSINPUT = 315, /* F16SUBPASSINPUT */ + YYSYMBOL_F16SUBPASSINPUTMS = 316, /* F16SUBPASSINPUTMS */ + YYSYMBOL_SPIRV_INSTRUCTION = 317, /* SPIRV_INSTRUCTION */ + YYSYMBOL_SPIRV_EXECUTION_MODE = 318, /* SPIRV_EXECUTION_MODE */ + YYSYMBOL_SPIRV_EXECUTION_MODE_ID = 319, /* SPIRV_EXECUTION_MODE_ID */ + YYSYMBOL_SPIRV_DECORATE = 320, /* SPIRV_DECORATE */ + YYSYMBOL_SPIRV_DECORATE_ID = 321, /* SPIRV_DECORATE_ID */ + YYSYMBOL_SPIRV_DECORATE_STRING = 322, /* SPIRV_DECORATE_STRING */ + YYSYMBOL_SPIRV_TYPE = 323, /* SPIRV_TYPE */ + YYSYMBOL_SPIRV_STORAGE_CLASS = 324, /* SPIRV_STORAGE_CLASS */ + YYSYMBOL_SPIRV_BY_REFERENCE = 325, /* SPIRV_BY_REFERENCE */ + YYSYMBOL_SPIRV_LITERAL = 326, /* SPIRV_LITERAL */ + YYSYMBOL_LEFT_OP = 327, /* LEFT_OP */ + YYSYMBOL_RIGHT_OP = 328, /* RIGHT_OP */ + YYSYMBOL_INC_OP = 329, /* INC_OP */ + YYSYMBOL_DEC_OP = 330, /* DEC_OP */ + YYSYMBOL_LE_OP = 331, /* LE_OP */ + YYSYMBOL_GE_OP = 332, /* GE_OP */ + YYSYMBOL_EQ_OP = 333, /* EQ_OP */ + YYSYMBOL_NE_OP = 334, /* NE_OP */ + YYSYMBOL_AND_OP = 335, /* AND_OP */ + YYSYMBOL_OR_OP = 336, /* OR_OP */ + YYSYMBOL_XOR_OP = 337, /* XOR_OP */ + YYSYMBOL_MUL_ASSIGN = 338, /* MUL_ASSIGN */ + YYSYMBOL_DIV_ASSIGN = 339, /* DIV_ASSIGN */ + YYSYMBOL_ADD_ASSIGN = 340, /* ADD_ASSIGN */ + YYSYMBOL_MOD_ASSIGN = 341, /* MOD_ASSIGN */ + YYSYMBOL_LEFT_ASSIGN = 342, /* LEFT_ASSIGN */ + YYSYMBOL_RIGHT_ASSIGN = 343, /* RIGHT_ASSIGN */ + YYSYMBOL_AND_ASSIGN = 344, /* AND_ASSIGN */ + YYSYMBOL_XOR_ASSIGN = 345, /* XOR_ASSIGN */ + YYSYMBOL_OR_ASSIGN = 346, /* OR_ASSIGN */ + YYSYMBOL_SUB_ASSIGN = 347, /* SUB_ASSIGN */ + YYSYMBOL_STRING_LITERAL = 348, /* STRING_LITERAL */ + YYSYMBOL_LEFT_PAREN = 349, /* LEFT_PAREN */ + YYSYMBOL_RIGHT_PAREN = 350, /* RIGHT_PAREN */ + YYSYMBOL_LEFT_BRACKET = 351, /* LEFT_BRACKET */ + YYSYMBOL_RIGHT_BRACKET = 352, /* RIGHT_BRACKET */ + YYSYMBOL_LEFT_BRACE = 353, /* LEFT_BRACE */ + YYSYMBOL_RIGHT_BRACE = 354, /* RIGHT_BRACE */ + YYSYMBOL_DOT = 355, /* DOT */ + YYSYMBOL_COMMA = 356, /* COMMA */ + YYSYMBOL_COLON = 357, /* COLON */ + YYSYMBOL_EQUAL = 358, /* EQUAL */ + YYSYMBOL_SEMICOLON = 359, /* SEMICOLON */ + YYSYMBOL_BANG = 360, /* BANG */ + YYSYMBOL_DASH = 361, /* DASH */ + YYSYMBOL_TILDE = 362, /* TILDE */ + YYSYMBOL_PLUS = 363, /* PLUS */ + YYSYMBOL_STAR = 364, /* STAR */ + YYSYMBOL_SLASH = 365, /* SLASH */ + YYSYMBOL_PERCENT = 366, /* PERCENT */ + YYSYMBOL_LEFT_ANGLE = 367, /* LEFT_ANGLE */ + YYSYMBOL_RIGHT_ANGLE = 368, /* RIGHT_ANGLE */ + YYSYMBOL_VERTICAL_BAR = 369, /* VERTICAL_BAR */ + YYSYMBOL_CARET = 370, /* CARET */ + YYSYMBOL_AMPERSAND = 371, /* AMPERSAND */ + YYSYMBOL_QUESTION = 372, /* QUESTION */ + YYSYMBOL_INVARIANT = 373, /* INVARIANT */ + YYSYMBOL_HIGH_PRECISION = 374, /* HIGH_PRECISION */ + YYSYMBOL_MEDIUM_PRECISION = 375, /* MEDIUM_PRECISION */ + YYSYMBOL_LOW_PRECISION = 376, /* LOW_PRECISION */ + YYSYMBOL_PRECISION = 377, /* PRECISION */ + YYSYMBOL_PACKED = 378, /* PACKED */ + YYSYMBOL_RESOURCE = 379, /* RESOURCE */ + YYSYMBOL_SUPERP = 380, /* SUPERP */ + YYSYMBOL_FLOATCONSTANT = 381, /* FLOATCONSTANT */ + YYSYMBOL_INTCONSTANT = 382, /* INTCONSTANT */ + YYSYMBOL_UINTCONSTANT = 383, /* UINTCONSTANT */ + YYSYMBOL_BOOLCONSTANT = 384, /* BOOLCONSTANT */ + YYSYMBOL_IDENTIFIER = 385, /* IDENTIFIER */ + YYSYMBOL_TYPE_NAME = 386, /* TYPE_NAME */ + YYSYMBOL_CENTROID = 387, /* CENTROID */ + YYSYMBOL_IN = 388, /* IN */ + YYSYMBOL_OUT = 389, /* OUT */ + YYSYMBOL_INOUT = 390, /* INOUT */ + YYSYMBOL_STRUCT = 391, /* STRUCT */ + YYSYMBOL_VOID = 392, /* VOID */ + YYSYMBOL_WHILE = 393, /* WHILE */ + YYSYMBOL_BREAK = 394, /* BREAK */ + YYSYMBOL_CONTINUE = 395, /* CONTINUE */ + YYSYMBOL_DO = 396, /* DO */ + YYSYMBOL_ELSE = 397, /* ELSE */ + YYSYMBOL_FOR = 398, /* FOR */ + YYSYMBOL_IF = 399, /* IF */ + YYSYMBOL_DISCARD = 400, /* DISCARD */ + YYSYMBOL_RETURN = 401, /* RETURN */ + YYSYMBOL_SWITCH = 402, /* SWITCH */ + YYSYMBOL_CASE = 403, /* CASE */ + YYSYMBOL_DEFAULT = 404, /* DEFAULT */ + YYSYMBOL_TERMINATE_INVOCATION = 405, /* TERMINATE_INVOCATION */ + YYSYMBOL_TERMINATE_RAY = 406, /* TERMINATE_RAY */ + YYSYMBOL_IGNORE_INTERSECTION = 407, /* IGNORE_INTERSECTION */ + YYSYMBOL_UNIFORM = 408, /* UNIFORM */ + YYSYMBOL_SHARED = 409, /* SHARED */ + YYSYMBOL_BUFFER = 410, /* BUFFER */ + YYSYMBOL_FLAT = 411, /* FLAT */ + YYSYMBOL_SMOOTH = 412, /* SMOOTH */ + YYSYMBOL_LAYOUT = 413, /* LAYOUT */ + YYSYMBOL_DOUBLECONSTANT = 414, /* DOUBLECONSTANT */ + YYSYMBOL_INT16CONSTANT = 415, /* INT16CONSTANT */ + YYSYMBOL_UINT16CONSTANT = 416, /* UINT16CONSTANT */ + YYSYMBOL_FLOAT16CONSTANT = 417, /* FLOAT16CONSTANT */ + YYSYMBOL_INT32CONSTANT = 418, /* INT32CONSTANT */ + YYSYMBOL_UINT32CONSTANT = 419, /* UINT32CONSTANT */ + YYSYMBOL_INT64CONSTANT = 420, /* INT64CONSTANT */ + YYSYMBOL_UINT64CONSTANT = 421, /* UINT64CONSTANT */ + YYSYMBOL_SUBROUTINE = 422, /* SUBROUTINE */ + YYSYMBOL_DEMOTE = 423, /* DEMOTE */ + YYSYMBOL_PAYLOADNV = 424, /* PAYLOADNV */ + YYSYMBOL_PAYLOADINNV = 425, /* PAYLOADINNV */ + YYSYMBOL_HITATTRNV = 426, /* HITATTRNV */ + YYSYMBOL_CALLDATANV = 427, /* CALLDATANV */ + YYSYMBOL_CALLDATAINNV = 428, /* CALLDATAINNV */ + YYSYMBOL_PAYLOADEXT = 429, /* PAYLOADEXT */ + YYSYMBOL_PAYLOADINEXT = 430, /* PAYLOADINEXT */ + YYSYMBOL_HITATTREXT = 431, /* HITATTREXT */ + YYSYMBOL_CALLDATAEXT = 432, /* CALLDATAEXT */ + YYSYMBOL_CALLDATAINEXT = 433, /* CALLDATAINEXT */ + YYSYMBOL_PATCH = 434, /* PATCH */ + YYSYMBOL_SAMPLE = 435, /* SAMPLE */ + YYSYMBOL_NONUNIFORM = 436, /* NONUNIFORM */ + YYSYMBOL_COHERENT = 437, /* COHERENT */ + YYSYMBOL_VOLATILE = 438, /* VOLATILE */ + YYSYMBOL_RESTRICT = 439, /* RESTRICT */ + YYSYMBOL_READONLY = 440, /* READONLY */ + YYSYMBOL_WRITEONLY = 441, /* WRITEONLY */ + YYSYMBOL_DEVICECOHERENT = 442, /* DEVICECOHERENT */ + YYSYMBOL_QUEUEFAMILYCOHERENT = 443, /* QUEUEFAMILYCOHERENT */ + YYSYMBOL_WORKGROUPCOHERENT = 444, /* WORKGROUPCOHERENT */ + YYSYMBOL_SUBGROUPCOHERENT = 445, /* SUBGROUPCOHERENT */ + YYSYMBOL_NONPRIVATE = 446, /* NONPRIVATE */ + YYSYMBOL_SHADERCALLCOHERENT = 447, /* SHADERCALLCOHERENT */ + YYSYMBOL_NOPERSPECTIVE = 448, /* NOPERSPECTIVE */ + YYSYMBOL_EXPLICITINTERPAMD = 449, /* EXPLICITINTERPAMD */ + YYSYMBOL_PERVERTEXNV = 450, /* PERVERTEXNV */ + YYSYMBOL_PERPRIMITIVENV = 451, /* PERPRIMITIVENV */ + YYSYMBOL_PERVIEWNV = 452, /* PERVIEWNV */ + YYSYMBOL_PERTASKNV = 453, /* PERTASKNV */ + YYSYMBOL_PRECISE = 454, /* PRECISE */ + YYSYMBOL_YYACCEPT = 455, /* $accept */ + YYSYMBOL_variable_identifier = 456, /* variable_identifier */ + YYSYMBOL_primary_expression = 457, /* primary_expression */ + YYSYMBOL_postfix_expression = 458, /* postfix_expression */ + YYSYMBOL_integer_expression = 459, /* integer_expression */ + YYSYMBOL_function_call = 460, /* function_call */ + YYSYMBOL_function_call_or_method = 461, /* function_call_or_method */ + YYSYMBOL_function_call_generic = 462, /* function_call_generic */ + YYSYMBOL_function_call_header_no_parameters = 463, /* function_call_header_no_parameters */ + YYSYMBOL_function_call_header_with_parameters = 464, /* function_call_header_with_parameters */ + YYSYMBOL_function_call_header = 465, /* function_call_header */ + YYSYMBOL_function_identifier = 466, /* function_identifier */ + YYSYMBOL_unary_expression = 467, /* unary_expression */ + YYSYMBOL_unary_operator = 468, /* unary_operator */ + YYSYMBOL_multiplicative_expression = 469, /* multiplicative_expression */ + YYSYMBOL_additive_expression = 470, /* additive_expression */ + YYSYMBOL_shift_expression = 471, /* shift_expression */ + YYSYMBOL_relational_expression = 472, /* relational_expression */ + YYSYMBOL_equality_expression = 473, /* equality_expression */ + YYSYMBOL_and_expression = 474, /* and_expression */ + YYSYMBOL_exclusive_or_expression = 475, /* exclusive_or_expression */ + YYSYMBOL_inclusive_or_expression = 476, /* inclusive_or_expression */ + YYSYMBOL_logical_and_expression = 477, /* logical_and_expression */ + YYSYMBOL_logical_xor_expression = 478, /* logical_xor_expression */ + YYSYMBOL_logical_or_expression = 479, /* logical_or_expression */ + YYSYMBOL_conditional_expression = 480, /* conditional_expression */ + YYSYMBOL_481_1 = 481, /* $@1 */ + YYSYMBOL_assignment_expression = 482, /* assignment_expression */ + YYSYMBOL_assignment_operator = 483, /* assignment_operator */ + YYSYMBOL_expression = 484, /* expression */ + YYSYMBOL_constant_expression = 485, /* constant_expression */ + YYSYMBOL_declaration = 486, /* declaration */ + YYSYMBOL_block_structure = 487, /* block_structure */ + YYSYMBOL_488_2 = 488, /* $@2 */ + YYSYMBOL_identifier_list = 489, /* identifier_list */ + YYSYMBOL_function_prototype = 490, /* function_prototype */ + YYSYMBOL_function_declarator = 491, /* function_declarator */ + YYSYMBOL_function_header_with_parameters = 492, /* function_header_with_parameters */ + YYSYMBOL_function_header = 493, /* function_header */ + YYSYMBOL_parameter_declarator = 494, /* parameter_declarator */ + YYSYMBOL_parameter_declaration = 495, /* parameter_declaration */ + YYSYMBOL_parameter_type_specifier = 496, /* parameter_type_specifier */ + YYSYMBOL_init_declarator_list = 497, /* init_declarator_list */ + YYSYMBOL_single_declaration = 498, /* single_declaration */ + YYSYMBOL_fully_specified_type = 499, /* fully_specified_type */ + YYSYMBOL_invariant_qualifier = 500, /* invariant_qualifier */ + YYSYMBOL_interpolation_qualifier = 501, /* interpolation_qualifier */ + YYSYMBOL_layout_qualifier = 502, /* layout_qualifier */ + YYSYMBOL_layout_qualifier_id_list = 503, /* layout_qualifier_id_list */ + YYSYMBOL_layout_qualifier_id = 504, /* layout_qualifier_id */ + YYSYMBOL_precise_qualifier = 505, /* precise_qualifier */ + YYSYMBOL_type_qualifier = 506, /* type_qualifier */ + YYSYMBOL_single_type_qualifier = 507, /* single_type_qualifier */ + YYSYMBOL_storage_qualifier = 508, /* storage_qualifier */ + YYSYMBOL_non_uniform_qualifier = 509, /* non_uniform_qualifier */ + YYSYMBOL_type_name_list = 510, /* type_name_list */ + YYSYMBOL_type_specifier = 511, /* type_specifier */ + YYSYMBOL_array_specifier = 512, /* array_specifier */ + YYSYMBOL_type_parameter_specifier_opt = 513, /* type_parameter_specifier_opt */ + YYSYMBOL_type_parameter_specifier = 514, /* type_parameter_specifier */ + YYSYMBOL_type_parameter_specifier_list = 515, /* type_parameter_specifier_list */ + YYSYMBOL_type_specifier_nonarray = 516, /* type_specifier_nonarray */ + YYSYMBOL_precision_qualifier = 517, /* precision_qualifier */ + YYSYMBOL_struct_specifier = 518, /* struct_specifier */ + YYSYMBOL_519_3 = 519, /* $@3 */ + YYSYMBOL_520_4 = 520, /* $@4 */ + YYSYMBOL_struct_declaration_list = 521, /* struct_declaration_list */ + YYSYMBOL_struct_declaration = 522, /* struct_declaration */ + YYSYMBOL_struct_declarator_list = 523, /* struct_declarator_list */ + YYSYMBOL_struct_declarator = 524, /* struct_declarator */ + YYSYMBOL_initializer = 525, /* initializer */ + YYSYMBOL_initializer_list = 526, /* initializer_list */ + YYSYMBOL_declaration_statement = 527, /* declaration_statement */ + YYSYMBOL_statement = 528, /* statement */ + YYSYMBOL_simple_statement = 529, /* simple_statement */ + YYSYMBOL_demote_statement = 530, /* demote_statement */ + YYSYMBOL_compound_statement = 531, /* compound_statement */ + YYSYMBOL_532_5 = 532, /* $@5 */ + YYSYMBOL_533_6 = 533, /* $@6 */ + YYSYMBOL_statement_no_new_scope = 534, /* statement_no_new_scope */ + YYSYMBOL_statement_scoped = 535, /* statement_scoped */ + YYSYMBOL_536_7 = 536, /* $@7 */ + YYSYMBOL_537_8 = 537, /* $@8 */ + YYSYMBOL_compound_statement_no_new_scope = 538, /* compound_statement_no_new_scope */ + YYSYMBOL_statement_list = 539, /* statement_list */ + YYSYMBOL_expression_statement = 540, /* expression_statement */ + YYSYMBOL_selection_statement = 541, /* selection_statement */ + YYSYMBOL_selection_statement_nonattributed = 542, /* selection_statement_nonattributed */ + YYSYMBOL_selection_rest_statement = 543, /* selection_rest_statement */ + YYSYMBOL_condition = 544, /* condition */ + YYSYMBOL_switch_statement = 545, /* switch_statement */ + YYSYMBOL_switch_statement_nonattributed = 546, /* switch_statement_nonattributed */ + YYSYMBOL_547_9 = 547, /* $@9 */ + YYSYMBOL_switch_statement_list = 548, /* switch_statement_list */ + YYSYMBOL_case_label = 549, /* case_label */ + YYSYMBOL_iteration_statement = 550, /* iteration_statement */ + YYSYMBOL_iteration_statement_nonattributed = 551, /* iteration_statement_nonattributed */ + YYSYMBOL_552_10 = 552, /* $@10 */ + YYSYMBOL_553_11 = 553, /* $@11 */ + YYSYMBOL_554_12 = 554, /* $@12 */ + YYSYMBOL_for_init_statement = 555, /* for_init_statement */ + YYSYMBOL_conditionopt = 556, /* conditionopt */ + YYSYMBOL_for_rest_statement = 557, /* for_rest_statement */ + YYSYMBOL_jump_statement = 558, /* jump_statement */ + YYSYMBOL_translation_unit = 559, /* translation_unit */ + YYSYMBOL_external_declaration = 560, /* external_declaration */ + YYSYMBOL_function_definition = 561, /* function_definition */ + YYSYMBOL_562_13 = 562, /* $@13 */ + YYSYMBOL_attribute = 563, /* attribute */ + YYSYMBOL_attribute_list = 564, /* attribute_list */ + YYSYMBOL_single_attribute = 565, /* single_attribute */ + YYSYMBOL_spirv_requirements_list = 566, /* spirv_requirements_list */ + YYSYMBOL_spirv_requirements_parameter = 567, /* spirv_requirements_parameter */ + YYSYMBOL_spirv_extension_list = 568, /* spirv_extension_list */ + YYSYMBOL_spirv_capability_list = 569, /* spirv_capability_list */ + YYSYMBOL_spirv_execution_mode_qualifier = 570, /* spirv_execution_mode_qualifier */ + YYSYMBOL_spirv_execution_mode_parameter_list = 571, /* spirv_execution_mode_parameter_list */ + YYSYMBOL_spirv_execution_mode_parameter = 572, /* spirv_execution_mode_parameter */ + YYSYMBOL_spirv_execution_mode_id_parameter_list = 573, /* spirv_execution_mode_id_parameter_list */ + YYSYMBOL_spirv_storage_class_qualifier = 574, /* spirv_storage_class_qualifier */ + YYSYMBOL_spirv_decorate_qualifier = 575, /* spirv_decorate_qualifier */ + YYSYMBOL_spirv_decorate_parameter_list = 576, /* spirv_decorate_parameter_list */ + YYSYMBOL_spirv_decorate_parameter = 577, /* spirv_decorate_parameter */ + YYSYMBOL_spirv_decorate_id_parameter_list = 578, /* spirv_decorate_id_parameter_list */ + YYSYMBOL_spirv_decorate_string_parameter_list = 579, /* spirv_decorate_string_parameter_list */ + YYSYMBOL_spirv_type_specifier = 580, /* spirv_type_specifier */ + YYSYMBOL_spirv_type_parameter_list = 581, /* spirv_type_parameter_list */ + YYSYMBOL_spirv_type_parameter = 582, /* spirv_type_parameter */ + YYSYMBOL_spirv_instruction_qualifier = 583, /* spirv_instruction_qualifier */ + YYSYMBOL_spirv_instruction_qualifier_list = 584, /* spirv_instruction_qualifier_list */ + YYSYMBOL_spirv_instruction_qualifier_id = 585 /* spirv_instruction_qualifier_id */ }; - -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif +typedef enum yysymbol_kind_t yysymbol_kind_t; - -int yyparse (glslang::TParseContext* pParseContext); - -#endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */ - -/* Copy the second part of user declarations. */ -#line 106 "MachineIndependent/glslang.y" /* yacc.c:358 */ +/* Second part of user prologue. */ +#line 136 "MachineIndependent/glslang.y" /* windows only pragma */ @@ -601,34 +728,82 @@ int yyparse (glslang::TParseContext* pParseContext); extern int yylex(YYSTYPE*, TParseContext&); -#line 605 "MachineIndependent/glslang_tab.cpp" /* yacc.c:358 */ +#line 732 "MachineIndependent/glslang_tab.cpp" + #ifdef short # undef short #endif -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif #endif -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; #else -typedef unsigned short int yytype_uint16; +typedef short yytype_int16; #endif -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; #else -typedef short int yytype_int16; +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif #endif #ifndef YYSIZE_T @@ -636,15 +811,28 @@ typedef short int yytype_int16; # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t -# elif ! defined YYSIZE_T +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else -# define YYSIZE_T unsigned int +# define YYSIZE_T unsigned # endif #endif -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_int16 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS @@ -658,30 +846,20 @@ typedef short int yytype_int16; # endif #endif -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else -# define YY_ATTRIBUTE(Spec) /* empty */ +# define YY_ATTRIBUTE_PURE # endif #endif -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - #ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# define YY_ATTRIBUTE_UNUSED # endif #endif @@ -692,13 +870,13 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value @@ -711,8 +889,22 @@ typedef short int yytype_int16; # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif -#if ! defined yyoverflow || YYERROR_VERBOSE + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if 1 /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -777,8 +969,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - +#endif /* 1 */ #if (! defined yyoverflow \ && (! defined __cplusplus \ @@ -787,17 +978,17 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss_alloc; + yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 @@ -810,11 +1001,11 @@ union yyalloc # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ - YYSIZE_T yynewbytes; \ + YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) @@ -826,12 +1017,12 @@ union yyalloc # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ - YYSIZE_T yyi; \ + YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ @@ -841,30 +1032,33 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 382 +#define YYFINAL 442 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 9317 +#define YYLAST 12453 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 407 +#define YYNTOKENS 455 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 107 +#define YYNNTS 131 /* YYNRULES -- Number of rules. */ -#define YYNRULES 572 +#define YYNRULES 684 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 713 +#define YYNSTATES 930 -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 661 +/* YYMAXUTOK -- Last valid token kind. */ +#define YYMAXUTOK 709 -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ -static const yytype_uint16 yytranslate[] = + as returned by yylex. */ +static const yytype_int16 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -932,168 +1126,204 @@ static const yytype_uint16 yytranslate[] = 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406 + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = +static const yytype_int16 yyrline[] = { - 0, 296, 296, 302, 305, 309, 313, 316, 320, 324, - 328, 332, 336, 339, 343, 347, 350, 358, 361, 364, - 367, 370, 375, 383, 390, 397, 403, 407, 414, 417, - 423, 430, 440, 448, 453, 480, 488, 494, 498, 502, - 522, 523, 524, 525, 531, 532, 537, 542, 551, 552, - 557, 565, 566, 572, 581, 582, 587, 592, 597, 605, - 606, 614, 625, 626, 635, 636, 645, 646, 655, 656, - 664, 665, 673, 674, 682, 683, 683, 701, 702, 718, - 722, 726, 730, 735, 739, 743, 747, 751, 755, 759, - 766, 769, 780, 787, 792, 797, 805, 809, 813, 817, - 822, 827, 836, 836, 847, 851, 858, 865, 868, 875, - 883, 903, 926, 941, 966, 977, 987, 997, 1007, 1016, - 1019, 1023, 1027, 1032, 1040, 1045, 1050, 1055, 1060, 1069, - 1080, 1107, 1116, 1123, 1130, 1141, 1150, 1160, 1172, 1181, - 1193, 1199, 1202, 1209, 1213, 1217, 1225, 1234, 1237, 1248, - 1251, 1254, 1258, 1262, 1266, 1270, 1276, 1280, 1292, 1306, - 1311, 1317, 1323, 1330, 1336, 1341, 1346, 1351, 1361, 1371, - 1381, 1391, 1400, 1412, 1416, 1421, 1426, 1431, 1436, 1441, - 1445, 1449, 1453, 1457, 1463, 1472, 1479, 1482, 1490, 1494, - 1503, 1508, 1516, 1520, 1530, 1534, 1538, 1543, 1548, 1553, - 1558, 1562, 1567, 1572, 1577, 1582, 1587, 1592, 1597, 1602, - 1607, 1611, 1616, 1621, 1626, 1632, 1638, 1644, 1650, 1656, - 1662, 1668, 1674, 1680, 1686, 1692, 1698, 1703, 1708, 1713, - 1718, 1723, 1728, 1734, 1740, 1746, 1752, 1758, 1764, 1770, - 1776, 1782, 1788, 1794, 1800, 1806, 1812, 1818, 1824, 1830, - 1836, 1842, 1848, 1854, 1860, 1866, 1872, 1878, 1884, 1890, - 1895, 1900, 1905, 1910, 1915, 1920, 1925, 1930, 1935, 1940, - 1945, 1950, 1956, 1962, 1968, 1974, 1980, 1986, 1992, 1998, - 2004, 2010, 2016, 2022, 2028, 2034, 2040, 2046, 2052, 2058, - 2064, 2070, 2076, 2082, 2088, 2094, 2100, 2106, 2112, 2118, - 2124, 2130, 2136, 2142, 2148, 2154, 2160, 2166, 2172, 2178, - 2184, 2190, 2196, 2202, 2208, 2214, 2220, 2226, 2232, 2238, - 2244, 2249, 2254, 2259, 2264, 2269, 2274, 2279, 2284, 2289, - 2294, 2299, 2304, 2309, 2314, 2322, 2330, 2338, 2346, 2354, - 2362, 2370, 2378, 2386, 2394, 2402, 2410, 2418, 2423, 2428, - 2433, 2438, 2443, 2448, 2453, 2458, 2463, 2468, 2473, 2478, - 2483, 2488, 2493, 2498, 2506, 2514, 2519, 2524, 2529, 2537, - 2542, 2547, 2552, 2560, 2565, 2570, 2575, 2583, 2588, 2593, - 2598, 2603, 2608, 2616, 2621, 2629, 2634, 2642, 2647, 2655, - 2660, 2668, 2673, 2681, 2686, 2694, 2699, 2704, 2709, 2714, - 2719, 2724, 2729, 2734, 2739, 2744, 2749, 2754, 2759, 2764, - 2769, 2777, 2782, 2787, 2792, 2800, 2805, 2810, 2815, 2823, - 2828, 2833, 2838, 2846, 2851, 2856, 2861, 2869, 2874, 2879, - 2884, 2892, 2897, 2902, 2907, 2915, 2920, 2925, 2930, 2938, - 2943, 2948, 2953, 2961, 2966, 2971, 2976, 2984, 2989, 2994, - 2999, 3007, 3012, 3017, 3022, 3030, 3035, 3040, 3045, 3053, - 3058, 3063, 3068, 3076, 3081, 3086, 3091, 3099, 3104, 3109, - 3115, 3121, 3127, 3133, 3142, 3151, 3157, 3163, 3169, 3175, - 3180, 3196, 3201, 3206, 3214, 3214, 3225, 3225, 3235, 3238, - 3251, 3273, 3300, 3304, 3310, 3315, 3326, 3329, 3335, 3344, - 3347, 3353, 3357, 3358, 3364, 3365, 3366, 3367, 3368, 3369, - 3370, 3374, 3375, 3379, 3375, 3391, 3392, 3396, 3396, 3403, - 3403, 3417, 3420, 3428, 3436, 3447, 3448, 3452, 3455, 3461, - 3468, 3472, 3480, 3484, 3497, 3500, 3506, 3506, 3526, 3529, - 3535, 3547, 3559, 3562, 3568, 3568, 3583, 3583, 3599, 3599, - 3620, 3623, 3629, 3632, 3638, 3642, 3649, 3654, 3659, 3666, - 3669, 3678, 3682, 3691, 3694, 3697, 3705, 3705, 3727, 3733, - 3736, 3741, 3744 + 0, 392, 392, 398, 401, 406, 409, 412, 416, 420, + 423, 427, 431, 435, 439, 443, 447, 453, 461, 464, + 467, 470, 473, 478, 486, 493, 500, 506, 510, 517, + 520, 526, 533, 543, 551, 556, 584, 593, 599, 603, + 607, 627, 628, 629, 630, 636, 637, 642, 647, 656, + 657, 662, 670, 671, 677, 686, 687, 692, 697, 702, + 710, 711, 720, 732, 733, 742, 743, 752, 753, 762, + 763, 771, 772, 780, 781, 789, 790, 790, 808, 809, + 825, 829, 833, 837, 842, 846, 850, 854, 858, 862, + 866, 873, 876, 887, 894, 900, 907, 913, 918, 925, + 929, 933, 937, 942, 947, 956, 956, 967, 971, 978, + 982, 988, 994, 1004, 1007, 1014, 1022, 1042, 1065, 1080, + 1105, 1116, 1126, 1136, 1146, 1155, 1158, 1162, 1166, 1171, + 1179, 1186, 1191, 1196, 1201, 1210, 1220, 1247, 1256, 1263, + 1271, 1278, 1285, 1293, 1303, 1310, 1321, 1327, 1330, 1337, + 1341, 1345, 1354, 1364, 1367, 1378, 1381, 1384, 1388, 1392, + 1397, 1401, 1404, 1409, 1413, 1418, 1427, 1431, 1436, 1442, + 1448, 1455, 1460, 1468, 1474, 1486, 1500, 1506, 1511, 1519, + 1527, 1535, 1543, 1551, 1559, 1567, 1575, 1582, 1589, 1593, + 1598, 1603, 1608, 1613, 1618, 1623, 1627, 1631, 1635, 1639, + 1645, 1656, 1663, 1666, 1675, 1680, 1690, 1695, 1703, 1707, + 1717, 1720, 1726, 1732, 1739, 1749, 1753, 1757, 1761, 1766, + 1770, 1775, 1780, 1785, 1790, 1795, 1800, 1805, 1810, 1815, + 1821, 1827, 1833, 1838, 1843, 1848, 1853, 1858, 1863, 1868, + 1873, 1878, 1883, 1888, 1894, 1901, 1906, 1911, 1916, 1921, + 1926, 1931, 1936, 1941, 1946, 1951, 1956, 1964, 1972, 1980, + 1986, 1992, 1998, 2004, 2010, 2016, 2022, 2028, 2034, 2040, + 2046, 2052, 2058, 2064, 2070, 2076, 2082, 2088, 2094, 2100, + 2106, 2112, 2118, 2124, 2130, 2136, 2142, 2148, 2154, 2160, + 2166, 2172, 2178, 2186, 2194, 2202, 2210, 2218, 2226, 2234, + 2242, 2250, 2258, 2266, 2274, 2280, 2286, 2292, 2298, 2304, + 2310, 2316, 2322, 2328, 2334, 2340, 2346, 2352, 2358, 2364, + 2370, 2376, 2382, 2388, 2394, 2400, 2406, 2412, 2418, 2424, + 2430, 2436, 2442, 2448, 2454, 2460, 2466, 2472, 2478, 2484, + 2490, 2494, 2498, 2502, 2507, 2513, 2518, 2523, 2528, 2533, + 2538, 2543, 2549, 2554, 2559, 2564, 2569, 2574, 2580, 2586, + 2592, 2598, 2604, 2610, 2616, 2622, 2628, 2634, 2640, 2646, + 2652, 2658, 2663, 2668, 2673, 2678, 2683, 2688, 2694, 2699, + 2704, 2709, 2714, 2719, 2724, 2729, 2735, 2740, 2745, 2750, + 2755, 2760, 2765, 2770, 2775, 2780, 2785, 2790, 2795, 2800, + 2805, 2811, 2816, 2821, 2827, 2833, 2838, 2843, 2848, 2854, + 2859, 2864, 2869, 2875, 2880, 2885, 2890, 2896, 2901, 2906, + 2911, 2917, 2923, 2929, 2935, 2940, 2946, 2952, 2958, 2963, + 2968, 2973, 2978, 2983, 2989, 2994, 2999, 3004, 3010, 3015, + 3020, 3025, 3031, 3036, 3041, 3046, 3052, 3057, 3062, 3067, + 3073, 3078, 3083, 3088, 3094, 3099, 3104, 3109, 3115, 3120, + 3125, 3130, 3136, 3141, 3146, 3151, 3157, 3162, 3167, 3172, + 3178, 3183, 3188, 3193, 3199, 3204, 3209, 3214, 3220, 3225, + 3230, 3235, 3241, 3246, 3251, 3256, 3262, 3267, 3272, 3277, + 3283, 3288, 3293, 3298, 3303, 3308, 3313, 3318, 3323, 3328, + 3333, 3338, 3343, 3348, 3353, 3358, 3363, 3368, 3373, 3378, + 3383, 3388, 3393, 3398, 3403, 3409, 3415, 3421, 3427, 3434, + 3441, 3447, 3453, 3459, 3465, 3471, 3477, 3483, 3488, 3493, + 3509, 3514, 3519, 3527, 3527, 3538, 3538, 3548, 3551, 3564, + 3586, 3613, 3617, 3623, 3628, 3639, 3643, 3649, 3655, 3666, + 3669, 3676, 3680, 3681, 3687, 3688, 3689, 3690, 3691, 3692, + 3693, 3695, 3701, 3710, 3711, 3715, 3711, 3727, 3728, 3732, + 3732, 3739, 3739, 3753, 3756, 3764, 3772, 3783, 3784, 3788, + 3792, 3800, 3807, 3811, 3819, 3823, 3836, 3840, 3848, 3848, + 3868, 3871, 3877, 3889, 3901, 3905, 3913, 3913, 3928, 3928, + 3944, 3944, 3965, 3968, 3974, 3977, 3983, 3987, 3994, 3999, + 4004, 4011, 4014, 4018, 4023, 4027, 4037, 4041, 4050, 4053, + 4057, 4066, 4066, 4108, 4113, 4116, 4121, 4124, 4131, 4134, + 4139, 4142, 4147, 4150, 4155, 4158, 4163, 4167, 4172, 4176, + 4181, 4185, 4192, 4195, 4200, 4203, 4206, 4209, 4212, 4217, + 4226, 4237, 4242, 4250, 4254, 4259, 4263, 4268, 4272, 4277, + 4281, 4288, 4291, 4296, 4299, 4302, 4305, 4310, 4318, 4328, + 4332, 4337, 4341, 4346, 4350, 4357, 4360, 4365, 4368, 4373, + 4376, 4382, 4385, 4390, 4393 }; #endif -#if YYDEBUG || YYERROR_VERBOSE || 1 +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if 1 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "ATTRIBUTE", "VARYING", "FLOAT16_T", - "FLOAT", "FLOAT32_T", "DOUBLE", "FLOAT64_T", "CONST", "BOOL", "INT", - "UINT", "INT64_T", "UINT64_T", "INT32_T", "UINT32_T", "INT16_T", - "UINT16_T", "INT8_T", "UINT8_T", "BREAK", "CONTINUE", "DO", "ELSE", - "FOR", "IF", "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", - "SUBROUTINE", "BVEC2", "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", - "UVEC2", "UVEC3", "UVEC4", "I64VEC2", "I64VEC3", "I64VEC4", "U64VEC2", - "U64VEC3", "U64VEC4", "I32VEC2", "I32VEC3", "I32VEC4", "U32VEC2", - "U32VEC3", "U32VEC4", "I16VEC2", "I16VEC3", "I16VEC4", "U16VEC2", - "U16VEC3", "U16VEC4", "I8VEC2", "I8VEC3", "I8VEC4", "U8VEC2", "U8VEC3", - "U8VEC4", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", "MAT4", "CENTROID", - "IN", "OUT", "INOUT", "UNIFORM", "PATCH", "SAMPLE", "BUFFER", "SHARED", - "NONUNIFORM", "PAYLOADNV", "PAYLOADINNV", "HITATTRNV", "CALLDATANV", - "CALLDATAINNV", "COHERENT", "VOLATILE", "RESTRICT", "READONLY", - "WRITEONLY", "DEVICECOHERENT", "QUEUEFAMILYCOHERENT", - "WORKGROUPCOHERENT", "SUBGROUPCOHERENT", "NONPRIVATE", "DVEC2", "DVEC3", + "\"end of file\"", "error", "\"invalid token\"", "CONST", "BOOL", "INT", + "UINT", "FLOAT", "BVEC2", "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", + "UVEC2", "UVEC3", "UVEC4", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", + "MAT4", "MAT2X2", "MAT2X3", "MAT2X4", "MAT3X2", "MAT3X3", "MAT3X4", + "MAT4X2", "MAT4X3", "MAT4X4", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", + "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", "SAMPLER2DARRAY", + "SAMPLER2DARRAYSHADOW", "ISAMPLER2D", "ISAMPLER3D", "ISAMPLERCUBE", + "ISAMPLER2DARRAY", "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", + "USAMPLER2DARRAY", "SAMPLER", "SAMPLERSHADOW", "TEXTURE2D", "TEXTURE3D", + "TEXTURECUBE", "TEXTURE2DARRAY", "ITEXTURE2D", "ITEXTURE3D", + "ITEXTURECUBE", "ITEXTURE2DARRAY", "UTEXTURE2D", "UTEXTURE3D", + "UTEXTURECUBE", "UTEXTURE2DARRAY", "ATTRIBUTE", "VARYING", "FLOAT16_T", + "FLOAT32_T", "DOUBLE", "FLOAT64_T", "INT64_T", "UINT64_T", "INT32_T", + "UINT32_T", "INT16_T", "UINT16_T", "INT8_T", "UINT8_T", "I64VEC2", + "I64VEC3", "I64VEC4", "U64VEC2", "U64VEC3", "U64VEC4", "I32VEC2", + "I32VEC3", "I32VEC4", "U32VEC2", "U32VEC3", "U32VEC4", "I16VEC2", + "I16VEC3", "I16VEC4", "U16VEC2", "U16VEC3", "U16VEC4", "I8VEC2", + "I8VEC3", "I8VEC4", "U8VEC2", "U8VEC3", "U8VEC4", "DVEC2", "DVEC3", "DVEC4", "DMAT2", "DMAT3", "DMAT4", "F16VEC2", "F16VEC3", "F16VEC4", "F16MAT2", "F16MAT3", "F16MAT4", "F32VEC2", "F32VEC3", "F32VEC4", "F32MAT2", "F32MAT3", "F32MAT4", "F64VEC2", "F64VEC3", "F64VEC4", - "F64MAT2", "F64MAT3", "F64MAT4", "NOPERSPECTIVE", "FLAT", "SMOOTH", - "LAYOUT", "EXPLICITINTERPAMD", "PERVERTEXNV", "PERPRIMITIVENV", - "PERVIEWNV", "PERTASKNV", "MAT2X2", "MAT2X3", "MAT2X4", "MAT3X2", - "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3", "MAT4X4", "DMAT2X2", "DMAT2X3", - "DMAT2X4", "DMAT3X2", "DMAT3X3", "DMAT3X4", "DMAT4X2", "DMAT4X3", - "DMAT4X4", "F16MAT2X2", "F16MAT2X3", "F16MAT2X4", "F16MAT3X2", - "F16MAT3X3", "F16MAT3X4", "F16MAT4X2", "F16MAT4X3", "F16MAT4X4", - "F32MAT2X2", "F32MAT2X3", "F32MAT2X4", "F32MAT3X2", "F32MAT3X3", - "F32MAT3X4", "F32MAT4X2", "F32MAT4X3", "F32MAT4X4", "F64MAT2X2", - "F64MAT2X3", "F64MAT2X4", "F64MAT3X2", "F64MAT3X3", "F64MAT3X4", - "F64MAT4X2", "F64MAT4X3", "F64MAT4X4", "ATOMIC_UINT", "ACCSTRUCTNV", - "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", "SAMPLER1DSHADOW", - "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", "SAMPLER1DARRAY", - "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW", "SAMPLER2DARRAYSHADOW", - "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D", "ISAMPLERCUBE", - "ISAMPLER1DARRAY", "ISAMPLER2DARRAY", "USAMPLER1D", "USAMPLER2D", - "USAMPLER3D", "USAMPLERCUBE", "USAMPLER1DARRAY", "USAMPLER2DARRAY", - "SAMPLER2DRECT", "SAMPLER2DRECTSHADOW", "ISAMPLER2DRECT", - "USAMPLER2DRECT", "SAMPLERBUFFER", "ISAMPLERBUFFER", "USAMPLERBUFFER", + "F64MAT2", "F64MAT3", "F64MAT4", "DMAT2X2", "DMAT2X3", "DMAT2X4", + "DMAT3X2", "DMAT3X3", "DMAT3X4", "DMAT4X2", "DMAT4X3", "DMAT4X4", + "F16MAT2X2", "F16MAT2X3", "F16MAT2X4", "F16MAT3X2", "F16MAT3X3", + "F16MAT3X4", "F16MAT4X2", "F16MAT4X3", "F16MAT4X4", "F32MAT2X2", + "F32MAT2X3", "F32MAT2X4", "F32MAT3X2", "F32MAT3X3", "F32MAT3X4", + "F32MAT4X2", "F32MAT4X3", "F32MAT4X4", "F64MAT2X2", "F64MAT2X3", + "F64MAT2X4", "F64MAT3X2", "F64MAT3X3", "F64MAT3X4", "F64MAT4X2", + "F64MAT4X3", "F64MAT4X4", "ATOMIC_UINT", "ACCSTRUCTNV", "ACCSTRUCTEXT", + "RAYQUERYEXT", "FCOOPMATNV", "ICOOPMATNV", "UCOOPMATNV", "SAMPLERCUBEARRAY", "SAMPLERCUBEARRAYSHADOW", "ISAMPLERCUBEARRAY", - "USAMPLERCUBEARRAY", "SAMPLER2DMS", "ISAMPLER2DMS", "USAMPLER2DMS", - "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", "USAMPLER2DMSARRAY", - "SAMPLEREXTERNALOES", "SAMPLEREXTERNAL2DY2YEXT", "F16SAMPLER1D", + "USAMPLERCUBEARRAY", "SAMPLER1D", "SAMPLER1DARRAY", + "SAMPLER1DARRAYSHADOW", "ISAMPLER1D", "SAMPLER1DSHADOW", "SAMPLER2DRECT", + "SAMPLER2DRECTSHADOW", "ISAMPLER2DRECT", "USAMPLER2DRECT", + "SAMPLERBUFFER", "ISAMPLERBUFFER", "USAMPLERBUFFER", "SAMPLER2DMS", + "ISAMPLER2DMS", "USAMPLER2DMS", "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", + "USAMPLER2DMSARRAY", "SAMPLEREXTERNALOES", "SAMPLEREXTERNAL2DY2YEXT", + "ISAMPLER1DARRAY", "USAMPLER1D", "USAMPLER1DARRAY", "F16SAMPLER1D", "F16SAMPLER2D", "F16SAMPLER3D", "F16SAMPLER2DRECT", "F16SAMPLERCUBE", "F16SAMPLER1DARRAY", "F16SAMPLER2DARRAY", "F16SAMPLERCUBEARRAY", "F16SAMPLERBUFFER", "F16SAMPLER2DMS", "F16SAMPLER2DMSARRAY", "F16SAMPLER1DSHADOW", "F16SAMPLER2DSHADOW", "F16SAMPLER1DARRAYSHADOW", "F16SAMPLER2DARRAYSHADOW", "F16SAMPLER2DRECTSHADOW", - "F16SAMPLERCUBESHADOW", "F16SAMPLERCUBEARRAYSHADOW", "SAMPLER", - "SAMPLERSHADOW", "TEXTURE1D", "TEXTURE2D", "TEXTURE3D", "TEXTURECUBE", - "TEXTURE1DARRAY", "TEXTURE2DARRAY", "ITEXTURE1D", "ITEXTURE2D", - "ITEXTURE3D", "ITEXTURECUBE", "ITEXTURE1DARRAY", "ITEXTURE2DARRAY", - "UTEXTURE1D", "UTEXTURE2D", "UTEXTURE3D", "UTEXTURECUBE", - "UTEXTURE1DARRAY", "UTEXTURE2DARRAY", "TEXTURE2DRECT", "ITEXTURE2DRECT", - "UTEXTURE2DRECT", "TEXTUREBUFFER", "ITEXTUREBUFFER", "UTEXTUREBUFFER", - "TEXTURECUBEARRAY", "ITEXTURECUBEARRAY", "UTEXTURECUBEARRAY", - "TEXTURE2DMS", "ITEXTURE2DMS", "UTEXTURE2DMS", "TEXTURE2DMSARRAY", - "ITEXTURE2DMSARRAY", "UTEXTURE2DMSARRAY", "F16TEXTURE1D", "F16TEXTURE2D", - "F16TEXTURE3D", "F16TEXTURE2DRECT", "F16TEXTURECUBE", - "F16TEXTURE1DARRAY", "F16TEXTURE2DARRAY", "F16TEXTURECUBEARRAY", - "F16TEXTUREBUFFER", "F16TEXTURE2DMS", "F16TEXTURE2DMSARRAY", - "SUBPASSINPUT", "SUBPASSINPUTMS", "ISUBPASSINPUT", "ISUBPASSINPUTMS", - "USUBPASSINPUT", "USUBPASSINPUTMS", "F16SUBPASSINPUT", - "F16SUBPASSINPUTMS", "IMAGE1D", "IIMAGE1D", "UIMAGE1D", "IMAGE2D", - "IIMAGE2D", "UIMAGE2D", "IMAGE3D", "IIMAGE3D", "UIMAGE3D", "IMAGE2DRECT", - "IIMAGE2DRECT", "UIMAGE2DRECT", "IMAGECUBE", "IIMAGECUBE", "UIMAGECUBE", - "IMAGEBUFFER", "IIMAGEBUFFER", "UIMAGEBUFFER", "IMAGE1DARRAY", - "IIMAGE1DARRAY", "UIMAGE1DARRAY", "IMAGE2DARRAY", "IIMAGE2DARRAY", - "UIMAGE2DARRAY", "IMAGECUBEARRAY", "IIMAGECUBEARRAY", "UIMAGECUBEARRAY", - "IMAGE2DMS", "IIMAGE2DMS", "UIMAGE2DMS", "IMAGE2DMSARRAY", - "IIMAGE2DMSARRAY", "UIMAGE2DMSARRAY", "F16IMAGE1D", "F16IMAGE2D", - "F16IMAGE3D", "F16IMAGE2DRECT", "F16IMAGECUBE", "F16IMAGE1DARRAY", - "F16IMAGE2DARRAY", "F16IMAGECUBEARRAY", "F16IMAGEBUFFER", "F16IMAGE2DMS", - "F16IMAGE2DMSARRAY", "STRUCT", "VOID", "WHILE", "IDENTIFIER", - "TYPE_NAME", "FLOATCONSTANT", "DOUBLECONSTANT", "INT16CONSTANT", - "UINT16CONSTANT", "INT32CONSTANT", "UINT32CONSTANT", "INTCONSTANT", - "UINTCONSTANT", "INT64CONSTANT", "UINT64CONSTANT", "BOOLCONSTANT", - "FLOAT16CONSTANT", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", - "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", - "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", - "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "LEFT_PAREN", - "RIGHT_PAREN", "LEFT_BRACKET", "RIGHT_BRACKET", "LEFT_BRACE", - "RIGHT_BRACE", "DOT", "COMMA", "COLON", "EQUAL", "SEMICOLON", "BANG", - "DASH", "TILDE", "PLUS", "STAR", "SLASH", "PERCENT", "LEFT_ANGLE", - "RIGHT_ANGLE", "VERTICAL_BAR", "CARET", "AMPERSAND", "QUESTION", - "INVARIANT", "PRECISE", "HIGH_PRECISION", "MEDIUM_PRECISION", - "LOW_PRECISION", "PRECISION", "PACKED", "RESOURCE", "SUPERP", "$accept", - "variable_identifier", "primary_expression", "postfix_expression", - "integer_expression", "function_call", "function_call_or_method", - "function_call_generic", "function_call_header_no_parameters", + "F16SAMPLERCUBESHADOW", "F16SAMPLERCUBEARRAYSHADOW", "IMAGE1D", + "IIMAGE1D", "UIMAGE1D", "IMAGE2D", "IIMAGE2D", "UIMAGE2D", "IMAGE3D", + "IIMAGE3D", "UIMAGE3D", "IMAGE2DRECT", "IIMAGE2DRECT", "UIMAGE2DRECT", + "IMAGECUBE", "IIMAGECUBE", "UIMAGECUBE", "IMAGEBUFFER", "IIMAGEBUFFER", + "UIMAGEBUFFER", "IMAGE1DARRAY", "IIMAGE1DARRAY", "UIMAGE1DARRAY", + "IMAGE2DARRAY", "IIMAGE2DARRAY", "UIMAGE2DARRAY", "IMAGECUBEARRAY", + "IIMAGECUBEARRAY", "UIMAGECUBEARRAY", "IMAGE2DMS", "IIMAGE2DMS", + "UIMAGE2DMS", "IMAGE2DMSARRAY", "IIMAGE2DMSARRAY", "UIMAGE2DMSARRAY", + "F16IMAGE1D", "F16IMAGE2D", "F16IMAGE3D", "F16IMAGE2DRECT", + "F16IMAGECUBE", "F16IMAGE1DARRAY", "F16IMAGE2DARRAY", + "F16IMAGECUBEARRAY", "F16IMAGEBUFFER", "F16IMAGE2DMS", + "F16IMAGE2DMSARRAY", "I64IMAGE1D", "U64IMAGE1D", "I64IMAGE2D", + "U64IMAGE2D", "I64IMAGE3D", "U64IMAGE3D", "I64IMAGE2DRECT", + "U64IMAGE2DRECT", "I64IMAGECUBE", "U64IMAGECUBE", "I64IMAGEBUFFER", + "U64IMAGEBUFFER", "I64IMAGE1DARRAY", "U64IMAGE1DARRAY", + "I64IMAGE2DARRAY", "U64IMAGE2DARRAY", "I64IMAGECUBEARRAY", + "U64IMAGECUBEARRAY", "I64IMAGE2DMS", "U64IMAGE2DMS", "I64IMAGE2DMSARRAY", + "U64IMAGE2DMSARRAY", "TEXTURECUBEARRAY", "ITEXTURECUBEARRAY", + "UTEXTURECUBEARRAY", "TEXTURE1D", "ITEXTURE1D", "UTEXTURE1D", + "TEXTURE1DARRAY", "ITEXTURE1DARRAY", "UTEXTURE1DARRAY", "TEXTURE2DRECT", + "ITEXTURE2DRECT", "UTEXTURE2DRECT", "TEXTUREBUFFER", "ITEXTUREBUFFER", + "UTEXTUREBUFFER", "TEXTURE2DMS", "ITEXTURE2DMS", "UTEXTURE2DMS", + "TEXTURE2DMSARRAY", "ITEXTURE2DMSARRAY", "UTEXTURE2DMSARRAY", + "F16TEXTURE1D", "F16TEXTURE2D", "F16TEXTURE3D", "F16TEXTURE2DRECT", + "F16TEXTURECUBE", "F16TEXTURE1DARRAY", "F16TEXTURE2DARRAY", + "F16TEXTURECUBEARRAY", "F16TEXTUREBUFFER", "F16TEXTURE2DMS", + "F16TEXTURE2DMSARRAY", "SUBPASSINPUT", "SUBPASSINPUTMS", "ISUBPASSINPUT", + "ISUBPASSINPUTMS", "USUBPASSINPUT", "USUBPASSINPUTMS", "F16SUBPASSINPUT", + "F16SUBPASSINPUTMS", "SPIRV_INSTRUCTION", "SPIRV_EXECUTION_MODE", + "SPIRV_EXECUTION_MODE_ID", "SPIRV_DECORATE", "SPIRV_DECORATE_ID", + "SPIRV_DECORATE_STRING", "SPIRV_TYPE", "SPIRV_STORAGE_CLASS", + "SPIRV_BY_REFERENCE", "SPIRV_LITERAL", "LEFT_OP", "RIGHT_OP", "INC_OP", + "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", + "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", + "LEFT_ASSIGN", "RIGHT_ASSIGN", "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", + "SUB_ASSIGN", "STRING_LITERAL", "LEFT_PAREN", "RIGHT_PAREN", + "LEFT_BRACKET", "RIGHT_BRACKET", "LEFT_BRACE", "RIGHT_BRACE", "DOT", + "COMMA", "COLON", "EQUAL", "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS", + "STAR", "SLASH", "PERCENT", "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR", + "CARET", "AMPERSAND", "QUESTION", "INVARIANT", "HIGH_PRECISION", + "MEDIUM_PRECISION", "LOW_PRECISION", "PRECISION", "PACKED", "RESOURCE", + "SUPERP", "FLOATCONSTANT", "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT", + "IDENTIFIER", "TYPE_NAME", "CENTROID", "IN", "OUT", "INOUT", "STRUCT", + "VOID", "WHILE", "BREAK", "CONTINUE", "DO", "ELSE", "FOR", "IF", + "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "TERMINATE_INVOCATION", + "TERMINATE_RAY", "IGNORE_INTERSECTION", "UNIFORM", "SHARED", "BUFFER", + "FLAT", "SMOOTH", "LAYOUT", "DOUBLECONSTANT", "INT16CONSTANT", + "UINT16CONSTANT", "FLOAT16CONSTANT", "INT32CONSTANT", "UINT32CONSTANT", + "INT64CONSTANT", "UINT64CONSTANT", "SUBROUTINE", "DEMOTE", "PAYLOADNV", + "PAYLOADINNV", "HITATTRNV", "CALLDATANV", "CALLDATAINNV", "PAYLOADEXT", + "PAYLOADINEXT", "HITATTREXT", "CALLDATAEXT", "CALLDATAINEXT", "PATCH", + "SAMPLE", "NONUNIFORM", "COHERENT", "VOLATILE", "RESTRICT", "READONLY", + "WRITEONLY", "DEVICECOHERENT", "QUEUEFAMILYCOHERENT", + "WORKGROUPCOHERENT", "SUBGROUPCOHERENT", "NONPRIVATE", + "SHADERCALLCOHERENT", "NOPERSPECTIVE", "EXPLICITINTERPAMD", + "PERVERTEXNV", "PERPRIMITIVENV", "PERVIEWNV", "PERTASKNV", "PRECISE", + "$accept", "variable_identifier", "primary_expression", + "postfix_expression", "integer_expression", "function_call", + "function_call_or_method", "function_call_generic", + "function_call_header_no_parameters", "function_call_header_with_parameters", "function_call_header", "function_identifier", "unary_expression", "unary_operator", "multiplicative_expression", "additive_expression", "shift_expression", @@ -1111,13 +1341,14 @@ static const char *const yytname[] = "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id", "precise_qualifier", "type_qualifier", "single_type_qualifier", "storage_qualifier", "non_uniform_qualifier", "type_name_list", - "type_specifier", "array_specifier", "type_specifier_nonarray", - "precision_qualifier", "struct_specifier", "$@3", "$@4", - "struct_declaration_list", "struct_declaration", + "type_specifier", "array_specifier", "type_parameter_specifier_opt", + "type_parameter_specifier", "type_parameter_specifier_list", + "type_specifier_nonarray", "precision_qualifier", "struct_specifier", + "$@3", "$@4", "struct_declaration_list", "struct_declaration", "struct_declarator_list", "struct_declarator", "initializer", "initializer_list", "declaration_statement", "statement", - "simple_statement", "compound_statement", "$@5", "$@6", - "statement_no_new_scope", "statement_scoped", "$@7", "$@8", + "simple_statement", "demote_statement", "compound_statement", "$@5", + "$@6", "statement_no_new_scope", "statement_scoped", "$@7", "$@8", "compound_statement_no_new_scope", "statement_list", "expression_statement", "selection_statement", "selection_statement_nonattributed", "selection_rest_statement", @@ -1127,14 +1358,31 @@ static const char *const yytname[] = "for_init_statement", "conditionopt", "for_rest_statement", "jump_statement", "translation_unit", "external_declaration", "function_definition", "$@13", "attribute", "attribute_list", - "single_attribute", YY_NULLPTR + "single_attribute", "spirv_requirements_list", + "spirv_requirements_parameter", "spirv_extension_list", + "spirv_capability_list", "spirv_execution_mode_qualifier", + "spirv_execution_mode_parameter_list", "spirv_execution_mode_parameter", + "spirv_execution_mode_id_parameter_list", + "spirv_storage_class_qualifier", "spirv_decorate_qualifier", + "spirv_decorate_parameter_list", "spirv_decorate_parameter", + "spirv_decorate_id_parameter_list", + "spirv_decorate_string_parameter_list", "spirv_type_specifier", + "spirv_type_parameter_list", "spirv_type_parameter", + "spirv_instruction_qualifier", "spirv_instruction_qualifier_list", + "spirv_instruction_qualifier_id", YY_NULLPTR }; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + return yytname[yysymbol]; +} #endif -# ifdef YYPRINT +#ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ -static const yytype_uint16 yytoknum[] = +static const yytype_int16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, @@ -1176,207 +1424,260 @@ static const yytype_uint16 yytoknum[] = 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 659, 660, 661 + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, + 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, + 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, + 705, 706, 707, 708, 709 }; -# endif +#endif -#define YYPACT_NINF -657 +#define YYPACT_NINF (-863) -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-657))) +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF -518 +#define YYTABLE_NINF (-570) -#define yytable_value_is_error(Yytable_value) \ +#define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { - 3519, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -338, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -331, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -657, -318, -657, -657, -657, -657, -657, -657, - -657, -657, -258, -657, -319, -344, -303, -257, 5920, -281, - -657, -286, -657, -657, -657, -657, 4320, -657, -657, -657, - -657, -227, -657, -657, 712, -657, -657, -224, -68, -246, - -657, 8977, -339, -657, -657, -220, -657, 5920, -657, -657, - -657, 5920, -201, -175, -657, -341, -315, -657, -657, -657, - 6673, -206, -657, -657, -657, -308, -657, -214, -307, -657, - -657, 5920, -213, -657, -337, 1113, -657, -657, -657, -657, - -227, -322, -657, 7057, -321, -657, -167, -657, -261, -657, - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, 8209, 8209, 8209, -657, -657, -657, -657, -657, - -657, -657, -328, -657, -657, -657, -202, -285, 8593, -200, - -657, 8209, -244, -238, -266, -334, -207, -219, -217, -218, - -186, -183, -340, -196, -657, -657, 7441, -657, -157, 8209, - -657, -68, 5920, 5920, -156, 4720, -657, -657, -657, -199, - -195, -657, -190, -184, -192, 7825, -181, 8209, -194, -180, - -179, -178, -657, -657, -288, -657, -657, -259, -657, -344, - -174, -172, -657, -657, -657, -657, 1514, -657, -657, -657, - -657, -657, -657, -657, -657, -657, -19, -206, 7057, -312, - 7057, -657, -657, 7057, 5920, -657, -144, -657, -657, -657, - -284, -657, -657, 8209, -143, -657, -657, 8209, -171, -657, - -657, -657, 8209, 8209, 8209, 8209, 8209, 8209, 8209, 8209, - 8209, 8209, 8209, 8209, 8209, 8209, 8209, 8209, 8209, 8209, - 8209, -657, -657, -657, -169, -657, -657, -657, -657, 5120, - -156, -227, -255, -657, -657, -657, -657, -657, 1915, -657, - 8209, -657, -657, -253, 8209, -225, -657, -657, -136, -657, - 1915, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, 8209, 8209, -657, -657, -657, -657, -657, -657, - -657, 7057, -657, -240, -657, 5520, -657, -657, -168, -166, - -657, -657, -657, -657, -657, -244, -244, -238, -238, -266, - -266, -266, -266, -334, -334, -207, -219, -217, -218, -186, - -183, 8209, -657, -657, -247, -206, -156, -657, -132, 3118, - -282, -657, -277, -657, 3920, -164, -276, -657, 1915, -657, - -657, -657, -657, 6289, -657, -657, -221, -657, -657, -162, - -657, -657, 3920, -165, -657, -166, -125, 5920, -159, 8209, - -160, -136, -161, -657, -657, 8209, 8209, -657, -163, -155, - 194, -153, 2717, -657, -152, -134, 2316, -128, -657, -657, - -657, -657, -273, 8209, 2316, -165, -657, -657, 1915, 7057, - -657, -657, -657, -657, -133, -166, -657, -657, 1915, -129, - -657, -657, -657 + 4549, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -260, -182, -177, -163, -130, + -115, -100, -89, -863, -863, -196, -863, -863, -863, -863, + -863, -324, -863, -863, -863, -863, -863, -306, -863, -863, + -863, -863, -863, -863, -77, -66, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -332, -175, + -153, -161, 7713, -266, -863, -71, -863, -863, -863, -863, + 5453, -863, -863, -863, -863, -116, -863, -863, 933, -863, + -863, 7713, -35, -863, -863, -863, 5905, -54, -139, -138, + -137, -128, -124, -54, -123, -51, 12061, -863, -15, -347, + -44, -863, -295, -863, -9, -6, 7713, -863, -863, -863, + 7713, -39, -38, -863, -303, -863, -226, -863, -863, 10762, + -3, -863, -863, -863, 1, -32, 7713, -863, -5, -8, + -1, -863, -230, -863, -219, -2, 3, 4, 5, -215, + 6, 8, 10, 11, 12, 15, -214, 13, 16, 21, + -134, -863, 17, 7713, -863, 19, -863, -212, -863, -863, + -211, 9030, -863, -273, 1385, -863, -863, -863, -863, -863, + -3, -263, -863, 9463, -236, -863, -28, -863, -106, 10762, + 10762, -863, 10762, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -264, -863, -863, -863, 23, -203, 11195, 25, + -863, 10762, -863, -863, -311, 24, -6, 29, -863, -309, + -54, -863, -20, -863, -323, 28, -118, 10762, -112, -863, + -155, -111, 10762, -103, 35, -98, -54, -863, 11628, -863, + -94, 10762, 32, -51, -863, 7713, 18, 6357, -863, 7713, + 10762, -863, -347, -863, 33, -863, -863, -72, -254, -86, + -297, -68, -13, 26, 20, 50, 49, -300, 42, 9896, + -863, 43, -863, -863, 55, 58, 60, -863, 65, 71, + 62, 10329, 73, 10762, 66, 69, 70, 72, 74, -241, + -863, -863, -41, -863, -175, 83, 85, -863, -863, -863, + -863, -863, 1837, -863, -863, -863, -863, -863, -863, -863, + -863, -863, 5001, 24, 9463, -233, 8164, -863, -863, 9463, + 7713, -863, 51, -863, -863, -863, -194, -863, -863, 10762, + 52, -863, -863, 10762, 88, -863, -863, -863, 10762, -863, + -863, -863, -315, -863, -863, -191, 82, -863, -863, -863, + -863, -863, -863, -190, -863, -187, -863, -863, -186, 86, + -863, -863, -863, -863, -169, -863, -168, -863, -167, 89, + -863, -165, 91, -157, 82, -863, 85, -156, -863, 94, + 98, -863, -863, 18, -3, -40, -863, -863, -863, 6809, + -863, -863, -863, 10762, 10762, 10762, 10762, 10762, 10762, 10762, + 10762, 10762, 10762, 10762, 10762, 10762, 10762, 10762, 10762, 10762, + 10762, 10762, -863, -863, -863, 97, -863, 2289, -863, -863, + -863, 2289, -863, 10762, -863, -863, -34, 10762, -79, -863, + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, 10762, 10762, -863, -863, -863, + -863, -863, -863, -863, 9463, -863, -863, -208, -863, 7261, + -863, -863, 99, 96, -863, -863, -863, -863, -863, -132, + -131, -863, -307, -863, -323, -863, -323, -863, 10762, 10762, + -863, -155, -863, -155, -863, 10762, 10762, -863, 93, 35, + -863, 11628, -863, 10762, -863, -863, -33, 24, 18, -863, + -863, -863, -863, -863, -72, -72, -254, -254, -86, -86, + -86, -86, -297, -297, -68, -13, 26, 20, 50, 49, + 10762, -863, 2289, 4097, 57, 3645, -154, -863, -152, -863, + -863, -863, -863, -863, 8597, -863, -863, -863, 105, -863, + 75, -863, -145, -863, -144, -863, -143, -863, -142, -863, + -141, -140, -863, -863, -863, -27, 100, 96, 76, 106, + 109, -863, -863, 4097, 107, -863, -863, -863, -863, -863, + -863, -863, -863, -863, -863, -863, 10762, -863, 101, 2741, + 10762, -863, 103, 113, 67, 112, 3193, -863, 114, -863, + 9463, -863, -863, -863, -133, 10762, 2741, 107, -863, -863, + 2289, -863, 110, 96, -863, -863, 2289, 116, -863, -863 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ -static const yytype_uint16 yydefact[] = +static const yytype_int16 yydefact[] = { - 0, 157, 158, 197, 195, 198, 196, 199, 156, 210, - 200, 201, 208, 209, 206, 207, 204, 205, 202, 203, - 183, 226, 227, 228, 229, 230, 231, 244, 245, 246, - 241, 242, 243, 256, 257, 258, 238, 239, 240, 253, - 254, 255, 235, 236, 237, 250, 251, 252, 232, 233, - 234, 247, 248, 249, 211, 212, 213, 259, 260, 261, - 162, 160, 161, 159, 165, 163, 164, 166, 172, 185, - 168, 169, 167, 170, 171, 173, 179, 180, 181, 182, - 174, 175, 176, 177, 178, 214, 215, 216, 271, 272, - 273, 217, 218, 219, 283, 284, 285, 220, 221, 222, - 295, 296, 297, 223, 224, 225, 307, 308, 309, 134, - 133, 132, 0, 135, 136, 137, 138, 139, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 310, 311, 312, 313, 314, 315, - 316, 317, 318, 320, 319, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 331, 347, 348, 349, 350, - 351, 352, 354, 355, 356, 357, 358, 359, 361, 362, - 365, 366, 367, 369, 370, 332, 333, 353, 360, 371, - 373, 374, 375, 377, 378, 469, 470, 334, 335, 336, - 363, 337, 341, 342, 345, 368, 372, 376, 338, 339, - 343, 344, 364, 340, 346, 379, 380, 381, 383, 385, - 387, 389, 391, 395, 396, 397, 398, 399, 400, 402, - 403, 404, 405, 406, 407, 409, 411, 412, 413, 415, - 416, 393, 401, 408, 417, 419, 420, 421, 423, 424, - 382, 384, 386, 410, 388, 390, 392, 394, 414, 418, - 422, 471, 472, 475, 476, 477, 478, 473, 474, 425, - 427, 428, 429, 431, 432, 433, 435, 436, 437, 439, - 440, 441, 443, 444, 445, 447, 448, 449, 451, 452, - 453, 455, 456, 457, 459, 460, 461, 463, 464, 465, - 467, 468, 426, 430, 434, 438, 442, 450, 454, 458, - 446, 462, 466, 0, 194, 480, 565, 131, 146, 481, - 482, 483, 0, 564, 0, 566, 0, 108, 107, 0, - 119, 124, 153, 152, 150, 154, 0, 147, 149, 155, - 129, 188, 151, 479, 0, 561, 563, 0, 0, 0, - 486, 0, 0, 96, 93, 0, 106, 0, 115, 109, - 117, 0, 118, 0, 94, 125, 0, 99, 148, 130, - 0, 189, 1, 562, 186, 0, 145, 143, 0, 141, - 484, 0, 0, 97, 0, 0, 567, 110, 114, 116, - 112, 120, 111, 0, 126, 102, 0, 100, 0, 2, - 12, 13, 10, 11, 4, 5, 6, 7, 8, 9, - 15, 14, 0, 0, 0, 190, 42, 41, 43, 40, - 3, 17, 36, 19, 24, 25, 0, 0, 29, 0, - 44, 0, 48, 51, 54, 59, 62, 64, 66, 68, - 70, 72, 74, 0, 35, 33, 0, 184, 0, 0, - 140, 0, 0, 0, 0, 0, 488, 95, 98, 0, - 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 512, 521, 525, 44, 77, 90, 0, 501, 0, - 155, 129, 504, 523, 503, 502, 0, 505, 506, 527, - 507, 534, 508, 509, 542, 510, 0, 113, 0, 121, - 0, 496, 128, 0, 0, 104, 0, 101, 37, 38, - 0, 21, 22, 0, 0, 27, 26, 0, 194, 30, - 32, 39, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 219, 217, 218, 216, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 220, 221, 222, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 345, 346, 347, 348, 349, 350, 351, 371, 372, 373, + 374, 375, 376, 377, 386, 399, 400, 387, 388, 390, + 389, 391, 392, 393, 394, 395, 396, 397, 398, 174, + 175, 245, 246, 244, 247, 254, 255, 252, 253, 250, + 251, 248, 249, 277, 278, 279, 289, 290, 291, 274, + 275, 276, 286, 287, 288, 271, 272, 273, 283, 284, + 285, 268, 269, 270, 280, 281, 282, 256, 257, 258, + 292, 293, 294, 259, 260, 261, 304, 305, 306, 262, + 263, 264, 316, 317, 318, 265, 266, 267, 328, 329, + 330, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 319, + 320, 321, 322, 323, 324, 325, 326, 327, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 343, 340, 341, + 342, 524, 525, 526, 355, 356, 379, 382, 344, 353, + 354, 370, 352, 401, 402, 405, 406, 407, 409, 410, + 411, 413, 414, 415, 417, 418, 514, 515, 378, 380, + 381, 357, 358, 359, 403, 360, 364, 365, 368, 408, + 412, 416, 361, 362, 366, 367, 404, 363, 369, 448, + 450, 451, 452, 454, 455, 456, 458, 459, 460, 462, + 463, 464, 466, 467, 468, 470, 471, 472, 474, 475, + 476, 478, 479, 480, 482, 483, 484, 486, 487, 488, + 490, 491, 449, 453, 457, 461, 465, 473, 477, 481, + 469, 485, 489, 492, 493, 494, 495, 496, 497, 498, + 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, + 509, 510, 511, 512, 513, 383, 384, 385, 419, 428, + 430, 424, 429, 431, 432, 434, 435, 436, 438, 439, + 440, 442, 443, 444, 446, 447, 420, 421, 422, 433, + 423, 425, 426, 427, 437, 441, 445, 516, 517, 520, + 521, 522, 523, 518, 519, 0, 0, 0, 0, 0, + 0, 0, 0, 164, 165, 0, 620, 137, 530, 531, + 532, 0, 529, 170, 168, 169, 167, 0, 215, 171, + 172, 173, 139, 138, 0, 199, 180, 182, 178, 184, + 186, 181, 183, 179, 185, 187, 176, 177, 201, 188, + 195, 196, 197, 198, 189, 190, 191, 192, 193, 194, + 140, 141, 142, 143, 144, 145, 152, 619, 0, 621, + 0, 114, 113, 0, 125, 130, 159, 158, 156, 160, + 0, 153, 155, 161, 135, 211, 157, 528, 0, 616, + 618, 0, 0, 162, 163, 527, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, + 0, 99, 0, 94, 0, 109, 0, 121, 115, 123, + 0, 124, 0, 97, 131, 102, 0, 154, 136, 0, + 204, 210, 1, 617, 0, 0, 0, 96, 0, 0, + 0, 628, 0, 681, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 626, + 0, 624, 0, 0, 533, 149, 151, 0, 147, 202, + 0, 0, 100, 0, 0, 622, 110, 116, 120, 122, + 118, 126, 117, 0, 132, 105, 0, 103, 0, 0, + 0, 9, 0, 43, 42, 44, 41, 5, 6, 7, + 8, 2, 16, 14, 15, 17, 10, 11, 12, 13, + 3, 18, 37, 20, 25, 26, 0, 0, 30, 0, + 213, 0, 36, 34, 0, 205, 111, 0, 95, 0, + 0, 679, 0, 636, 0, 0, 0, 0, 0, 653, + 0, 0, 0, 0, 0, 0, 0, 673, 0, 651, + 0, 0, 0, 0, 98, 0, 0, 0, 537, 0, + 0, 146, 0, 200, 0, 206, 45, 49, 52, 55, + 60, 63, 65, 67, 69, 71, 73, 75, 0, 0, + 101, 564, 573, 577, 0, 0, 0, 598, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 78, 91, 0, 551, 0, 161, 135, 554, 575, 553, + 561, 552, 0, 555, 556, 579, 557, 586, 558, 559, + 594, 560, 0, 119, 0, 127, 0, 545, 134, 0, + 0, 107, 0, 104, 38, 39, 0, 22, 23, 0, + 0, 28, 27, 0, 215, 31, 33, 40, 0, 212, + 112, 683, 0, 684, 629, 0, 0, 682, 648, 644, + 645, 646, 647, 0, 642, 0, 93, 649, 0, 0, + 663, 664, 665, 666, 0, 661, 0, 667, 0, 0, + 669, 0, 0, 0, 2, 677, 678, 0, 675, 0, + 0, 623, 625, 0, 543, 0, 541, 536, 538, 0, + 150, 148, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 75, 191, 192, 0, 187, 92, 144, 142, 0, - 0, 494, 0, 492, 487, 489, 557, 556, 0, 548, - 0, 560, 558, 0, 0, 0, 541, 544, 0, 511, - 0, 80, 81, 83, 82, 85, 86, 87, 88, 89, - 84, 79, 0, 0, 526, 522, 524, 528, 535, 543, - 123, 0, 499, 0, 127, 0, 105, 16, 0, 23, - 20, 31, 45, 46, 47, 50, 49, 52, 53, 57, - 58, 55, 56, 60, 61, 63, 65, 67, 69, 71, - 73, 0, 193, 485, 0, 495, 0, 490, 0, 0, - 0, 559, 0, 540, 0, 571, 0, 569, 513, 78, - 91, 122, 497, 0, 103, 18, 0, 491, 493, 0, - 551, 550, 553, 519, 536, 532, 0, 0, 0, 0, - 0, 0, 0, 498, 500, 0, 0, 552, 0, 0, - 531, 0, 0, 529, 0, 0, 0, 0, 568, 570, - 514, 76, 0, 554, 0, 519, 518, 520, 538, 0, - 516, 545, 515, 572, 0, 555, 549, 530, 539, 0, - 533, 547, 537 + 0, 0, 76, 207, 208, 0, 563, 0, 596, 609, + 608, 0, 600, 0, 612, 610, 0, 0, 0, 593, + 613, 614, 615, 562, 81, 82, 84, 83, 86, 87, + 88, 89, 90, 85, 80, 0, 0, 578, 574, 576, + 580, 587, 595, 129, 0, 548, 549, 0, 133, 0, + 108, 4, 0, 24, 21, 32, 214, 632, 634, 0, + 0, 680, 0, 638, 0, 637, 0, 640, 0, 0, + 655, 0, 654, 0, 657, 0, 0, 659, 0, 0, + 674, 0, 671, 0, 652, 627, 0, 544, 0, 539, + 534, 46, 47, 48, 51, 50, 53, 54, 58, 59, + 56, 57, 61, 62, 64, 66, 68, 70, 72, 74, + 0, 209, 565, 0, 0, 0, 0, 611, 0, 592, + 79, 92, 128, 546, 0, 106, 19, 630, 0, 631, + 0, 643, 0, 650, 0, 662, 0, 668, 0, 670, + 0, 0, 676, 540, 542, 0, 0, 584, 0, 0, + 0, 603, 602, 605, 571, 588, 547, 550, 633, 635, + 639, 641, 656, 658, 660, 672, 0, 566, 0, 0, + 0, 604, 0, 0, 583, 0, 0, 581, 0, 77, + 0, 568, 597, 567, 0, 606, 0, 571, 570, 572, + 590, 585, 0, 607, 601, 582, 591, 0, 599, 589 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, - -657, -657, -305, -657, -373, -372, -429, -376, -323, -294, - -324, -295, -293, -296, -657, -370, -657, -394, -657, -383, - -414, 1, -657, -657, -657, 2, -657, -657, -657, -114, - -109, -111, -657, -657, -613, -657, -657, -657, -657, -198, - -657, -335, -342, -657, 6, -657, 0, -350, -657, -70, - -657, -657, -657, -444, -450, -292, -371, -494, -657, -375, - -462, -656, -415, -657, -657, -427, -426, -657, -657, -93, - -563, -366, -657, -232, -657, -387, -657, -230, -657, -657, - -657, -657, -229, -657, -657, -657, -657, -657, -657, -657, - -657, -76, -657, -657, -657, -657, -391 + -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, + -863, -863, -418, -863, -380, -379, -484, -382, -258, -256, + -253, -257, -252, -255, -863, -478, -863, -485, -863, -491, + -530, 14, -863, -863, -863, 7, -397, -863, -863, 44, + 53, 47, -863, -863, -400, -863, -863, -863, -863, -92, + -863, -377, -362, -863, 9, -863, 0, -414, -863, -863, + -863, -863, 150, -863, -863, -863, -546, -548, -218, -331, + -624, -863, -359, -609, -862, -863, -417, -863, -863, -427, + -426, -863, -863, 68, -719, -355, -863, -136, -863, -389, + -863, -135, -863, -863, -863, -863, -129, -863, -863, -863, + -863, -863, -863, -863, -863, 102, -863, -863, 2, -863, + -65, -234, -432, -863, -863, -863, -301, -293, -294, -863, + -863, -304, -299, -302, -298, -863, -296, -305, -863, -383, + -526 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 430, 431, 432, 608, 433, 434, 435, 436, 437, - 438, 439, 484, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 485, 631, 486, 592, 487, - 557, 488, 334, 514, 408, 489, 336, 337, 338, 368, - 369, 370, 339, 340, 341, 342, 343, 344, 388, 389, - 345, 346, 347, 348, 454, 385, 455, 381, 351, 352, - 353, 462, 391, 465, 466, 562, 563, 512, 603, 492, - 493, 494, 495, 580, 672, 701, 680, 681, 682, 702, - 496, 497, 498, 499, 683, 668, 500, 501, 684, 709, - 502, 503, 504, 644, 568, 639, 662, 678, 679, 505, - 354, 355, 356, 365, 506, 646, 647 + -1, 520, 521, 522, 782, 523, 524, 525, 526, 527, + 528, 529, 609, 531, 577, 578, 579, 580, 581, 582, + 583, 584, 585, 586, 587, 610, 840, 611, 765, 612, + 695, 613, 378, 640, 498, 614, 380, 381, 382, 427, + 428, 429, 383, 384, 385, 386, 387, 388, 477, 478, + 389, 390, 391, 392, 532, 480, 533, 483, 440, 441, + 534, 395, 396, 397, 569, 473, 567, 568, 705, 706, + 638, 777, 617, 618, 619, 620, 621, 737, 876, 912, + 904, 905, 906, 913, 622, 623, 624, 625, 907, 879, + 626, 627, 908, 927, 628, 629, 630, 843, 741, 845, + 883, 902, 903, 631, 398, 399, 400, 424, 632, 470, + 471, 450, 451, 789, 790, 402, 673, 674, 678, 403, + 404, 684, 685, 688, 691, 405, 697, 698, 406, 452, + 453 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1384,81 +1685,102 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 350, 333, 335, 371, 378, 471, 349, 472, 473, 511, - 453, 476, 394, 386, 600, 565, 602, 648, 559, 604, - 362, 359, 550, 539, 540, 404, 697, 521, 522, 378, - 700, 666, 371, 402, 596, 380, 357, 380, 700, 456, - 364, 520, 403, 358, 529, 393, -34, 468, 523, 666, - 507, 509, 524, 375, 380, 456, 463, 551, 541, 542, - 360, 508, 513, 405, 456, 363, 406, 457, 460, 407, - 605, 601, 366, 458, 461, 440, 581, 582, 583, 584, - 585, 586, 587, 588, 589, 590, 554, 537, 538, 556, - 526, 607, 573, 663, 575, 591, 527, 593, 664, 593, - 373, 670, 704, 374, 593, 671, 638, 651, 593, 565, - 619, 620, 621, 622, 511, 384, 511, 518, 519, 511, - 516, 378, 593, 517, 367, 594, 636, 463, 593, 637, - 463, 641, 390, 611, 636, 708, 531, 657, 400, 652, - 609, 653, 329, 330, 331, 532, 533, 534, 535, 380, - 536, 440, 543, 544, 440, 565, 593, 643, 395, 674, - 593, 675, 615, 616, 401, 617, 618, 623, 624, 459, - 456, 467, 515, 525, 530, 548, 547, 545, 546, 463, - 549, 552, 555, 561, 569, 566, 596, 640, 576, 567, - 570, 642, 571, 574, 577, 606, 610, 578, 649, 650, - -35, 579, -33, 645, -28, 710, 659, 511, 632, 655, - 669, 635, 676, -517, 685, 593, 686, 688, 690, 695, - 694, 693, 625, 627, 463, 481, 698, 612, 613, 614, - 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, - 440, 440, 440, 440, 440, 440, 596, 703, 656, 699, - 712, 711, 626, 628, 630, 687, 629, 398, 397, 511, - 399, 665, 361, 558, 660, 658, 696, 706, 634, 707, - 463, 387, 396, 661, 597, 677, 598, 599, 383, 665, - 689, 691, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 692, 0, 0, 0, 0, 0, 556, - 0, 0, 0, 0, 0, 511, 0, 0, 0, 667, - 705, 0, 0, 0, 0, 0, 0, 0, 0, 479, - 0, 0, 0, 0, 0, 378, 0, 667, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 372, 0, - 0, 0, 0, 0, 349, 0, 379, 0, 0, 0, - 0, 0, 349, 0, 350, 333, 335, 0, 0, 0, - 349, 392, 0, 0, 440, 0, 0, 372, 0, 0, - 0, 372, 0, 349, 0, 0, 0, 349, 0, 0, + 394, 445, 401, 588, 444, 430, 445, 379, 637, 393, + 773, 646, 776, 769, 377, 778, 667, 677, 842, 708, + 494, 530, 687, 709, 446, 668, 535, 421, 437, 446, + 466, 700, 667, 787, 720, 721, 731, 911, 475, 661, + 710, 661, 662, 655, 919, 658, 492, 417, 481, 430, + 328, 329, 330, 422, 911, 493, 481, 659, 669, 670, + 671, 672, 476, 576, 482, 647, 648, 788, 437, 676, + 722, 723, 732, 663, 676, 663, 633, 635, 589, 418, + 676, 644, 645, 676, 437, -35, 590, 649, 481, 407, + 432, 650, 676, 433, 779, 634, 565, 754, 755, 756, + 757, 758, 759, 760, 761, 762, 763, 716, 664, 717, + 746, 735, 748, 657, 664, 589, 664, 764, 589, 664, + 541, 664, 639, 664, 664, 774, 542, 495, 664, 576, + 496, 543, 844, 497, 576, 549, 557, 544, 571, 573, + 576, 550, 558, 576, 572, 574, 853, 652, 854, 637, + 852, 637, 576, 653, 637, 415, 781, 665, 783, 791, + 793, 708, 766, 795, 797, 542, 794, 408, 785, 796, + 798, 576, 409, 693, 456, 458, 460, 462, 464, 465, + 468, 800, 802, 804, 423, 807, 410, 801, 803, 805, + 565, 808, 565, 810, 812, 426, 884, 425, 885, 811, + 813, 926, 766, 437, 766, 890, 891, 892, 893, 894, + 895, 794, 798, 801, 805, 808, 813, 922, 562, 411, + 857, 859, 563, 766, 858, 860, 680, 681, 682, 683, + 887, 708, 445, 769, 412, 444, 828, 829, 830, 831, + 786, 718, 719, 454, 457, 459, 455, 455, 455, 413, + 642, 439, 846, 643, 461, 446, 848, 455, 463, 467, + 414, 455, 455, 565, 675, 724, 725, 455, 863, 677, + 679, 686, 419, 455, 455, 867, 687, 766, 849, 689, + 850, 851, 455, 420, 692, 667, 921, 455, 699, 637, + 817, 455, 713, 714, 715, 821, 822, 823, 576, 576, + 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, + 576, 576, 576, 576, 434, 766, 818, 769, 767, 819, + 676, 676, 766, 818, 447, 847, 873, 676, 676, 766, + 896, 449, 565, 676, 469, 676, 824, 825, 474, 826, + 827, 479, 832, 833, 484, 325, 490, 491, 481, 875, + 539, 536, 877, 537, 538, 540, 545, 641, 726, 546, + 547, 548, 551, 559, 552, 666, 553, 554, 555, 637, + 561, 556, 560, 651, 656, 589, 564, 570, 492, 662, + 576, 576, 431, 690, 701, 729, 730, 576, 576, 728, + 438, 393, 877, 576, 733, 576, 727, 736, 394, 393, + 401, 394, 565, 704, 738, 379, 394, 393, 401, 914, + 393, 909, 377, 448, 742, 393, 472, 739, 712, 740, + 743, 744, 747, 749, 923, 637, 431, 486, 750, 751, + 431, 752, -36, 753, -34, 393, 780, 784, -29, 393, + 792, 869, 799, 878, 814, 806, 438, 809, 815, 841, + 880, 856, 766, 888, 897, 393, 899, 889, 900, 910, + -569, 898, 915, 916, 917, 591, 446, 920, 834, 928, + 929, 835, 837, 566, 488, 836, 839, 489, 838, 487, + 711, 416, 393, 878, 616, 816, 881, 874, 918, 924, + 882, 925, 485, 615, 901, 862, 770, 771, 702, 866, + 443, 861, 865, 772, 868, 864, 446, 0, 872, 0, + 0, 870, 0, 0, 0, 871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 464, 0, 0, 0, 491, 0, 349, 0, 0, - 0, 490, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 660, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 696, 0, + 0, 0, 0, 0, 0, 703, 0, 566, 0, 566, + 0, 0, 0, 0, 393, 0, 393, 0, 393, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, + 0, 615, 394, 0, 0, 0, 0, 0, 0, 0, + 566, 393, 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 464, 560, 0, 464, 0, 0, 349, 349, - 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 566, + 0, 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 491, 0, 0, 0, - 0, 0, 490, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 464, 0, 0, 0, 0, 0, - 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, + 0, 616, 0, 0, 0, 0, 615, 0, 0, 0, + 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 566, + 0, 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 464, - 0, 0, 0, 0, 0, 349, 0, 0, 491, 0, - 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, - 491, 0, 0, 0, 0, 0, 490, 0, 0, 0, + 0, 696, 0, 696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 464, 0, 0, 0, 0, - 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, - 0, 0, 0, 0, 491, 490, 0, 0, 491, 0, - 490, 0, 0, 0, 490, 0, 0, 0, 0, 0, - 0, 0, 491, 0, 0, 0, 0, 379, 490, 0, - 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, - 0, 0, 491, 0, 0, 0, 491, 0, 490, 0, - 0, 0, 490, 0, 491, 0, 0, 0, 491, 0, - 490, 0, 0, 0, 490, 0, 0, 0, 491, 0, - 0, 0, 382, 0, 490, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, + 0, 0, 616, 616, 0, 616, 0, 401, 0, 0, + 0, 615, 615, 0, 615, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 0, 615, 0, 0, 0, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 616, 0, 615, 0, + 0, 0, 0, 0, 0, 615, 616, 0, 0, 0, + 616, 0, 0, 0, 0, 615, 616, 0, 0, 615, + 0, 0, 0, 442, 0, 615, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, @@ -1489,56 +1811,21 @@ static const yytype_int16 yytable[] = 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, + 0, 0, 326, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 327, 328, 329, 330, + 331, 0, 0, 0, 0, 0, 0, 0, 0, 332, + 333, 334, 335, 336, 337, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 326, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 327, 328, 329, 330, 331, 332, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 469, 470, 471, 0, 472, - 473, 474, 475, 476, 477, 478, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 479, 409, 325, 410, 411, 412, 413, 414, 415, - 416, 417, 418, 419, 420, 421, 0, 0, 422, 423, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 424, 0, 480, - 0, 481, 482, 0, 0, 0, 0, 483, 426, 427, - 428, 429, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 327, 328, 329, 330, 331, 332, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 469, 470, 471, 0, - 472, 473, 474, 475, 476, 477, 478, 20, 21, 22, + 0, 339, 340, 341, 342, 343, 344, 0, 0, 0, + 0, 0, 0, 0, 0, 345, 0, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, @@ -1569,56 +1856,21 @@ static const yytype_int16 yytable[] = 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 479, 409, 325, 410, 411, 412, 413, 414, - 415, 416, 417, 418, 419, 420, 421, 0, 0, 422, - 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 424, 0, - 480, 0, 481, 595, 0, 0, 0, 0, 483, 426, - 427, 428, 429, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 327, 328, 329, 330, 331, 332, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 469, 470, 471, - 0, 472, 473, 474, 475, 476, 477, 478, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, - 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 479, 409, 325, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 0, 0, - 422, 423, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 424, - 0, 480, 0, 481, 0, 0, 0, 0, 0, 483, - 426, 427, 428, 429, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 327, 328, 329, 330, 331, 332, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 469, 470, - 471, 0, 472, 473, 474, 475, 476, 477, 478, 20, + 323, 324, 0, 0, 499, 500, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 501, 502, 0, 325, 0, 591, 592, + 0, 0, 0, 0, 593, 503, 504, 505, 506, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 327, 328, + 329, 330, 331, 0, 0, 0, 507, 508, 509, 510, + 511, 332, 333, 334, 335, 336, 337, 338, 594, 595, + 596, 597, 0, 598, 599, 600, 601, 602, 603, 604, + 605, 606, 607, 339, 340, 341, 342, 343, 344, 512, + 513, 514, 515, 516, 517, 518, 519, 345, 608, 346, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, @@ -1649,57 +1901,22 @@ static const yytype_int16 yytable[] = 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 479, 409, 325, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 0, - 0, 422, 423, 0, 0, 0, 0, 0, 0, 0, + 321, 322, 323, 324, 0, 0, 499, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 424, 0, 480, 0, 395, 0, 0, 0, 0, 0, - 483, 426, 427, 428, 429, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 327, 328, 329, 330, 331, 332, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 469, - 470, 471, 0, 472, 473, 474, 475, 476, 477, 478, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 479, 409, 325, 410, 411, - 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, - 0, 0, 422, 423, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 424, 0, 480, 0, 0, 0, 0, 0, 0, - 0, 483, 426, 427, 428, 429, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 327, 328, 329, 330, 331, - 332, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 0, 0, 0, 0, 0, 501, 502, 0, 325, 0, + 591, 768, 0, 0, 0, 0, 593, 503, 504, 505, + 506, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 327, 328, 329, 330, 331, 0, 0, 0, 507, 508, + 509, 510, 511, 332, 333, 334, 335, 336, 337, 338, + 594, 595, 596, 597, 0, 598, 599, 600, 601, 602, + 603, 604, 605, 606, 607, 339, 340, 341, 342, 343, + 344, 512, 513, 514, 515, 516, 517, 518, 519, 345, + 608, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, @@ -1729,711 +1946,22 @@ static const yytype_int16 yytable[] = 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 0, 409, 325, 410, - 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, - 421, 0, 0, 422, 423, 0, 0, 0, 0, 0, + 319, 320, 321, 322, 323, 324, 0, 0, 499, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 424, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 483, 426, 427, 428, 429, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 327, 328, 329, 330, - 331, 332, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 0, 0, 325, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 326, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 327, 328, 329, - 330, 331, 332, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 0, 409, - 325, 410, 411, 412, 413, 414, 415, 416, 417, 418, - 419, 420, 421, 0, 0, 422, 423, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 424, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 426, 427, 428, 429, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 327, 328, - 329, 330, 331, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 0, 376, - 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 377, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 327, 328, - 329, 330, 331, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 0, 0, - 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 564, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 327, 328, - 329, 330, 331, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 0, 0, - 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 633, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 327, 328, - 329, 330, 331, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 0, 0, - 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 654, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 327, 328, - 329, 330, 331, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 0, 0, - 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 4, 5, 6, 7, 0, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 0, 0, 0, 0, 0, 0, 0, 327, 328, - 329, 330, 331, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 0, 409, 325, - 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, - 420, 421, 0, 0, 422, 423, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 424, 0, 0, 0, 510, 673, 0, - 0, 0, 0, 0, 426, 427, 428, 429, 3, 4, - 5, 6, 7, 0, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 0, 409, 325, 410, 411, 412, 413, 414, 415, - 416, 417, 418, 419, 420, 421, 0, 0, 422, 423, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 424, 0, 0, - 425, 0, 0, 0, 0, 0, 0, 0, 426, 427, - 428, 429, 3, 4, 5, 6, 7, 0, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 0, 409, 325, 410, 411, - 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, - 0, 0, 422, 423, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 424, 0, 0, 0, 510, 0, 0, 0, 0, - 0, 0, 426, 427, 428, 429, 3, 4, 5, 6, - 7, 0, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, - 409, 325, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 0, 0, 422, 423, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 424, 0, 0, 553, 0, - 0, 0, 0, 0, 0, 0, 426, 427, 428, 429, - 3, 4, 5, 6, 7, 0, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, - 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 0, 409, 325, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 0, 0, - 422, 423, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 424, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 572, - 426, 427, 428, 429, 3, 4, 5, 6, 7, 0, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 0, 409, 325, - 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, - 420, 421, 0, 0, 422, 423, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 424, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 426, 427, 428, 429, 3, 4, - 5, 6, 7, 0, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 528, 0, 409, 325, 410, 411, 412, 413, 414, 415, - 416, 417, 418, 419, 420, 421, 0, 0, 422, 423, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 424, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 426, 427, - 428, 429, 3, 4, 5, 6, 7, 0, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 0, 0, 325 -}; - -static const yytype_int16 yycheck[] = -{ - 0, 0, 0, 338, 346, 24, 0, 26, 27, 403, - 380, 30, 362, 81, 508, 465, 510, 580, 462, 513, - 339, 339, 362, 357, 358, 375, 682, 355, 356, 371, - 686, 644, 367, 374, 496, 376, 374, 376, 694, 376, - 384, 424, 383, 374, 438, 384, 374, 384, 376, 662, - 400, 401, 380, 339, 376, 376, 391, 397, 392, 393, - 378, 383, 383, 378, 376, 384, 381, 375, 375, 384, - 514, 383, 375, 381, 381, 380, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 456, 353, 354, 459, - 375, 375, 475, 375, 477, 383, 381, 381, 375, 381, - 381, 377, 375, 384, 381, 381, 568, 601, 381, 559, - 539, 540, 541, 542, 508, 339, 510, 422, 423, 513, - 381, 463, 381, 384, 381, 384, 381, 462, 381, 384, - 465, 384, 378, 527, 381, 698, 441, 384, 339, 379, - 523, 381, 400, 401, 402, 389, 390, 391, 386, 376, - 388, 456, 359, 360, 459, 605, 381, 382, 378, 653, - 381, 382, 535, 536, 339, 537, 538, 543, 544, 383, - 376, 384, 339, 375, 374, 361, 394, 396, 395, 514, - 363, 377, 339, 339, 374, 384, 648, 570, 382, 384, - 374, 574, 384, 374, 374, 339, 339, 376, 592, 593, - 374, 379, 374, 339, 375, 699, 338, 601, 377, 377, - 374, 561, 374, 378, 339, 381, 375, 377, 379, 25, - 375, 384, 545, 547, 559, 378, 378, 532, 533, 534, - 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, - 545, 546, 547, 548, 549, 550, 708, 375, 631, 383, - 379, 384, 546, 548, 550, 669, 549, 371, 367, 653, - 371, 644, 332, 461, 639, 636, 681, 694, 560, 695, - 605, 339, 365, 639, 506, 662, 506, 506, 354, 662, - 671, 675, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 676, -1, -1, -1, -1, -1, 669, - -1, -1, -1, -1, -1, 699, -1, -1, -1, 644, - 693, -1, -1, -1, -1, -1, -1, -1, -1, 338, - -1, -1, -1, -1, -1, 667, -1, 662, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 338, -1, - -1, -1, -1, -1, 338, -1, 346, -1, -1, -1, - -1, -1, 346, -1, 354, 354, 354, -1, -1, -1, - 354, 361, -1, -1, 669, -1, -1, 367, -1, -1, - -1, 371, -1, 367, -1, -1, -1, 371, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 391, -1, -1, -1, 395, -1, 391, -1, -1, - -1, 395, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 462, 463, -1, 465, -1, -1, 462, 463, - -1, 465, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 496, -1, -1, -1, - -1, -1, 496, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 514, -1, -1, -1, -1, -1, - 514, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 559, - -1, -1, -1, -1, -1, 559, -1, -1, 568, -1, - -1, -1, -1, -1, 568, -1, -1, -1, -1, -1, - 580, -1, -1, -1, -1, -1, 580, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 605, -1, -1, -1, -1, - -1, 605, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 639, - -1, -1, -1, -1, 644, 639, -1, -1, 648, -1, - 644, -1, -1, -1, 648, -1, -1, -1, -1, -1, - -1, -1, 662, -1, -1, -1, -1, 667, 662, -1, - -1, -1, -1, 667, -1, -1, -1, -1, -1, -1, - -1, -1, 682, -1, -1, -1, 686, -1, 682, -1, - -1, -1, 686, -1, 694, -1, -1, -1, 698, -1, - 694, -1, -1, -1, 698, -1, -1, -1, 708, -1, - -1, -1, 0, -1, 708, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, - -1, -1, 340, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 384, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 398, 399, 400, 401, 402, 403, 3, 4, 5, 6, + 0, 0, 0, 0, 0, 0, 0, 501, 502, 0, + 325, 0, 591, 0, 0, 0, 0, 0, 593, 503, + 504, 505, 506, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 327, 328, 329, 330, 331, 0, 0, 0, + 507, 508, 509, 510, 511, 332, 333, 334, 335, 336, + 337, 338, 594, 595, 596, 597, 0, 598, 599, 600, + 601, 602, 603, 604, 605, 606, 607, 339, 340, 341, + 342, 343, 344, 512, 513, 514, 515, 516, 517, 518, + 519, 345, 608, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, -1, 26, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, @@ -2463,58 +1991,23 @@ static const yytype_int16 yycheck[] = 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, 350, 351, 352, -1, -1, 355, 356, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 374, -1, 376, - -1, 378, 379, -1, -1, -1, -1, 384, 385, 386, - 387, 388, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 398, 399, 400, 401, 402, 403, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, -1, -1, 355, - 356, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 374, -1, - 376, -1, 378, 379, -1, -1, -1, -1, 384, 385, - 386, 387, 388, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 398, 399, 400, 401, 402, 403, 3, 4, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 0, + 499, 500, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, + 502, 0, 325, 0, 484, 0, 0, 0, 0, 0, + 593, 503, 504, 505, 506, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 327, 328, 329, 330, 331, 0, + 0, 0, 507, 508, 509, 510, 511, 332, 333, 334, + 335, 336, 337, 338, 594, 595, 596, 597, 0, 598, + 599, 600, 601, 602, 603, 604, 605, 606, 607, 339, + 340, 341, 342, 343, 344, 512, 513, 514, 515, 516, + 517, 518, 519, 345, 608, 346, 347, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, @@ -2544,57 +2037,22 @@ static const yytype_int16 yycheck[] = 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, -1, -1, - 355, 356, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 374, - -1, 376, -1, 378, -1, -1, -1, -1, -1, 384, - 385, 386, 387, 388, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 398, 399, 400, 401, 402, 403, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, -1, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 345, 346, 347, 348, 349, 350, 351, 352, -1, - -1, 355, 356, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 374, -1, 376, -1, 378, -1, -1, -1, -1, -1, - 384, 385, 386, 387, 388, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 398, 399, 400, 401, 402, 403, + 0, 0, 499, 500, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 501, 502, 0, 325, 0, 0, 0, 0, 0, + 0, 0, 593, 503, 504, 505, 506, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 327, 328, 329, 330, + 331, 0, 0, 0, 507, 508, 509, 510, 511, 332, + 333, 334, 335, 336, 337, 338, 594, 595, 596, 597, + 0, 598, 599, 600, 601, 602, 603, 604, 605, 606, + 607, 339, 340, 341, 342, 343, 344, 512, 513, 514, + 515, 516, 517, 518, 519, 345, 608, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, @@ -2624,20 +2082,605 @@ static const yytype_int16 yycheck[] = 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - -1, -1, 355, 356, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 374, -1, 376, -1, -1, -1, -1, -1, -1, - -1, 384, 385, 386, 387, 388, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 398, 399, 400, 401, 402, - 403, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 323, 324, 0, 0, 499, 500, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 501, 502, 0, 325, 0, 0, 0, + 0, 0, 0, 0, 593, 503, 504, 505, 506, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 327, 328, + 329, 330, 331, 0, 0, 0, 507, 508, 509, 510, + 511, 332, 333, 334, 335, 336, 337, 338, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 339, 340, 341, 342, 343, 344, 512, + 513, 514, 515, 516, 517, 518, 519, 345, 0, 346, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 0, 0, 0, 318, 319, 320, + 321, 322, 323, 324, 0, 0, 499, 500, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 501, 502, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 503, 504, 505, + 506, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 327, 328, 329, 330, 0, 0, 0, 0, 507, 508, + 509, 510, 511, 332, 333, 334, 335, 336, 337, 338, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 339, 340, 341, 342, 343, + 344, 512, 513, 514, 515, 516, 517, 518, 519, 345, + 0, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 325, 0, 0, 0, 0, 0, 0, 0, 326, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 327, 328, 329, 330, 331, 0, 0, 0, + 0, 0, 0, 0, 0, 332, 333, 334, 335, 336, + 337, 338, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 340, 341, + 342, 343, 344, 0, 0, 0, 0, 0, 0, 0, + 0, 345, 0, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 0, 0, + 0, 318, 319, 320, 321, 322, 323, 324, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 327, 328, 329, 330, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 332, 333, 334, + 335, 336, 337, 338, 594, 0, 0, 597, 0, 598, + 599, 0, 0, 602, 0, 0, 0, 0, 0, 339, + 340, 341, 342, 343, 344, 0, 0, 0, 0, 0, + 0, 0, 0, 345, 0, 346, 347, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 0, 0, 0, 318, 319, 320, 321, 322, 323, 324, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 327, 328, 329, 330, + 0, 0, 0, 0, 0, 0, 0, 0, 436, 332, + 333, 334, 335, 336, 337, 338, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 340, 341, 342, 343, 344, 0, 0, 0, + 0, 0, 0, 0, 0, 345, 0, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 0, 0, 0, 318, 319, 320, 321, 322, + 323, 324, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 327, 328, + 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 332, 333, 334, 335, 336, 337, 338, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 339, 340, 341, 342, 343, 344, 0, + 0, 0, 0, 0, 0, 0, 0, 345, 0, 346, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 0, 0, 0, 318, 319, 320, + 321, 322, 323, 324, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 707, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 327, 328, 329, 330, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 332, 333, 334, 335, 336, 337, 338, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 339, 340, 341, 342, 343, + 344, 0, 0, 0, 0, 0, 0, 0, 0, 345, + 0, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 0, 0, 0, 318, + 319, 320, 321, 322, 323, 324, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 820, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 327, 328, 329, 330, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 332, 333, 334, 335, 336, + 337, 338, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 340, 341, + 342, 343, 344, 0, 0, 0, 0, 0, 0, 0, + 0, 345, 0, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 0, 0, + 0, 318, 319, 320, 321, 322, 323, 324, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 855, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 327, 328, 329, 330, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 332, 333, 334, + 335, 336, 337, 338, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 339, + 340, 341, 342, 343, 344, 0, 0, 0, 0, 0, + 0, 0, 0, 345, 0, 346, 347, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 0, 0, 0, 318, 319, 320, 321, 322, 323, 324, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 327, 328, 329, 330, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, + 333, 334, 335, 336, 337, 338, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 340, 341, 342, 343, 344, 0, 0, 0, + 0, 0, 0, 0, 0, 345, 0, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 0, 0, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, + 314, 0, 0, 0, 0, 0, 0, 321, 0, 0, + 0, 0, 0, 499, 500, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 501, 502, 0, 0, 0, 636, 775, 0, + 0, 0, 0, 0, 503, 504, 505, 506, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 507, 508, 509, 510, 511, + 332, 0, 0, 0, 0, 337, 338, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 512, 513, + 514, 515, 516, 517, 518, 519, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 358, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 0, 0, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 0, 0, 0, 0, 0, 0, + 321, 0, 0, 0, 0, 0, 499, 500, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 501, 502, 0, 0, 0, + 636, 886, 0, 0, 0, 0, 0, 503, 504, 505, + 506, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 507, 508, + 509, 510, 511, 332, 0, 0, 0, 0, 337, 338, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 512, 513, 514, 515, 516, 517, 518, 519, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 358, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 0, 0, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 0, 0, 0, + 0, 0, 0, 321, 0, 0, 0, 0, 0, 499, + 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 501, 502, + 0, 0, 575, 0, 0, 0, 0, 0, 0, 0, + 503, 504, 505, 506, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 507, 508, 509, 510, 511, 332, 0, 0, 0, + 0, 337, 338, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 512, 513, 514, 515, 516, 517, + 518, 519, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 358, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 0, 0, 0, 0, 0, 0, 321, 0, 0, 0, + 0, 0, 499, 500, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 501, 502, 0, 0, 0, 636, 0, 0, 0, + 0, 0, 0, 503, 504, 505, 506, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 507, 508, 509, 510, 511, 332, + 0, 0, 0, 0, 337, 338, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 512, 513, 514, + 515, 516, 517, 518, 519, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 358, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 52, 53, 54, 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, @@ -2663,19 +2706,468 @@ static const yytype_int16 yycheck[] = 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, - 332, 333, 334, 335, 336, 337, -1, 339, 340, 341, - 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, - 352, -1, -1, 355, 356, -1, -1, -1, -1, -1, + 312, 313, 314, 0, 0, 0, 0, 0, 0, 321, + 0, 0, 0, 0, 0, 499, 500, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 501, 502, 0, 0, 734, 0, + 0, 0, 0, 0, 0, 0, 503, 504, 505, 506, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 507, 508, 509, + 510, 511, 332, 0, 0, 0, 0, 337, 338, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 512, 513, 514, 515, 516, 517, 518, 519, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 358, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 0, 0, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 0, 0, 0, 0, + 0, 0, 321, 0, 0, 0, 0, 0, 499, 500, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 501, 502, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 745, 503, + 504, 505, 506, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 507, 508, 509, 510, 511, 332, 0, 0, 0, 0, + 337, 338, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 512, 513, 514, 515, 516, 517, 518, + 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 358, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 0, 0, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 310, 311, 312, 313, 314, 0, + 0, 0, 0, 0, 0, 321, 0, 0, 0, 0, + 0, 499, 500, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 501, 502, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 503, 504, 505, 506, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 507, 508, 509, 510, 511, 332, 0, + 0, 0, 0, 337, 338, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 512, 513, 514, 515, + 516, 517, 518, 519, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 358, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 0, 0, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 0, 0, 0, 0, 0, 0, 321, 0, + 0, 0, 0, 0, 499, 500, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 501, 502, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 503, 504, 505, 506, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 507, 508, 509, 510, + 511, 332, 0, 0, 0, 0, 337, 654, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, + 513, 514, 515, 516, 517, 518, 519, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 358, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, + 0, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 0, 0, 0, 0, 0, + 0, 321, 0, 0, 0, 0, 0, 499, 500, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 501, 502, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 503, 504, + 505, 506, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 507, + 508, 509, 510, 694, 332, 0, 0, 0, 0, 337, + 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 512, 513, 514, 515, 516, 517, 518, 519, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 358, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 0, 0, + 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 332, 0, 0, + 0, 0, 337, 338 +}; + +static const yytype_int16 yycheck[] = +{ + 0, 401, 0, 481, 401, 382, 406, 0, 493, 0, + 634, 502, 636, 622, 0, 639, 542, 547, 737, 567, + 434, 439, 552, 569, 401, 348, 440, 359, 390, 406, + 413, 561, 558, 348, 331, 332, 336, 899, 385, 348, + 570, 348, 351, 528, 906, 356, 349, 353, 351, 426, + 374, 375, 376, 385, 916, 358, 351, 368, 381, 382, + 383, 384, 409, 481, 359, 329, 330, 382, 430, 547, + 367, 368, 372, 382, 552, 382, 490, 491, 351, 385, + 558, 499, 500, 561, 446, 349, 359, 351, 351, 349, + 356, 355, 570, 359, 640, 358, 473, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 361, 540, 363, + 601, 589, 603, 531, 546, 351, 548, 358, 351, 551, + 350, 553, 358, 555, 556, 358, 356, 353, 560, 547, + 356, 350, 741, 359, 552, 350, 350, 356, 350, 350, + 558, 356, 356, 561, 356, 356, 354, 350, 356, 634, + 774, 636, 570, 356, 639, 351, 350, 540, 649, 350, + 350, 709, 356, 350, 350, 356, 356, 349, 653, 356, + 356, 589, 349, 556, 408, 409, 410, 411, 412, 413, + 414, 350, 350, 350, 359, 350, 349, 356, 356, 356, + 567, 356, 569, 350, 350, 356, 350, 350, 350, 356, + 356, 920, 356, 565, 356, 350, 350, 350, 350, 350, + 350, 356, 356, 356, 356, 356, 356, 350, 352, 349, + 352, 352, 356, 356, 356, 356, 381, 382, 383, 384, + 854, 779, 632, 842, 349, 632, 720, 721, 722, 723, + 658, 327, 328, 382, 382, 382, 385, 385, 385, 349, + 356, 367, 743, 359, 382, 632, 747, 385, 382, 382, + 349, 385, 385, 640, 382, 333, 334, 385, 798, 799, + 382, 382, 349, 385, 385, 805, 806, 356, 357, 382, + 765, 766, 385, 349, 382, 811, 910, 385, 382, 774, + 704, 385, 364, 365, 366, 713, 714, 715, 716, 717, + 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, + 728, 729, 730, 731, 385, 356, 356, 926, 359, 359, + 798, 799, 356, 356, 359, 359, 359, 805, 806, 356, + 357, 385, 709, 811, 385, 813, 716, 717, 353, 718, + 719, 385, 724, 725, 353, 351, 385, 385, 351, 840, + 358, 350, 843, 385, 359, 356, 358, 385, 371, 356, + 356, 356, 356, 350, 356, 385, 356, 356, 356, 854, + 349, 356, 356, 350, 349, 351, 359, 358, 349, 351, + 798, 799, 382, 348, 352, 335, 337, 805, 806, 369, + 390, 382, 883, 811, 352, 813, 370, 354, 398, 390, + 398, 401, 779, 385, 349, 398, 406, 398, 406, 900, + 401, 896, 398, 406, 349, 406, 416, 359, 385, 359, + 349, 359, 349, 357, 915, 910, 426, 425, 359, 359, + 430, 359, 349, 359, 349, 426, 385, 385, 350, 430, + 358, 348, 356, 843, 350, 356, 446, 356, 350, 352, + 393, 352, 356, 348, 354, 446, 350, 382, 349, 358, + 353, 385, 359, 350, 397, 353, 843, 353, 726, 359, + 354, 727, 729, 473, 430, 728, 731, 430, 730, 426, + 572, 331, 473, 883, 484, 703, 845, 818, 905, 916, + 845, 917, 424, 484, 883, 796, 632, 632, 563, 803, + 398, 794, 801, 632, 806, 799, 883, -1, 813, -1, + -1, 809, -1, -1, -1, 811, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 374, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 384, 385, 386, 387, 388, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 398, 399, 400, 401, - 402, 403, 3, 4, 5, 6, 7, 8, 9, 10, + -1, -1, -1, -1, -1, -1, -1, -1, 536, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 558, -1, + -1, -1, -1, -1, -1, 565, -1, 567, -1, 569, + -1, -1, -1, -1, 565, -1, 567, -1, 569, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 622, -1, -1, -1, -1, -1, -1, -1, + -1, 622, 632, -1, -1, -1, -1, -1, -1, -1, + 640, 632, -1, -1, -1, -1, -1, -1, -1, 640, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 709, + -1, -1, -1, -1, -1, -1, -1, -1, 709, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 737, -1, -1, + -1, 741, -1, -1, -1, -1, 737, -1, -1, -1, + 741, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 779, + -1, -1, -1, -1, -1, -1, -1, -1, 779, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 811, -1, 813, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 842, 843, -1, 845, -1, 845, -1, -1, + -1, 842, 843, -1, 845, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 883, -1, -1, -1, -1, -1, -1, + -1, -1, 883, -1, -1, -1, -1, -1, -1, 899, + -1, -1, -1, -1, -1, -1, 906, -1, 899, -1, + -1, -1, -1, -1, -1, 906, 916, -1, -1, -1, + 920, -1, -1, -1, -1, 916, 926, -1, -1, 920, + -1, -1, -1, 0, -1, 926, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 351, -1, -1, -1, -1, -1, + -1, -1, 359, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 373, 374, 375, 376, + 377, -1, -1, -1, -1, -1, -1, -1, -1, 386, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 408, 409, 410, 411, 412, 413, -1, -1, -1, + -1, -1, -1, -1, -1, 422, -1, 424, 425, 426, + 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, + 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, + 447, 448, 449, 450, 451, 452, 453, 454, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, -1, -1, 329, 330, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 348, 349, -1, 351, -1, 353, 354, + -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 373, 374, + 375, 376, 377, -1, -1, -1, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, -1, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, -1, -1, 329, 330, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 348, 349, -1, 351, -1, + 353, 354, -1, -1, -1, -1, 359, 360, 361, 362, + 363, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 373, 374, 375, 376, 377, -1, -1, -1, 381, 382, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, -1, 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, + 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, + 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, + 453, 454, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, @@ -2704,303 +3196,78 @@ static const yytype_int16 yycheck[] = 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 336, 337, -1, -1, 340, + 321, 322, 323, 324, 325, 326, -1, -1, 329, 330, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 384, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 398, 399, 400, - 401, 402, 403, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 334, 335, 336, 337, -1, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - 350, 351, 352, -1, -1, 355, 356, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 374, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 385, 386, 387, 388, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 398, 399, - 400, 401, 402, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 334, 335, 336, 337, -1, 339, - 340, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 384, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 398, 399, - 400, 401, 402, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 334, 335, 336, 337, -1, -1, - 340, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 379, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 398, 399, - 400, 401, 402, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 334, 335, 336, 337, -1, -1, - 340, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 379, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 398, 399, - 400, 401, 402, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 334, 335, 336, 337, -1, -1, - 340, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 379, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 398, 399, - 400, 401, 402, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 334, 335, 336, 337, -1, -1, - 340, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 5, 6, 7, 8, 9, -1, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, -1, -1, -1, -1, -1, -1, -1, 398, 399, - 400, 401, 402, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 82, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 336, 337, -1, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, - 351, 352, -1, -1, 355, 356, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 374, -1, -1, -1, 378, 379, -1, - -1, -1, -1, -1, 385, 386, 387, 388, 5, 6, - 7, 8, 9, -1, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 34, 35, 36, + -1, -1, -1, -1, -1, -1, -1, 348, 349, -1, + 351, -1, 353, -1, -1, -1, -1, -1, 359, 360, + 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 373, 374, 375, 376, 377, -1, -1, -1, + 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, -1, 398, 399, 400, + 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, + 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, + 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, + 451, 452, 453, 454, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 326, -1, -1, + 329, 330, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 348, + 349, -1, 351, -1, 353, -1, -1, -1, -1, -1, + 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 373, 374, 375, 376, 377, -1, + -1, -1, 381, 382, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, -1, 398, + 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, + 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, + 449, 450, 451, 452, 453, 454, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 82, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 131, 132, 133, 134, 135, 136, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, @@ -3020,102 +3287,32 @@ static const yytype_int16 yycheck[] = 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, - 337, -1, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, 350, 351, 352, -1, -1, 355, 356, + -1, -1, 329, 330, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, - 377, -1, -1, -1, -1, -1, -1, -1, 385, 386, - 387, 388, 5, 6, 7, 8, 9, -1, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, -1, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - -1, -1, 355, 356, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 374, -1, -1, -1, 378, -1, -1, -1, -1, - -1, -1, 385, 386, 387, 388, 5, 6, 7, 8, - 9, -1, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 82, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 334, 335, 336, 337, -1, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, -1, -1, 355, 356, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 374, -1, -1, 377, -1, - -1, -1, -1, -1, -1, -1, 385, 386, 387, 388, - 5, 6, 7, 8, 9, -1, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, + -1, 348, 349, -1, 351, -1, -1, -1, -1, -1, + -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 373, 374, 375, 376, + 377, -1, -1, -1, 381, 382, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + -1, 398, 399, 400, 401, 402, 403, 404, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, + 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, + 447, 448, 449, 450, 451, 452, 453, 454, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 98, 99, 100, 101, 102, 103, 104, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 131, 132, 133, 134, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, @@ -3135,131 +3332,22 @@ static const yytype_int16 yycheck[] = 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, -1, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, -1, -1, - 355, 356, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 374, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 384, - 385, 386, 387, 388, 5, 6, 7, 8, 9, -1, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 82, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 336, 337, -1, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, - 351, 352, -1, -1, 355, 356, -1, -1, -1, -1, + 325, 326, -1, -1, 329, 330, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 374, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 385, 386, 387, 388, 5, 6, - 7, 8, 9, -1, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 82, -1, -1, -1, -1, + -1, -1, -1, 348, 349, -1, 351, -1, -1, -1, + -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 373, 374, + 375, 376, 377, -1, -1, -1, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, - 337, -1, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, 350, 351, 352, -1, -1, 355, 356, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 385, 386, - 387, 388, 5, 6, 7, 8, 9, -1, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, -1, -1, 340 -}; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint16 yystos[] = -{ - 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + -1, -1, -1, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, -1, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, @@ -3288,136 +3376,1011 @@ static const yytype_uint16 yystos[] = 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 340, 384, 398, 399, 400, - 401, 402, 403, 438, 439, 442, 443, 444, 445, 449, - 450, 451, 452, 453, 454, 457, 458, 459, 460, 461, - 463, 465, 466, 467, 507, 508, 509, 374, 374, 339, - 378, 466, 339, 384, 384, 510, 375, 381, 446, 447, - 448, 458, 463, 381, 384, 339, 339, 384, 459, 463, - 376, 464, 0, 508, 339, 462, 81, 339, 455, 456, - 378, 469, 463, 384, 464, 378, 486, 447, 446, 448, - 339, 339, 374, 383, 464, 378, 381, 384, 441, 339, - 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, - 351, 352, 355, 356, 374, 377, 385, 386, 387, 388, - 408, 409, 410, 412, 413, 414, 415, 416, 417, 418, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, 461, 463, 376, 375, 381, 383, - 375, 381, 468, 458, 463, 470, 471, 384, 384, 22, - 23, 24, 26, 27, 28, 29, 30, 31, 32, 338, - 376, 378, 379, 384, 419, 432, 434, 436, 438, 442, - 461, 463, 476, 477, 478, 479, 487, 488, 489, 490, - 493, 494, 497, 498, 499, 506, 511, 464, 383, 464, - 378, 434, 474, 383, 440, 339, 381, 384, 419, 419, - 436, 355, 356, 376, 380, 375, 375, 381, 337, 434, - 374, 419, 389, 390, 391, 386, 388, 353, 354, 357, - 358, 392, 393, 359, 360, 396, 395, 394, 361, 363, - 362, 397, 377, 377, 432, 339, 432, 437, 456, 470, - 463, 339, 472, 473, 379, 471, 384, 384, 501, 374, - 374, 384, 384, 436, 374, 436, 382, 374, 376, 379, - 480, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 383, 435, 381, 384, 379, 477, 490, 494, 499, - 474, 383, 474, 475, 474, 470, 339, 375, 411, 436, - 339, 434, 419, 419, 419, 421, 421, 422, 422, 423, - 423, 423, 423, 424, 424, 425, 426, 427, 428, 429, - 430, 433, 377, 379, 472, 464, 381, 384, 477, 502, - 436, 384, 436, 382, 500, 339, 512, 513, 487, 434, - 434, 474, 379, 381, 379, 377, 436, 384, 473, 338, - 476, 488, 503, 375, 375, 436, 451, 458, 492, 374, - 377, 381, 481, 379, 474, 382, 374, 492, 504, 505, - 483, 484, 485, 491, 495, 339, 375, 437, 377, 513, - 379, 434, 436, 384, 375, 25, 479, 478, 378, 383, - 478, 482, 486, 375, 375, 436, 482, 483, 487, 496, - 474, 384, 379 + 313, 314, 315, 316, -1, -1, -1, 320, 321, 322, + 323, 324, 325, 326, -1, -1, 329, 330, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 348, 349, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 360, 361, 362, + 363, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 373, 374, 375, 376, -1, -1, -1, -1, 381, 382, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, + -1, 424, 425, 426, 427, 428, 429, 430, 431, 432, + 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, + 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, + 453, 454, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 325, 326, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 351, -1, -1, -1, -1, -1, -1, -1, 359, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 373, 374, 375, 376, 377, -1, -1, -1, + -1, -1, -1, -1, -1, 386, 387, 388, 389, 390, + 391, 392, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 408, 409, 410, + 411, 412, 413, -1, -1, -1, -1, -1, -1, -1, + -1, 422, -1, 424, 425, 426, 427, 428, 429, 430, + 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, + 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, + 451, 452, 453, 454, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, -1, -1, + -1, 320, 321, 322, 323, 324, 325, 326, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 373, 374, 375, 376, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 386, 387, 388, + 389, 390, 391, 392, 393, -1, -1, 396, -1, 398, + 399, -1, -1, 402, -1, -1, -1, -1, -1, 408, + 409, 410, 411, 412, 413, -1, -1, -1, -1, -1, + -1, -1, -1, 422, -1, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, + 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, + 449, 450, 451, 452, 453, 454, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + -1, -1, -1, 320, 321, 322, 323, 324, 325, 326, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 359, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 373, 374, 375, 376, + -1, -1, -1, -1, -1, -1, -1, -1, 385, 386, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 408, 409, 410, 411, 412, 413, -1, -1, -1, + -1, -1, -1, -1, -1, 422, -1, 424, 425, 426, + 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, + 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, + 447, 448, 449, 450, 451, 452, 453, 454, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, -1, -1, -1, 320, 321, 322, 323, 324, + 325, 326, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 351, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 373, 374, + 375, 376, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 386, 387, 388, 389, 390, 391, 392, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 408, 409, 410, 411, 412, 413, -1, + -1, -1, -1, -1, -1, -1, -1, 422, -1, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, -1, -1, -1, 320, 321, 322, + 323, 324, 325, 326, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 354, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 373, 374, 375, 376, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 386, 387, 388, 389, 390, 391, 392, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 408, 409, 410, 411, 412, + 413, -1, -1, -1, -1, -1, -1, -1, -1, 422, + -1, 424, 425, 426, 427, 428, 429, 430, 431, 432, + 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, + 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, + 453, 454, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 315, 316, -1, -1, -1, 320, + 321, 322, 323, 324, 325, 326, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 354, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 373, 374, 375, 376, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 386, 387, 388, 389, 390, + 391, 392, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 408, 409, 410, + 411, 412, 413, -1, -1, -1, -1, -1, -1, -1, + -1, 422, -1, 424, 425, 426, 427, 428, 429, 430, + 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, + 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, + 451, 452, 453, 454, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, -1, -1, + -1, 320, 321, 322, 323, 324, 325, 326, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 354, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 373, 374, 375, 376, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 386, 387, 388, + 389, 390, 391, 392, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 408, + 409, 410, 411, 412, 413, -1, -1, -1, -1, -1, + -1, -1, -1, 422, -1, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, + 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, + 449, 450, 451, 452, 453, 454, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + -1, -1, -1, 320, 321, 322, 323, 324, 325, 326, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 373, 374, 375, 376, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 386, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 408, 409, 410, 411, 412, 413, -1, -1, -1, + -1, -1, -1, -1, -1, 422, -1, 424, 425, 426, + 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, + 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, + 447, 448, 449, 450, 451, 452, 453, 454, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, -1, -1, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, -1, -1, -1, -1, -1, -1, 323, -1, -1, + -1, -1, -1, 329, 330, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 348, 349, -1, -1, -1, 353, 354, -1, + -1, -1, -1, -1, 360, 361, 362, 363, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 381, 382, 383, 384, 385, + 386, -1, -1, -1, -1, 391, 392, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 414, 415, + 416, 417, 418, 419, 420, 421, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 436, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, -1, -1, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, -1, -1, -1, -1, -1, -1, + 323, -1, -1, -1, -1, -1, 329, 330, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 348, 349, -1, -1, -1, + 353, 354, -1, -1, -1, -1, -1, 360, 361, 362, + 363, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 381, 382, + 383, 384, 385, 386, -1, -1, -1, -1, 391, 392, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 414, 415, 416, 417, 418, 419, 420, 421, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 436, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, -1, -1, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, -1, -1, -1, + -1, -1, -1, 323, -1, -1, -1, -1, -1, 329, + 330, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 348, 349, + -1, -1, 352, -1, -1, -1, -1, -1, -1, -1, + 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 381, 382, 383, 384, 385, 386, -1, -1, -1, + -1, 391, 392, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 414, 415, 416, 417, 418, 419, + 420, 421, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 436, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + -1, -1, -1, -1, -1, -1, 323, -1, -1, -1, + -1, -1, 329, 330, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 348, 349, -1, -1, -1, 353, -1, -1, -1, + -1, -1, -1, 360, 361, 362, 363, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 381, 382, 383, 384, 385, 386, + -1, -1, -1, -1, 391, 392, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 414, 415, 416, + 417, 418, 419, 420, 421, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 436, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, -1, -1, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, + 314, 315, 316, -1, -1, -1, -1, -1, -1, 323, + -1, -1, -1, -1, -1, 329, 330, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 348, 349, -1, -1, 352, -1, + -1, -1, -1, -1, -1, -1, 360, 361, 362, 363, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 381, 382, 383, + 384, 385, 386, -1, -1, -1, -1, 391, 392, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 414, 415, 416, 417, 418, 419, 420, 421, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 436, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + -1, -1, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 315, 316, -1, -1, -1, -1, + -1, -1, 323, -1, -1, -1, -1, -1, 329, 330, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 348, 349, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, + 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 381, 382, 383, 384, 385, 386, -1, -1, -1, -1, + 391, 392, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 414, 415, 416, 417, 418, 419, 420, + 421, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 436, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, -1, -1, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, -1, + -1, -1, -1, -1, -1, 323, -1, -1, -1, -1, + -1, 329, 330, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 348, 349, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 360, 361, 362, 363, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 381, 382, 383, 384, 385, 386, -1, + -1, -1, -1, 391, 392, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 414, 415, 416, 417, + 418, 419, 420, 421, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 436, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, -1, -1, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, -1, -1, -1, -1, -1, -1, 323, -1, + -1, -1, -1, -1, 329, 330, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 348, 349, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 360, 361, 362, 363, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 381, 382, 383, 384, + 385, 386, -1, -1, -1, -1, 391, 392, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 414, + 415, 416, 417, 418, 419, 420, 421, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 436, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, + -1, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, -1, -1, -1, -1, -1, + -1, 323, -1, -1, -1, -1, -1, 329, 330, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 348, 349, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 360, 361, + 362, 363, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 381, + 382, 383, 384, 385, 386, -1, -1, -1, -1, 391, + 392, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 414, 415, 416, 417, 418, 419, 420, 421, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 436, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, -1, -1, + -1, -1, -1, -1, 323, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 386, -1, -1, + -1, -1, 391, 392 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_int16 yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 325, 326, 351, 359, 373, 374, 375, + 376, 377, 386, 387, 388, 389, 390, 391, 392, 408, + 409, 410, 411, 412, 413, 422, 424, 425, 426, 427, + 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, + 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, + 448, 449, 450, 451, 452, 453, 454, 486, 487, 490, + 491, 492, 493, 497, 498, 499, 500, 501, 502, 505, + 506, 507, 508, 509, 511, 516, 517, 518, 559, 560, + 561, 563, 570, 574, 575, 580, 583, 349, 349, 349, + 349, 349, 349, 349, 349, 351, 517, 353, 385, 349, + 349, 359, 385, 359, 562, 350, 356, 494, 495, 496, + 506, 511, 356, 359, 385, 359, 385, 507, 511, 367, + 513, 514, 0, 560, 491, 499, 506, 359, 490, 385, + 566, 567, 584, 585, 382, 385, 566, 382, 566, 382, + 566, 382, 566, 382, 566, 566, 584, 382, 566, 385, + 564, 565, 511, 520, 353, 385, 409, 503, 504, 385, + 510, 351, 359, 512, 353, 538, 563, 495, 494, 496, + 385, 385, 349, 358, 512, 353, 356, 359, 489, 329, + 330, 348, 349, 360, 361, 362, 363, 381, 382, 383, + 384, 385, 414, 415, 416, 417, 418, 419, 420, 421, + 456, 457, 458, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 509, 511, 515, 512, 350, 385, 359, 358, + 356, 350, 356, 350, 356, 358, 356, 356, 356, 350, + 356, 356, 356, 356, 356, 356, 356, 350, 356, 350, + 356, 349, 352, 356, 359, 506, 511, 521, 522, 519, + 358, 350, 356, 350, 356, 352, 467, 469, 470, 471, + 472, 473, 474, 475, 476, 477, 478, 479, 480, 351, + 359, 353, 354, 359, 393, 394, 395, 396, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 407, 423, 467, + 480, 482, 484, 486, 490, 509, 511, 527, 528, 529, + 530, 531, 539, 540, 541, 542, 545, 546, 549, 550, + 551, 558, 563, 512, 358, 512, 353, 482, 525, 358, + 488, 385, 356, 359, 467, 467, 484, 329, 330, 351, + 355, 350, 350, 356, 392, 482, 349, 467, 356, 368, + 563, 348, 351, 382, 567, 584, 385, 585, 348, 381, + 382, 383, 384, 571, 572, 382, 480, 485, 573, 382, + 381, 382, 383, 384, 576, 577, 382, 485, 578, 382, + 348, 579, 382, 584, 385, 485, 511, 581, 582, 382, + 485, 352, 565, 511, 385, 523, 524, 354, 522, 521, + 485, 504, 385, 364, 365, 366, 361, 363, 327, 328, + 331, 332, 367, 368, 333, 334, 371, 370, 369, 335, + 337, 336, 372, 352, 352, 480, 354, 532, 349, 359, + 359, 553, 349, 349, 359, 359, 484, 349, 484, 357, + 359, 359, 359, 359, 338, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 358, 483, 356, 359, 354, 528, + 542, 546, 551, 525, 358, 354, 525, 526, 525, 521, + 385, 350, 459, 484, 385, 482, 467, 348, 382, 568, + 569, 350, 358, 350, 356, 350, 356, 350, 356, 356, + 350, 356, 350, 356, 350, 356, 356, 350, 356, 356, + 350, 356, 350, 356, 350, 350, 523, 512, 356, 359, + 354, 467, 467, 467, 469, 469, 470, 470, 471, 471, + 471, 471, 472, 472, 473, 474, 475, 476, 477, 478, + 481, 352, 539, 552, 528, 554, 484, 359, 484, 357, + 482, 482, 525, 354, 356, 354, 352, 352, 356, 352, + 356, 572, 571, 485, 573, 577, 576, 485, 578, 348, + 579, 581, 582, 359, 524, 484, 533, 484, 499, 544, + 393, 527, 540, 555, 350, 350, 354, 525, 348, 382, + 350, 350, 350, 350, 350, 350, 357, 354, 385, 350, + 349, 544, 556, 557, 535, 536, 537, 543, 547, 482, + 358, 529, 534, 538, 484, 359, 350, 397, 531, 529, + 353, 525, 350, 484, 534, 535, 539, 548, 359, 354 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint16 yyr1[] = +static const yytype_int16 yyr1[] = { - 0, 407, 408, 409, 409, 409, 409, 409, 409, 409, - 409, 409, 409, 409, 409, 409, 409, 410, 410, 410, - 410, 410, 410, 411, 412, 413, 414, 414, 415, 415, - 416, 416, 417, 418, 418, 418, 419, 419, 419, 419, - 420, 420, 420, 420, 421, 421, 421, 421, 422, 422, - 422, 423, 423, 423, 424, 424, 424, 424, 424, 425, - 425, 425, 426, 426, 427, 427, 428, 428, 429, 429, - 430, 430, 431, 431, 432, 433, 432, 434, 434, 435, - 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, - 436, 436, 437, 438, 438, 438, 438, 438, 438, 438, - 438, 438, 440, 439, 441, 441, 442, 443, 443, 444, - 444, 445, 446, 446, 447, 447, 447, 447, 448, 449, - 449, 449, 449, 449, 450, 450, 450, 450, 450, 451, - 451, 452, 453, 453, 453, 453, 453, 453, 453, 453, - 454, 455, 455, 456, 456, 456, 457, 458, 458, 459, - 459, 459, 459, 459, 459, 459, 460, 460, 460, 460, - 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, - 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, - 460, 460, 460, 460, 460, 461, 462, 462, 463, 463, - 464, 464, 464, 464, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, - 465, 466, 466, 466, 468, 467, 469, 467, 470, 470, - 471, 471, 472, 472, 473, 473, 474, 474, 474, 475, - 475, 476, 477, 477, 478, 478, 478, 478, 478, 478, - 478, 479, 480, 481, 479, 482, 482, 484, 483, 485, - 483, 486, 486, 487, 487, 488, 488, 489, 489, 490, - 491, 491, 492, 492, 493, 493, 495, 494, 496, 496, - 497, 497, 498, 498, 500, 499, 501, 499, 502, 499, - 503, 503, 504, 504, 505, 505, 506, 506, 506, 506, - 506, 507, 507, 508, 508, 508, 510, 509, 511, 512, - 512, 513, 513 + 0, 455, 456, 457, 457, 457, 457, 457, 457, 457, + 457, 457, 457, 457, 457, 457, 457, 457, 458, 458, + 458, 458, 458, 458, 459, 460, 461, 462, 462, 463, + 463, 464, 464, 465, 466, 466, 466, 467, 467, 467, + 467, 468, 468, 468, 468, 469, 469, 469, 469, 470, + 470, 470, 471, 471, 471, 472, 472, 472, 472, 472, + 473, 473, 473, 474, 474, 475, 475, 476, 476, 477, + 477, 478, 478, 479, 479, 480, 481, 480, 482, 482, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 484, 484, 485, 486, 486, 486, 486, 486, 486, + 486, 486, 486, 486, 486, 488, 487, 489, 489, 490, + 490, 490, 490, 491, 491, 492, 492, 493, 494, 494, + 495, 495, 495, 495, 496, 497, 497, 497, 497, 497, + 498, 498, 498, 498, 498, 499, 499, 500, 501, 501, + 501, 501, 501, 501, 501, 501, 502, 503, 503, 504, + 504, 504, 505, 506, 506, 507, 507, 507, 507, 507, + 507, 507, 507, 507, 507, 507, 508, 508, 508, 508, + 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, + 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, + 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, + 508, 509, 510, 510, 511, 511, 512, 512, 512, 512, + 513, 513, 514, 515, 515, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 517, 517, 517, 519, 518, 520, 518, 521, 521, 522, + 522, 523, 523, 524, 524, 525, 525, 525, 525, 526, + 526, 527, 528, 528, 529, 529, 529, 529, 529, 529, + 529, 529, 530, 531, 532, 533, 531, 534, 534, 536, + 535, 537, 535, 538, 538, 539, 539, 540, 540, 541, + 541, 542, 543, 543, 544, 544, 545, 545, 547, 546, + 548, 548, 549, 549, 550, 550, 552, 551, 553, 551, + 554, 551, 555, 555, 556, 556, 557, 557, 558, 558, + 558, 558, 558, 558, 558, 558, 559, 559, 560, 560, + 560, 562, 561, 563, 564, 564, 565, 565, 566, 566, + 567, 567, 568, 568, 569, 569, 570, 570, 570, 570, + 570, 570, 571, 571, 572, 572, 572, 572, 572, 573, + 573, 574, 574, 575, 575, 575, 575, 575, 575, 575, + 575, 576, 576, 577, 577, 577, 577, 578, 578, 579, + 579, 580, 580, 580, 580, 581, 581, 582, 582, 583, + 583, 584, 584, 585, 585 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = +static const yytype_int8 yyr2[] = { - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, 4, 1, - 3, 2, 2, 1, 1, 1, 2, 2, 2, 1, - 2, 3, 2, 1, 1, 1, 1, 2, 2, 2, - 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, - 3, 1, 3, 3, 1, 3, 3, 3, 3, 1, - 3, 3, 1, 3, 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 1, 0, 6, 1, 3, 1, + 0, 2, 1, 1, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, + 1, 3, 2, 2, 1, 1, 1, 2, 2, 2, + 1, 2, 3, 2, 1, 1, 1, 1, 2, 2, + 2, 1, 1, 1, 1, 1, 3, 3, 3, 1, + 3, 3, 1, 3, 3, 1, 3, 3, 3, 3, + 1, 3, 3, 1, 3, 1, 3, 1, 3, 1, + 3, 1, 3, 1, 3, 1, 0, 6, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 1, 2, 2, 4, 2, 3, 4, 2, - 3, 4, 0, 6, 2, 3, 2, 1, 1, 2, - 3, 3, 2, 3, 2, 1, 2, 1, 1, 1, - 3, 4, 6, 5, 1, 2, 3, 5, 4, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 3, 1, 3, 1, 1, 1, 2, 1, + 1, 1, 3, 1, 2, 3, 2, 2, 4, 2, + 3, 4, 2, 3, 4, 0, 6, 2, 3, 2, + 3, 3, 4, 1, 1, 2, 3, 3, 2, 3, + 2, 1, 2, 1, 1, 1, 3, 4, 6, 5, + 1, 2, 3, 5, 4, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 4, 1, 3, 1, + 3, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 4, 1, 1, 3, 1, 2, - 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 1, 1, 3, 2, 3, 2, 3, 3, 4, + 1, 0, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -3446,23 +4409,32 @@ static const yytype_uint8 yyr2[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 6, 0, 5, 1, 2, - 3, 4, 1, 3, 1, 2, 1, 3, 4, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 6, 0, 5, 1, 2, 3, + 4, 1, 3, 1, 2, 1, 3, 4, 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 0, 0, 5, 1, 1, 0, 2, 0, - 2, 2, 3, 1, 2, 1, 2, 1, 2, 5, - 3, 1, 1, 4, 1, 2, 0, 8, 0, 1, - 3, 2, 1, 2, 0, 6, 0, 8, 0, 7, - 1, 1, 1, 0, 2, 3, 2, 2, 2, 3, - 2, 1, 2, 1, 1, 1, 0, 3, 5, 1, - 3, 1, 4 + 1, 1, 2, 2, 0, 0, 5, 1, 1, 0, + 2, 0, 2, 2, 3, 1, 2, 1, 2, 1, + 2, 5, 3, 1, 1, 4, 1, 2, 0, 8, + 0, 1, 3, 2, 1, 2, 0, 6, 0, 8, + 0, 7, 1, 1, 1, 0, 2, 3, 2, 2, + 2, 3, 2, 2, 2, 2, 1, 2, 1, 1, + 1, 0, 3, 5, 1, 3, 1, 4, 1, 3, + 5, 5, 1, 3, 1, 3, 4, 6, 6, 8, + 6, 8, 1, 3, 1, 1, 1, 1, 1, 1, + 3, 4, 6, 4, 6, 6, 8, 6, 8, 6, + 8, 1, 3, 1, 1, 1, 1, 1, 3, 1, + 3, 6, 8, 4, 6, 1, 3, 1, 1, 4, + 6, 1, 3, 3, 3 }; +enum { YYENOMEM = -2 }; + #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab @@ -3471,27 +4443,26 @@ static const yytype_uint8 yyr2[] = #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (pParseContext, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (pParseContext, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF /* Enable debugging if requested. */ @@ -3509,55 +4480,59 @@ do { \ } while (0) /* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif +# ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ - Type, Value, pParseContext); \ + Kind, Value, pParseContext); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YYUSE (yyoutput); YYUSE (pParseContext); if (!yyvaluep) return; # ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + if (yykind < YYNTOKENS) + YYPRINT (yyo, yytoknum[yykind], *yyvaluep); # endif - YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END } -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) { - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + YYFPRINTF (yyo, "%s %s (", + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, pParseContext); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yykind, yyvaluep, pParseContext); + YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. @@ -3566,7 +4541,7 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, gls `------------------------------------------------------------------*/ static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) @@ -3589,21 +4564,21 @@ do { \ `------------------------------------------------*/ static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, glslang::TParseContext* pParseContext) +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule, glslang::TParseContext* pParseContext) { - unsigned long int yylno = yyrline[yyrule]; + int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , pParseContext); + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)], pParseContext); YYFPRINTF (stderr, "\n"); } } @@ -3618,8 +4593,8 @@ do { \ multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ @@ -3642,28 +4617,76 @@ int yydebug; #endif -#if YYERROR_VERBOSE +/* Context of a parse error. */ +typedef struct +{ + yy_state_t *yyssp; + yysymbol_kind_t yytoken; +} yypcontext_t; -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else +/* Put in YYARG at most YYARGN of the expected tokens given the + current YYCTX, and return the number of tokens stored in YYARG. If + YYARG is null, return the number of expected tokens (guaranteed to + be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. + Return 0 if there are more than YYARGN expected tokens, yet fill + YYARG up to YYARGN. */ +static int +yypcontext_expected_tokens (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) +{ + /* Actual size of YYARG. */ + int yycount = 0; + int yyn = yypact[+*yyctx->yyssp]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (!yyarg) + ++yycount; + else if (yycount == yyargn) + return 0; + else + yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); + } + } + if (yyarg && yycount == 0 && 0 < yyargn) + yyarg[0] = YYSYMBOL_YYEMPTY; + return yycount; +} + + + + +#ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) +# else /* Return the length of YYSTR. */ -static YYSIZE_T +static YYPTRDIFF_T yystrlen (const char *yystr) { - YYSIZE_T yylen; + YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } -# endif # endif +#endif -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else +#ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * @@ -3677,10 +4700,10 @@ yystpcpy (char *yydest, const char *yysrc) return yyd - 1; } -# endif # endif +#endif -# ifndef yytnamerr +#ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string @@ -3688,14 +4711,13 @@ yystpcpy (char *yydest, const char *yysrc) backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ -static YYSIZE_T +static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { - YYSIZE_T yyn = 0; + YYPTRDIFF_T yyn = 0; char const *yyp = yystr; - for (;;) switch (*++yyp) { @@ -3706,7 +4728,10 @@ yytnamerr (char *yyres, const char *yystr) case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; - /* Fall through. */ + else + goto append; + + append: default: if (yyres) yyres[yyn] = *yyp; @@ -3721,36 +4746,20 @@ yytnamerr (char *yyres, const char *yystr) do_not_strip_quotes: ; } - if (! yyres) + if (yyres) + return yystpcpy (yyres, yystr) - yyres; + else return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; } -# endif +#endif -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) +yy_syntax_error_arguments (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) { - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ + /* Actual size of YYARG. */ int yycount = 0; - /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action @@ -3774,63 +4783,78 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ - if (yytoken != YYEMPTY) + if (yyctx->yytoken != YYSYMBOL_YYEMPTY) { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } + int yyn; + if (yyarg) + yyarg[yycount] = yyctx->yytoken; + ++yycount; + yyn = yypcontext_expected_tokens (yyctx, + yyarg ? yyarg + 1 : yyarg, yyargn - 1); + if (yyn == YYENOMEM) + return YYENOMEM; + else + yycount += yyn; } + return yycount; +} + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, + const yypcontext_t *yyctx) +{ + enum { YYARGS_MAX = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat: reported tokens (one for the "unexpected", + one per "expected"). */ + yysymbol_kind_t yyarg[YYARGS_MAX]; + /* Cumulated lengths of YYARG. */ + YYPTRDIFF_T yysize = 0; + + /* Actual size of YYARG. */ + int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); + if (yycount == YYENOMEM) + return YYENOMEM; switch (yycount) { -# define YYCASE_(N, S) \ +#define YYCASE_(N, S) \ case N: \ yyformat = S; \ - break + break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ +#undef YYCASE_ } + /* Compute error message size. Don't count the "%s"s, but reserve + room for the terminator. */ + yysize = yystrlen (yyformat) - 2 * yycount + 1; { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + int yyi; + for (yyi = 0; yyi < yycount; ++yyi) + { + YYPTRDIFF_T yysize1 + = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return YYENOMEM; + } } if (*yymsg_alloc < yysize) @@ -3839,7 +4863,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; + return -1; } /* Avoid sprintf, as that infringes on the user's name space. @@ -3851,40 +4875,43 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { - yyp += yytnamerr (yyp, yyarg[yyi++]); + yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); yyformat += 2; } else { - yyp++; - yyformat++; + ++yyp; + ++yyformat; } } return 0; } -#endif /* YYERROR_VERBOSE */ + /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, glslang::TParseContext* pParseContext) +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep, glslang::TParseContext* pParseContext) { YYUSE (yyvaluep); YYUSE (pParseContext); if (!yymsg) yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); + YYUSE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } + + /*----------. | yyparse. | `----------*/ @@ -3892,7 +4919,7 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, glslang::TParseCon int yyparse (glslang::TParseContext* pParseContext) { -/* The lookahead symbol. */ +/* Lookahead token kind. */ int yychar; @@ -3903,45 +4930,41 @@ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Number of syntax errors so far. */ - int yynerrs; + int yynerrs = 0; - int yystate; + yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; + int yyerrstatus = 0; - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow + /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; - /* The semantic value stack. */ + /* The state stack: array, bottom, top. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; + + /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; int yyn; + /* The return value of yyparse. */ int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; -#if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif + YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) @@ -3949,58 +4972,60 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); Keep to zero when no symbol should be popped. */ int yylen = 0; - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - YYDPRINTF ((stderr, "Starting parse\n")); - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; + /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | +| yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: +yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; - yysetstate: - *yyssp = yystate; + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYPTRDIFF_T yysize = yyssp - yyss + 1; -#ifdef yyoverflow +# if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ + yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else +# else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; @@ -4009,9 +5034,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; + yy_state_t *yyss1 = yyss; union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); @@ -4021,30 +5047,30 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); YYSTACK_FREE (yyss1); } # endif -#endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; + /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ @@ -4055,18 +5081,29 @@ yybackup: /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); + YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (&yylval, parseContext); } if (yychar <= YYEOF) { - yychar = yytoken = YYEOF; + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } else { yytoken = YYTRANSLATE (yychar); @@ -4094,15 +5131,13 @@ yybackup: /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END + /* Discard the shifted token. */ + yychar = YYEMPTY; goto yynewstate; @@ -4117,7 +5152,7 @@ yydefault: /*-----------------------------. -| yyreduce -- Do a reduction. | +| yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -4137,294 +5172,304 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 2: -#line 296 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 2: /* variable_identifier: IDENTIFIER */ +#line 392 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleVariable((yyvsp[0].lex).loc, (yyvsp[0].lex).symbol, (yyvsp[0].lex).string); } -#line 4146 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5181 "MachineIndependent/glslang_tab.cpp" break; - case 3: -#line 302 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 3: /* primary_expression: variable_identifier */ +#line 398 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4154 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5189 "MachineIndependent/glslang_tab.cpp" break; - case 4: -#line 305 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); - } -#line 4163 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 5: -#line 309 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); - } -#line 4172 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 6: -#line 313 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); - } -#line 4180 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 7: -#line 316 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); - } -#line 4189 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 8: -#line 320 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i64, (yyvsp[0].lex).loc, true); - } -#line 4198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 9: -#line 324 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u64, (yyvsp[0].lex).loc, true); - } -#line 4207 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 10: -#line 328 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit integer literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((short)(yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); - } -#line 4216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 11: -#line 332 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit unsigned integer literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((unsigned short)(yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); - } -#line 4225 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 12: -#line 336 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); - } -#line 4233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 13: -#line 339 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtDouble, (yyvsp[0].lex).loc, true); - } -#line 4242 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 14: -#line 343 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((yyvsp[0].lex).loc, "half float literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat16, (yyvsp[0].lex).loc, true); - } -#line 4251 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 15: -#line 347 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); - } -#line 4259 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 16: -#line 350 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 4: /* primary_expression: LEFT_PAREN expression RIGHT_PAREN */ +#line 401 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } -#line 4269 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5199 "MachineIndependent/glslang_tab.cpp" break; - case 17: -#line 358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 5: /* primary_expression: FLOATCONSTANT */ +#line 406 "MachineIndependent/glslang.y" + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); + } +#line 5207 "MachineIndependent/glslang_tab.cpp" + break; + + case 6: /* primary_expression: INTCONSTANT */ +#line 409 "MachineIndependent/glslang.y" + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 5215 "MachineIndependent/glslang_tab.cpp" + break; + + case 7: /* primary_expression: UINTCONSTANT */ +#line 412 "MachineIndependent/glslang.y" + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + } +#line 5224 "MachineIndependent/glslang_tab.cpp" + break; + + case 8: /* primary_expression: BOOLCONSTANT */ +#line 416 "MachineIndependent/glslang.y" + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); + } +#line 5232 "MachineIndependent/glslang_tab.cpp" + break; + + case 9: /* primary_expression: STRING_LITERAL */ +#line 420 "MachineIndependent/glslang.y" + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true); + } +#line 5240 "MachineIndependent/glslang_tab.cpp" + break; + + case 10: /* primary_expression: INT32CONSTANT */ +#line 423 "MachineIndependent/glslang.y" + { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 5249 "MachineIndependent/glslang_tab.cpp" + break; + + case 11: /* primary_expression: UINT32CONSTANT */ +#line 427 "MachineIndependent/glslang.y" + { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + } +#line 5258 "MachineIndependent/glslang_tab.cpp" + break; + + case 12: /* primary_expression: INT64CONSTANT */ +#line 431 "MachineIndependent/glslang.y" + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i64, (yyvsp[0].lex).loc, true); + } +#line 5267 "MachineIndependent/glslang_tab.cpp" + break; + + case 13: /* primary_expression: UINT64CONSTANT */ +#line 435 "MachineIndependent/glslang.y" + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u64, (yyvsp[0].lex).loc, true); + } +#line 5276 "MachineIndependent/glslang_tab.cpp" + break; + + case 14: /* primary_expression: INT16CONSTANT */ +#line 439 "MachineIndependent/glslang.y" + { + parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((short)(yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 5285 "MachineIndependent/glslang_tab.cpp" + break; + + case 15: /* primary_expression: UINT16CONSTANT */ +#line 443 "MachineIndependent/glslang.y" + { + parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit unsigned integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((unsigned short)(yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + } +#line 5294 "MachineIndependent/glslang_tab.cpp" + break; + + case 16: /* primary_expression: DOUBLECONSTANT */ +#line 447 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double literal"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtDouble, (yyvsp[0].lex).loc, true); + } +#line 5305 "MachineIndependent/glslang_tab.cpp" + break; + + case 17: /* primary_expression: FLOAT16CONSTANT */ +#line 453 "MachineIndependent/glslang.y" + { + parseContext.float16Check((yyvsp[0].lex).loc, "half float literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat16, (yyvsp[0].lex).loc, true); + } +#line 5314 "MachineIndependent/glslang_tab.cpp" + break; + + case 18: /* postfix_expression: primary_expression */ +#line 461 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4277 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5322 "MachineIndependent/glslang_tab.cpp" break; - case 18: -#line 361 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 19: /* postfix_expression: postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET */ +#line 464 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBracketDereference((yyvsp[-2].lex).loc, (yyvsp[-3].interm.intermTypedNode), (yyvsp[-1].interm.intermTypedNode)); } -#line 4285 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5330 "MachineIndependent/glslang_tab.cpp" break; - case 19: -#line 364 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 20: /* postfix_expression: function_call */ +#line 467 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5338 "MachineIndependent/glslang_tab.cpp" break; - case 20: -#line 367 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 21: /* postfix_expression: postfix_expression DOT IDENTIFIER */ +#line 470 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleDotDereference((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode), *(yyvsp[0].lex).string); } -#line 4301 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5346 "MachineIndependent/glslang_tab.cpp" break; - case 21: -#line 370 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 22: /* postfix_expression: postfix_expression INC_OP */ +#line 473 "MachineIndependent/glslang.y" + { parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "++", (yyvsp[-1].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "++", EOpPostIncrement, (yyvsp[-1].interm.intermTypedNode)); } -#line 4311 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5356 "MachineIndependent/glslang_tab.cpp" break; - case 22: -#line 375 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 23: /* postfix_expression: postfix_expression DEC_OP */ +#line 478 "MachineIndependent/glslang.y" + { parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "--", (yyvsp[-1].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "--", EOpPostDecrement, (yyvsp[-1].interm.intermTypedNode)); } -#line 4321 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5366 "MachineIndependent/glslang_tab.cpp" break; - case 23: -#line 383 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 24: /* integer_expression: expression */ +#line 486 "MachineIndependent/glslang.y" + { parseContext.integerCheck((yyvsp[0].interm.intermTypedNode), "[]"); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4330 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5375 "MachineIndependent/glslang_tab.cpp" break; - case 24: -#line 390 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 25: /* function_call: function_call_or_method */ +#line 493 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleFunctionCall((yyvsp[0].interm).loc, (yyvsp[0].interm).function, (yyvsp[0].interm).intermNode); delete (yyvsp[0].interm).function; } -#line 4339 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5384 "MachineIndependent/glslang_tab.cpp" break; - case 25: -#line 397 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 26: /* function_call_or_method: function_call_generic */ +#line 500 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[0].interm); } -#line 4347 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5392 "MachineIndependent/glslang_tab.cpp" break; - case 26: -#line 403 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 27: /* function_call_generic: function_call_header_with_parameters RIGHT_PAREN */ +#line 506 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[-1].interm); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 4356 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5401 "MachineIndependent/glslang_tab.cpp" break; - case 27: -#line 407 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 28: /* function_call_generic: function_call_header_no_parameters RIGHT_PAREN */ +#line 510 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[-1].interm); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 4365 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5410 "MachineIndependent/glslang_tab.cpp" break; - case 28: -#line 414 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 29: /* function_call_header_no_parameters: function_call_header VOID */ +#line 517 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[-1].interm); } -#line 4373 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5418 "MachineIndependent/glslang_tab.cpp" break; - case 29: -#line 417 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 30: /* function_call_header_no_parameters: function_call_header */ +#line 520 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[0].interm); } -#line 4381 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5426 "MachineIndependent/glslang_tab.cpp" break; - case 30: -#line 423 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 31: /* function_call_header_with_parameters: function_call_header assignment_expression */ +#line 526 "MachineIndependent/glslang.y" + { TParameter param = { 0, new TType }; param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); (yyvsp[-1].interm).function->addParameter(param); (yyval.interm).function = (yyvsp[-1].interm).function; (yyval.interm).intermNode = (yyvsp[0].interm.intermTypedNode); } -#line 4393 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5438 "MachineIndependent/glslang_tab.cpp" break; - case 31: -#line 430 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 32: /* function_call_header_with_parameters: function_call_header_with_parameters COMMA assignment_expression */ +#line 533 "MachineIndependent/glslang.y" + { TParameter param = { 0, new TType }; param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); (yyvsp[-2].interm).function->addParameter(param); (yyval.interm).function = (yyvsp[-2].interm).function; (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); } -#line 4405 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5450 "MachineIndependent/glslang_tab.cpp" break; - case 32: -#line 440 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 33: /* function_call_header: function_identifier LEFT_PAREN */ +#line 543 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[-1].interm); } -#line 4413 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5458 "MachineIndependent/glslang_tab.cpp" break; - case 33: -#line 448 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 34: /* function_identifier: type_specifier */ +#line 551 "MachineIndependent/glslang.y" + { // Constructor (yyval.interm).intermNode = 0; (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); } -#line 4423 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5468 "MachineIndependent/glslang_tab.cpp" break; - case 34: -#line 453 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 35: /* function_identifier: postfix_expression */ +#line 556 "MachineIndependent/glslang.y" + { // // Should be a method or subroutine call, but we haven't recognized the arguments yet. // @@ -4447,55 +5492,55 @@ yyreduce: if ((yyval.interm).function == 0) { // error recover - TString empty(""); - (yyval.interm).function = new TFunction(&empty, TType(EbtVoid), EOpNull); + TString* empty = NewPoolTString(""); + (yyval.interm).function = new TFunction(empty, TType(EbtVoid), EOpNull); } } -#line 4455 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5500 "MachineIndependent/glslang_tab.cpp" break; - case 35: -#line 480 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 36: /* function_identifier: non_uniform_qualifier */ +#line 584 "MachineIndependent/glslang.y" + { // Constructor (yyval.interm).intermNode = 0; (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); } -#line 4465 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5510 "MachineIndependent/glslang_tab.cpp" break; - case 36: -#line 488 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 37: /* unary_expression: postfix_expression */ +#line 593 "MachineIndependent/glslang.y" + { parseContext.variableCheck((yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); if (TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode()) parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); } -#line 4476 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5521 "MachineIndependent/glslang_tab.cpp" break; - case 37: -#line 494 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 38: /* unary_expression: INC_OP unary_expression */ +#line 599 "MachineIndependent/glslang.y" + { parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "++", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "++", EOpPreIncrement, (yyvsp[0].interm.intermTypedNode)); } -#line 4485 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5530 "MachineIndependent/glslang_tab.cpp" break; - case 38: -#line 498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 39: /* unary_expression: DEC_OP unary_expression */ +#line 603 "MachineIndependent/glslang.y" + { parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "--", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "--", EOpPreDecrement, (yyvsp[0].interm.intermTypedNode)); } -#line 4494 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5539 "MachineIndependent/glslang_tab.cpp" break; - case 39: -#line 502 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 40: /* unary_expression: unary_operator unary_expression */ +#line 607 "MachineIndependent/glslang.y" + { if ((yyvsp[-1].interm).op != EOpNull) { char errorOp[2] = {0, 0}; switch((yyvsp[-1].interm).op) { @@ -4511,319 +5556,321 @@ yyreduce: (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } } -#line 4515 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5560 "MachineIndependent/glslang_tab.cpp" break; - case 40: -#line 522 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } -#line 4521 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 41: /* unary_operator: PLUS */ +#line 627 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } +#line 5566 "MachineIndependent/glslang_tab.cpp" break; - case 41: -#line 523 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } -#line 4527 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 42: /* unary_operator: DASH */ +#line 628 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } +#line 5572 "MachineIndependent/glslang_tab.cpp" break; - case 42: -#line 524 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } -#line 4533 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 43: /* unary_operator: BANG */ +#line 629 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } +#line 5578 "MachineIndependent/glslang_tab.cpp" break; - case 43: -#line 525 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpBitwiseNot; + case 44: /* unary_operator: TILDE */ +#line 630 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpBitwiseNot; parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise not"); } -#line 4540 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5585 "MachineIndependent/glslang_tab.cpp" break; - case 44: -#line 531 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 45: /* multiplicative_expression: unary_expression */ +#line 636 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5591 "MachineIndependent/glslang_tab.cpp" break; - case 45: -#line 532 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 46: /* multiplicative_expression: multiplicative_expression STAR unary_expression */ +#line 637 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "*", EOpMul, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4556 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5601 "MachineIndependent/glslang_tab.cpp" break; - case 46: -#line 537 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 47: /* multiplicative_expression: multiplicative_expression SLASH unary_expression */ +#line 642 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "/", EOpDiv, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4566 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5611 "MachineIndependent/glslang_tab.cpp" break; - case 47: -#line 542 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 48: /* multiplicative_expression: multiplicative_expression PERCENT unary_expression */ +#line 647 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "%"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "%", EOpMod, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4577 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5622 "MachineIndependent/glslang_tab.cpp" break; - case 48: -#line 551 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4583 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 49: /* additive_expression: multiplicative_expression */ +#line 656 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5628 "MachineIndependent/glslang_tab.cpp" break; - case 49: -#line 552 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 50: /* additive_expression: additive_expression PLUS multiplicative_expression */ +#line 657 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "+", EOpAdd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4593 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5638 "MachineIndependent/glslang_tab.cpp" break; - case 50: -#line 557 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 51: /* additive_expression: additive_expression DASH multiplicative_expression */ +#line 662 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "-", EOpSub, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5648 "MachineIndependent/glslang_tab.cpp" break; - case 51: -#line 565 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 52: /* shift_expression: additive_expression */ +#line 670 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5654 "MachineIndependent/glslang_tab.cpp" break; - case 52: -#line 566 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 53: /* shift_expression: shift_expression LEFT_OP additive_expression */ +#line 671 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift left"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<<", EOpLeftShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4620 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5665 "MachineIndependent/glslang_tab.cpp" break; - case 53: -#line 572 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 54: /* shift_expression: shift_expression RIGHT_OP additive_expression */ +#line 677 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift right"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">>", EOpRightShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4631 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5676 "MachineIndependent/glslang_tab.cpp" break; - case 54: -#line 581 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4637 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 55: /* relational_expression: shift_expression */ +#line 686 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5682 "MachineIndependent/glslang_tab.cpp" break; - case 55: -#line 582 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 56: /* relational_expression: relational_expression LEFT_ANGLE shift_expression */ +#line 687 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<", EOpLessThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4647 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5692 "MachineIndependent/glslang_tab.cpp" break; - case 56: -#line 587 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 57: /* relational_expression: relational_expression RIGHT_ANGLE shift_expression */ +#line 692 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">", EOpGreaterThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4657 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5702 "MachineIndependent/glslang_tab.cpp" break; - case 57: -#line 592 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 58: /* relational_expression: relational_expression LE_OP shift_expression */ +#line 697 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<=", EOpLessThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4667 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5712 "MachineIndependent/glslang_tab.cpp" break; - case 58: -#line 597 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 59: /* relational_expression: relational_expression GE_OP shift_expression */ +#line 702 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">=", EOpGreaterThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4677 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5722 "MachineIndependent/glslang_tab.cpp" break; - case 59: -#line 605 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4683 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 60: /* equality_expression: relational_expression */ +#line 710 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5728 "MachineIndependent/glslang_tab.cpp" break; - case 60: -#line 606 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 61: /* equality_expression: equality_expression EQ_OP relational_expression */ +#line 711 "MachineIndependent/glslang.y" + { parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); parseContext.specializationCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); + parseContext.referenceCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "==", EOpEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5742 "MachineIndependent/glslang_tab.cpp" break; - case 61: -#line 614 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 62: /* equality_expression: equality_expression NE_OP relational_expression */ +#line 720 "MachineIndependent/glslang.y" + { parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); parseContext.specializationCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); + parseContext.referenceCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "!=", EOpNotEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5756 "MachineIndependent/glslang_tab.cpp" break; - case 62: -#line 625 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4715 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 63: /* and_expression: equality_expression */ +#line 732 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5762 "MachineIndependent/glslang_tab.cpp" break; - case 63: -#line 626 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 64: /* and_expression: and_expression AMPERSAND equality_expression */ +#line 733 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise and"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&", EOpAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4726 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5773 "MachineIndependent/glslang_tab.cpp" break; - case 64: -#line 635 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 65: /* exclusive_or_expression: and_expression */ +#line 742 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5779 "MachineIndependent/glslang_tab.cpp" break; - case 65: -#line 636 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 66: /* exclusive_or_expression: exclusive_or_expression CARET and_expression */ +#line 743 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise exclusive or"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^", EOpExclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4743 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5790 "MachineIndependent/glslang_tab.cpp" break; - case 66: -#line 645 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4749 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 67: /* inclusive_or_expression: exclusive_or_expression */ +#line 752 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5796 "MachineIndependent/glslang_tab.cpp" break; - case 67: -#line 646 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 68: /* inclusive_or_expression: inclusive_or_expression VERTICAL_BAR exclusive_or_expression */ +#line 753 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise inclusive or"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "|", EOpInclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5807 "MachineIndependent/glslang_tab.cpp" break; - case 68: -#line 655 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4766 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 69: /* logical_and_expression: inclusive_or_expression */ +#line 762 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5813 "MachineIndependent/glslang_tab.cpp" break; - case 69: -#line 656 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 70: /* logical_and_expression: logical_and_expression AND_OP inclusive_or_expression */ +#line 763 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&&", EOpLogicalAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4776 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5823 "MachineIndependent/glslang_tab.cpp" break; - case 70: -#line 664 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4782 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 71: /* logical_xor_expression: logical_and_expression */ +#line 771 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5829 "MachineIndependent/glslang_tab.cpp" break; - case 71: -#line 665 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 72: /* logical_xor_expression: logical_xor_expression XOR_OP logical_and_expression */ +#line 772 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^^", EOpLogicalXor, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4792 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5839 "MachineIndependent/glslang_tab.cpp" break; - case 72: -#line 673 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4798 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 73: /* logical_or_expression: logical_xor_expression */ +#line 780 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5845 "MachineIndependent/glslang_tab.cpp" break; - case 73: -#line 674 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 74: /* logical_or_expression: logical_or_expression OR_OP logical_xor_expression */ +#line 781 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "||", EOpLogicalOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4808 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5855 "MachineIndependent/glslang_tab.cpp" break; - case 74: -#line 682 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4814 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 75: /* conditional_expression: logical_or_expression */ +#line 789 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5861 "MachineIndependent/glslang_tab.cpp" break; - case 75: -#line 683 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 76: /* $@1: %empty */ +#line 790 "MachineIndependent/glslang.y" + { ++parseContext.controlFlowNestingLevel; } -#line 4822 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5869 "MachineIndependent/glslang_tab.cpp" break; - case 76: -#line 686 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 77: /* conditional_expression: logical_or_expression QUESTION $@1 expression COLON assignment_expression */ +#line 793 "MachineIndependent/glslang.y" + { --parseContext.controlFlowNestingLevel; parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-5].interm.intermTypedNode)); parseContext.rValueErrorCheck((yyvsp[-4].lex).loc, "?", (yyvsp[-5].interm.intermTypedNode)); @@ -4835,144 +5882,144 @@ yyreduce: (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 4839 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5886 "MachineIndependent/glslang_tab.cpp" break; - case 77: -#line 701 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4845 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 78: /* assignment_expression: conditional_expression */ +#line 808 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 5892 "MachineIndependent/glslang_tab.cpp" break; - case 78: -#line 702 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 79: /* assignment_expression: unary_expression assignment_operator assignment_expression */ +#line 809 "MachineIndependent/glslang.y" + { parseContext.arrayObjectCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array assignment"); parseContext.opaqueCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); parseContext.storage16BitAssignmentCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); parseContext.specializationCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); parseContext.lValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)); parseContext.rValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[0].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].interm).loc); + (yyval.interm.intermTypedNode) = parseContext.addAssign((yyvsp[-1].interm).loc, (yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) { parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } } -#line 4863 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5910 "MachineIndependent/glslang_tab.cpp" break; - case 79: -#line 718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 80: /* assignment_operator: EQUAL */ +#line 825 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAssign; } -#line 4872 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5919 "MachineIndependent/glslang_tab.cpp" break; - case 80: -#line 722 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 81: /* assignment_operator: MUL_ASSIGN */ +#line 829 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpMulAssign; } -#line 4881 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5928 "MachineIndependent/glslang_tab.cpp" break; - case 81: -#line 726 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 82: /* assignment_operator: DIV_ASSIGN */ +#line 833 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpDivAssign; } -#line 4890 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5937 "MachineIndependent/glslang_tab.cpp" break; - case 82: -#line 730 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 83: /* assignment_operator: MOD_ASSIGN */ +#line 837 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "%="); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpModAssign; } -#line 4900 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5947 "MachineIndependent/glslang_tab.cpp" break; - case 83: -#line 735 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 84: /* assignment_operator: ADD_ASSIGN */ +#line 842 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAddAssign; } -#line 4909 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5956 "MachineIndependent/glslang_tab.cpp" break; - case 84: -#line 739 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 85: /* assignment_operator: SUB_ASSIGN */ +#line 846 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpSubAssign; } -#line 4918 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5965 "MachineIndependent/glslang_tab.cpp" break; - case 85: -#line 743 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 86: /* assignment_operator: LEFT_ASSIGN */ +#line 850 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift left assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLeftShiftAssign; } -#line 4927 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5974 "MachineIndependent/glslang_tab.cpp" break; - case 86: -#line 747 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 87: /* assignment_operator: RIGHT_ASSIGN */ +#line 854 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift right assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpRightShiftAssign; } -#line 4936 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5983 "MachineIndependent/glslang_tab.cpp" break; - case 87: -#line 751 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 88: /* assignment_operator: AND_ASSIGN */ +#line 858 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-and assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAndAssign; } -#line 4945 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5992 "MachineIndependent/glslang_tab.cpp" break; - case 88: -#line 755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 89: /* assignment_operator: XOR_ASSIGN */ +#line 862 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-xor assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpExclusiveOrAssign; } -#line 4954 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6001 "MachineIndependent/glslang_tab.cpp" break; - case 89: -#line 759 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 90: /* assignment_operator: OR_ASSIGN */ +#line 866 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-or assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpInclusiveOrAssign; } -#line 4963 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6010 "MachineIndependent/glslang_tab.cpp" break; - case 90: -#line 766 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 91: /* expression: assignment_expression */ +#line 873 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4971 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6018 "MachineIndependent/glslang_tab.cpp" break; - case 91: -#line 769 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 92: /* expression: expression COMMA assignment_expression */ +#line 876 "MachineIndependent/glslang.y" + { parseContext.samplerConstructorLocationCheck((yyvsp[-1].lex).loc, ",", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); if ((yyval.interm.intermTypedNode) == 0) { @@ -4980,119 +6027,140 @@ yyreduce: (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 4984 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6031 "MachineIndependent/glslang_tab.cpp" break; - case 92: -#line 780 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 93: /* constant_expression: conditional_expression */ +#line 887 "MachineIndependent/glslang.y" + { parseContext.constantValueCheck((yyvsp[0].interm.intermTypedNode), ""); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4993 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6040 "MachineIndependent/glslang_tab.cpp" break; - case 93: -#line 787 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 94: /* declaration: function_prototype SEMICOLON */ +#line 894 "MachineIndependent/glslang.y" + { parseContext.handleFunctionDeclarator((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).function, true /* prototype */); (yyval.interm.intermNode) = 0; // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature } -#line 5003 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6050 "MachineIndependent/glslang_tab.cpp" break; - case 94: -#line 792 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 95: /* declaration: spirv_instruction_qualifier function_prototype SEMICOLON */ +#line 900 "MachineIndependent/glslang.y" + { + parseContext.requireExtensions((yyvsp[-1].interm).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier"); + (yyvsp[-1].interm).function->setSpirvInstruction(*(yyvsp[-2].interm.spirvInst)); // Attach SPIR-V intruction qualifier + parseContext.handleFunctionDeclarator((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).function, true /* prototype */); + (yyval.interm.intermNode) = 0; + // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature + } +#line 6062 "MachineIndependent/glslang_tab.cpp" + break; + + case 96: /* declaration: spirv_execution_mode_qualifier SEMICOLON */ +#line 907 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "SPIR-V execution mode qualifier"); + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier"); + (yyval.interm.intermNode) = 0; + } +#line 6072 "MachineIndependent/glslang_tab.cpp" + break; + + case 97: /* declaration: init_declarator_list SEMICOLON */ +#line 913 "MachineIndependent/glslang.y" + { if ((yyvsp[-1].interm).intermNode && (yyvsp[-1].interm).intermNode->getAsAggregate()) (yyvsp[-1].interm).intermNode->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-1].interm).intermNode; } -#line 5013 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6082 "MachineIndependent/glslang_tab.cpp" break; - case 95: -#line 797 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 98: /* declaration: PRECISION precision_qualifier type_specifier SEMICOLON */ +#line 918 "MachineIndependent/glslang.y" + { parseContext.profileRequires((yyvsp[-3].lex).loc, ENoProfile, 130, 0, "precision statement"); - // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]); parseContext.setDefaultPrecision((yyvsp[-3].lex).loc, (yyvsp[-1].interm.type), (yyvsp[-2].interm.type).qualifier.precision); (yyval.interm.intermNode) = 0; } -#line 5026 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6094 "MachineIndependent/glslang_tab.cpp" break; - case 96: -#line 805 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 99: /* declaration: block_structure SEMICOLON */ +#line 925 "MachineIndependent/glslang.y" + { parseContext.declareBlock((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).typeList); (yyval.interm.intermNode) = 0; } -#line 5035 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6103 "MachineIndependent/glslang_tab.cpp" break; - case 97: -#line 809 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 100: /* declaration: block_structure IDENTIFIER SEMICOLON */ +#line 929 "MachineIndependent/glslang.y" + { parseContext.declareBlock((yyvsp[-2].interm).loc, *(yyvsp[-2].interm).typeList, (yyvsp[-1].lex).string); (yyval.interm.intermNode) = 0; } -#line 5044 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6112 "MachineIndependent/glslang_tab.cpp" break; - case 98: -#line 813 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 101: /* declaration: block_structure IDENTIFIER array_specifier SEMICOLON */ +#line 933 "MachineIndependent/glslang.y" + { parseContext.declareBlock((yyvsp[-3].interm).loc, *(yyvsp[-3].interm).typeList, (yyvsp[-2].lex).string, (yyvsp[-1].interm).arraySizes); (yyval.interm.intermNode) = 0; } -#line 5053 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6121 "MachineIndependent/glslang_tab.cpp" break; - case 99: -#line 817 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 102: /* declaration: type_qualifier SEMICOLON */ +#line 937 "MachineIndependent/glslang.y" + { parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); parseContext.updateStandaloneQualifierDefaults((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type)); (yyval.interm.intermNode) = 0; } -#line 5063 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6131 "MachineIndependent/glslang_tab.cpp" break; - case 100: -#line 822 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 103: /* declaration: type_qualifier IDENTIFIER SEMICOLON */ +#line 942 "MachineIndependent/glslang.y" + { parseContext.checkNoShaderLayouts((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).shaderQualifiers); parseContext.addQualifierToExisting((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, *(yyvsp[-1].lex).string); (yyval.interm.intermNode) = 0; } -#line 5073 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6141 "MachineIndependent/glslang_tab.cpp" break; - case 101: -#line 827 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 104: /* declaration: type_qualifier IDENTIFIER identifier_list SEMICOLON */ +#line 947 "MachineIndependent/glslang.y" + { parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers); (yyvsp[-1].interm.identifierList)->push_back((yyvsp[-2].lex).string); parseContext.addQualifierToExisting((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier, *(yyvsp[-1].interm.identifierList)); (yyval.interm.intermNode) = 0; } -#line 5084 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6152 "MachineIndependent/glslang_tab.cpp" break; - case 102: -#line 836 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } -#line 5090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 105: /* $@2: %empty */ +#line 956 "MachineIndependent/glslang.y" + { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } +#line 6158 "MachineIndependent/glslang_tab.cpp" break; - case 103: -#line 836 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - --parseContext.structNestingLevel; + case 106: /* block_structure: type_qualifier IDENTIFIER LEFT_BRACE $@2 struct_declaration_list RIGHT_BRACE */ +#line 956 "MachineIndependent/glslang.y" + { + --parseContext.blockNestingLevel; parseContext.blockName = (yyvsp[-4].lex).string; parseContext.globalQualifierFixCheck((yyvsp[-5].interm.type).loc, (yyvsp[-5].interm.type).qualifier); parseContext.checkNoShaderLayouts((yyvsp[-5].interm.type).loc, (yyvsp[-5].interm.type).shaderQualifiers); @@ -5100,55 +6168,89 @@ yyreduce: (yyval.interm).loc = (yyvsp[-5].interm.type).loc; (yyval.interm).typeList = (yyvsp[-1].interm.typeList); } -#line 5104 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6172 "MachineIndependent/glslang_tab.cpp" break; - case 104: -#line 847 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 107: /* identifier_list: COMMA IDENTIFIER */ +#line 967 "MachineIndependent/glslang.y" + { (yyval.interm.identifierList) = new TIdentifierList; (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 5113 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6181 "MachineIndependent/glslang_tab.cpp" break; - case 105: -#line 851 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 108: /* identifier_list: identifier_list COMMA IDENTIFIER */ +#line 971 "MachineIndependent/glslang.y" + { (yyval.interm.identifierList) = (yyvsp[-2].interm.identifierList); (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 5122 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6190 "MachineIndependent/glslang_tab.cpp" break; - case 106: -#line 858 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 109: /* function_prototype: function_declarator RIGHT_PAREN */ +#line 978 "MachineIndependent/glslang.y" + { (yyval.interm).function = (yyvsp[-1].interm.function); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 5131 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6199 "MachineIndependent/glslang_tab.cpp" break; - case 107: -#line 865 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 110: /* function_prototype: function_declarator RIGHT_PAREN attribute */ +#line 982 "MachineIndependent/glslang.y" + { + (yyval.interm).function = (yyvsp[-2].interm.function); + (yyval.interm).loc = (yyvsp[-1].lex).loc; + parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); + parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes), (yyval.interm).function); + } +#line 6210 "MachineIndependent/glslang_tab.cpp" + break; + + case 111: /* function_prototype: attribute function_declarator RIGHT_PAREN */ +#line 988 "MachineIndependent/glslang.y" + { + (yyval.interm).function = (yyvsp[-1].interm.function); + (yyval.interm).loc = (yyvsp[0].lex).loc; + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); + parseContext.handleFunctionAttributes((yyvsp[0].lex).loc, *(yyvsp[-2].interm.attributes), (yyval.interm).function); + } +#line 6221 "MachineIndependent/glslang_tab.cpp" + break; + + case 112: /* function_prototype: attribute function_declarator RIGHT_PAREN attribute */ +#line 994 "MachineIndependent/glslang.y" + { + (yyval.interm).function = (yyvsp[-2].interm.function); + (yyval.interm).loc = (yyvsp[-1].lex).loc; + parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); + parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[-3].interm.attributes), (yyval.interm).function); + parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes), (yyval.interm).function); + } +#line 6233 "MachineIndependent/glslang_tab.cpp" + break; + + case 113: /* function_declarator: function_header */ +#line 1004 "MachineIndependent/glslang.y" + { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 5139 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6241 "MachineIndependent/glslang_tab.cpp" break; - case 108: -#line 868 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 114: /* function_declarator: function_header_with_parameters */ +#line 1007 "MachineIndependent/glslang.y" + { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 5147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6249 "MachineIndependent/glslang_tab.cpp" break; - case 109: -#line 875 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 115: /* function_header_with_parameters: function_header parameter_declaration */ +#line 1014 "MachineIndependent/glslang.y" + { // Add the parameter (yyval.interm.function) = (yyvsp[-1].interm.function); if ((yyvsp[0].interm).param.type->getBasicType() != EbtVoid) @@ -5156,12 +6258,12 @@ yyreduce: else delete (yyvsp[0].interm).param.type; } -#line 5160 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6262 "MachineIndependent/glslang_tab.cpp" break; - case 110: -#line 883 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 116: /* function_header_with_parameters: function_header_with_parameters COMMA parameter_declaration */ +#line 1022 "MachineIndependent/glslang.y" + { // // Only first parameter of one-parameter functions can be void // The check for named parameters not being void is done in parameter_declarator @@ -5178,12 +6280,12 @@ yyreduce: (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); } } -#line 5182 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6284 "MachineIndependent/glslang_tab.cpp" break; - case 111: -#line 903 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 117: /* function_header: fully_specified_type IDENTIFIER LEFT_PAREN */ +#line 1042 "MachineIndependent/glslang.y" + { if ((yyvsp[-2].interm.type).qualifier.storage != EvqGlobal && (yyvsp[-2].interm.type).qualifier.storage != EvqTemporary) { parseContext.error((yyvsp[-1].lex).loc, "no qualifiers allowed for function return", GetStorageQualifierString((yyvsp[-2].interm.type).qualifier.storage), ""); @@ -5202,12 +6304,12 @@ yyreduce: function = new TFunction((yyvsp[-1].lex).string, type); (yyval.interm.function) = function; } -#line 5206 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6308 "MachineIndependent/glslang_tab.cpp" break; - case 112: -#line 926 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 118: /* parameter_declarator: type_specifier IDENTIFIER */ +#line 1065 "MachineIndependent/glslang.y" + { if ((yyvsp[-1].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-1].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires((yyvsp[-1].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); @@ -5222,12 +6324,12 @@ yyreduce: (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).param = param; } -#line 5226 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6328 "MachineIndependent/glslang_tab.cpp" break; - case 113: -#line 941 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 119: /* parameter_declarator: type_specifier IDENTIFIER array_specifier */ +#line 1080 "MachineIndependent/glslang.y" + { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); @@ -5246,12 +6348,12 @@ yyreduce: (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).param = param; } -#line 5250 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6352 "MachineIndependent/glslang_tab.cpp" break; - case 114: -#line 966 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 120: /* parameter_declaration: type_qualifier parameter_declarator */ +#line 1105 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; @@ -5262,24 +6364,24 @@ yyreduce: parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 5266 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6368 "MachineIndependent/glslang_tab.cpp" break; - case 115: -#line 977 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 121: /* parameter_declaration: parameter_declarator */ +#line 1116 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[0].interm); parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); } -#line 5278 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6380 "MachineIndependent/glslang_tab.cpp" break; - case 116: -#line 987 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 122: /* parameter_declaration: type_qualifier parameter_type_specifier */ +#line 1126 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; @@ -5289,131 +6391,133 @@ yyreduce: parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 5293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6395 "MachineIndependent/glslang_tab.cpp" break; - case 117: -#line 997 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 123: /* parameter_declaration: parameter_type_specifier */ +#line 1136 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[0].interm); parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); } -#line 5305 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6407 "MachineIndependent/glslang_tab.cpp" break; - case 118: -#line 1007 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 124: /* parameter_type_specifier: type_specifier */ +#line 1146 "MachineIndependent/glslang.y" + { TParameter param = { 0, new TType((yyvsp[0].interm.type)) }; (yyval.interm).param = param; if ((yyvsp[0].interm.type).arraySizes) parseContext.arraySizeRequiredCheck((yyvsp[0].interm.type).loc, *(yyvsp[0].interm.type).arraySizes); } -#line 5316 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6418 "MachineIndependent/glslang_tab.cpp" break; - case 119: -#line 1016 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 125: /* init_declarator_list: single_declaration */ +#line 1155 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[0].interm); } -#line 5324 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6426 "MachineIndependent/glslang_tab.cpp" break; - case 120: -#line 1019 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 126: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER */ +#line 1158 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[-2].interm); parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-2].interm).type); } -#line 5333 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6435 "MachineIndependent/glslang_tab.cpp" break; - case 121: -#line 1023 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 127: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER array_specifier */ +#line 1162 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[-3].interm); parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-3].interm).type, (yyvsp[0].interm).arraySizes); } -#line 5342 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6444 "MachineIndependent/glslang_tab.cpp" break; - case 122: -#line 1027 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 128: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer */ +#line 1166 "MachineIndependent/glslang.y" + { (yyval.interm).type = (yyvsp[-5].interm).type; TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-5].interm).type, (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-5].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 5352 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6454 "MachineIndependent/glslang_tab.cpp" break; - case 123: -#line 1032 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 129: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER EQUAL initializer */ +#line 1171 "MachineIndependent/glslang.y" + { (yyval.interm).type = (yyvsp[-4].interm).type; TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-4].interm).type, 0, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-4].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 5362 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6464 "MachineIndependent/glslang_tab.cpp" break; - case 124: -#line 1040 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 130: /* single_declaration: fully_specified_type */ +#line 1179 "MachineIndependent/glslang.y" + { (yyval.interm).type = (yyvsp[0].interm.type); (yyval.interm).intermNode = 0; + parseContext.declareTypeDefaults((yyval.interm).loc, (yyval.interm).type); + } -#line 5372 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6476 "MachineIndependent/glslang_tab.cpp" break; - case 125: -#line 1045 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 131: /* single_declaration: fully_specified_type IDENTIFIER */ +#line 1186 "MachineIndependent/glslang.y" + { (yyval.interm).type = (yyvsp[-1].interm.type); (yyval.interm).intermNode = 0; parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-1].interm.type)); } -#line 5382 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6486 "MachineIndependent/glslang_tab.cpp" break; - case 126: -#line 1050 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 132: /* single_declaration: fully_specified_type IDENTIFIER array_specifier */ +#line 1191 "MachineIndependent/glslang.y" + { (yyval.interm).type = (yyvsp[-2].interm.type); (yyval.interm).intermNode = 0; parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-2].interm.type), (yyvsp[0].interm).arraySizes); } -#line 5392 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6496 "MachineIndependent/glslang_tab.cpp" break; - case 127: -#line 1055 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 133: /* single_declaration: fully_specified_type IDENTIFIER array_specifier EQUAL initializer */ +#line 1196 "MachineIndependent/glslang.y" + { (yyval.interm).type = (yyvsp[-4].interm.type); TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-4].interm.type), (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); } -#line 5402 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6506 "MachineIndependent/glslang_tab.cpp" break; - case 128: -#line 1060 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 134: /* single_declaration: fully_specified_type IDENTIFIER EQUAL initializer */ +#line 1201 "MachineIndependent/glslang.y" + { (yyval.interm).type = (yyvsp[-3].interm.type); TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), 0, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); } -#line 5412 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6516 "MachineIndependent/glslang_tab.cpp" break; - case 129: -#line 1069 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 135: /* fully_specified_type: type_specifier */ +#line 1210 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[0].interm.type); parseContext.globalQualifierTypeCheck((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier, (yyval.interm.type)); @@ -5421,15 +6525,14 @@ yyreduce: parseContext.profileRequires((yyvsp[0].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires((yyvsp[0].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); } - parseContext.precisionQualifierCheck((yyval.interm.type).loc, (yyval.interm.type).basicType, (yyval.interm.type).qualifier); } -#line 5428 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6531 "MachineIndependent/glslang_tab.cpp" break; - case 130: -#line 1080 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 136: /* fully_specified_type: type_qualifier type_specifier */ +#line 1220 "MachineIndependent/glslang.y" + { parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); parseContext.globalQualifierTypeCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, (yyvsp[0].interm.type)); @@ -5453,93 +6556,84 @@ yyreduce: (parseContext.language == EShLangFragment && (yyval.interm.type).qualifier.storage == EvqVaryingIn))) (yyval.interm.type).qualifier.smooth = true; } -#line 5457 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6560 "MachineIndependent/glslang_tab.cpp" break; - case 131: -#line 1107 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 137: /* invariant_qualifier: INVARIANT */ +#line 1247 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "invariant"); parseContext.profileRequires((yyval.interm.type).loc, ENoProfile, 120, 0, "invariant"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.invariant = true; } -#line 5468 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6571 "MachineIndependent/glslang_tab.cpp" break; - case 132: -#line 1116 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 138: /* interpolation_qualifier: SMOOTH */ +#line 1256 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "smooth"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "smooth"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "smooth"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.smooth = true; } -#line 5480 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6583 "MachineIndependent/glslang_tab.cpp" break; - case 133: -#line 1123 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 139: /* interpolation_qualifier: FLAT */ +#line 1263 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "flat"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "flat"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "flat"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.flat = true; } -#line 5492 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6595 "MachineIndependent/glslang_tab.cpp" break; - case 134: -#line 1130 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 140: /* interpolation_qualifier: NOPERSPECTIVE */ +#line 1271 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "noperspective"); -#ifdef NV_EXTENSIONS parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective"); -#else - parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "noperspective"); -#endif parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "noperspective"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nopersp = true; } -#line 5508 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6607 "MachineIndependent/glslang_tab.cpp" break; - case 135: -#line 1141 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 141: /* interpolation_qualifier: EXPLICITINTERPAMD */ +#line 1278 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "__explicitInterpAMD"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); parseContext.profileRequires((yyvsp[0].lex).loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.explicitInterp = true; -#endif } -#line 5522 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6619 "MachineIndependent/glslang_tab.cpp" break; - case 136: -#line 1150 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 142: /* interpolation_qualifier: PERVERTEXNV */ +#line 1285 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "pervertexNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); parseContext.profileRequires((yyvsp[0].lex).loc, ECompatibilityProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.pervertexNV = true; -#endif } -#line 5537 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6632 "MachineIndependent/glslang_tab.cpp" break; - case 137: -#line 1160 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 143: /* interpolation_qualifier: PERPRIMITIVENV */ +#line 1293 "MachineIndependent/glslang.y" + { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV"); @@ -5548,115 +6642,110 @@ yyreduce: parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perPrimitiveNV = true; -#endif } -#line 5554 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6647 "MachineIndependent/glslang_tab.cpp" break; - case 138: -#line 1172 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 144: /* interpolation_qualifier: PERVIEWNV */ +#line 1303 "MachineIndependent/glslang.y" + { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perviewNV"); parseContext.requireStage((yyvsp[0].lex).loc, EShLangMeshNV, "perviewNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perViewNV = true; -#endif } -#line 5568 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6659 "MachineIndependent/glslang_tab.cpp" break; - case 139: -#line 1181 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 145: /* interpolation_qualifier: PERTASKNV */ +#line 1310 "MachineIndependent/glslang.y" + { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "taskNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perTaskNV = true; -#endif } -#line 5582 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6671 "MachineIndependent/glslang_tab.cpp" break; - case 140: -#line 1193 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 146: /* layout_qualifier: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN */ +#line 1321 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[-1].interm.type); } -#line 5590 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6679 "MachineIndependent/glslang_tab.cpp" break; - case 141: -#line 1199 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 147: /* layout_qualifier_id_list: layout_qualifier_id */ +#line 1327 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5598 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6687 "MachineIndependent/glslang_tab.cpp" break; - case 142: -#line 1202 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 148: /* layout_qualifier_id_list: layout_qualifier_id_list COMMA layout_qualifier_id */ +#line 1330 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[-2].interm.type); (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); parseContext.mergeObjectLayoutQualifiers((yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 5608 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6697 "MachineIndependent/glslang_tab.cpp" break; - case 143: -#line 1209 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 149: /* layout_qualifier_id: IDENTIFIER */ +#line 1337 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), *(yyvsp[0].lex).string); } -#line 5617 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6706 "MachineIndependent/glslang_tab.cpp" break; - case 144: -#line 1213 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 150: /* layout_qualifier_id: IDENTIFIER EQUAL constant_expression */ +#line 1341 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[-2].lex).loc); parseContext.setLayoutQualifier((yyvsp[-2].lex).loc, (yyval.interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode)); } -#line 5626 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6715 "MachineIndependent/glslang_tab.cpp" break; - case 145: -#line 1217 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { // because "shared" is both an identifier and a keyword + case 151: /* layout_qualifier_id: SHARED */ +#line 1345 "MachineIndependent/glslang.y" + { // because "shared" is both an identifier and a keyword (yyval.interm.type).init((yyvsp[0].lex).loc); TString strShared("shared"); parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), strShared); } -#line 5636 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6725 "MachineIndependent/glslang_tab.cpp" break; - case 146: -#line 1225 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 152: /* precise_qualifier: PRECISE */ +#line 1354 "MachineIndependent/glslang.y" + { parseContext.profileRequires((yyval.interm.type).loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "precise"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.noContraction = true; } -#line 5647 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6736 "MachineIndependent/glslang_tab.cpp" break; - case 147: -#line 1234 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 153: /* type_qualifier: single_type_qualifier */ +#line 1364 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5655 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6744 "MachineIndependent/glslang_tab.cpp" break; - case 148: -#line 1237 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 154: /* type_qualifier: type_qualifier single_type_qualifier */ +#line 1367 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[-1].interm.type); if ((yyval.interm.type).basicType == EbtVoid) (yyval.interm.type).basicType = (yyvsp[0].interm.type).basicType; @@ -5664,81 +6753,197 @@ yyreduce: (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); parseContext.mergeQualifiers((yyval.interm.type).loc, (yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 5668 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6757 "MachineIndependent/glslang_tab.cpp" break; - case 149: -#line 1248 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 155: /* single_type_qualifier: storage_qualifier */ +#line 1378 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6765 "MachineIndependent/glslang_tab.cpp" break; - case 150: -#line 1251 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 156: /* single_type_qualifier: layout_qualifier */ +#line 1381 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5684 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6773 "MachineIndependent/glslang_tab.cpp" break; - case 151: -#line 1254 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 157: /* single_type_qualifier: precision_qualifier */ +#line 1384 "MachineIndependent/glslang.y" + { parseContext.checkPrecisionQualifier((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier.precision); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5693 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6782 "MachineIndependent/glslang_tab.cpp" break; - case 152: -#line 1258 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 158: /* single_type_qualifier: interpolation_qualifier */ +#line 1388 "MachineIndependent/glslang.y" + { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5702 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6791 "MachineIndependent/glslang_tab.cpp" break; - case 153: -#line 1262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 159: /* single_type_qualifier: invariant_qualifier */ +#line 1392 "MachineIndependent/glslang.y" + { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5711 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6800 "MachineIndependent/glslang_tab.cpp" break; - case 154: -#line 1266 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 160: /* single_type_qualifier: precise_qualifier */ +#line 1397 "MachineIndependent/glslang.y" + { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6809 "MachineIndependent/glslang_tab.cpp" break; - case 155: -#line 1270 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 161: /* single_type_qualifier: non_uniform_qualifier */ +#line 1401 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5728 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6817 "MachineIndependent/glslang_tab.cpp" break; - case 156: -#line 1276 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 162: /* single_type_qualifier: spirv_storage_class_qualifier */ +#line 1404 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].interm.type).loc, "spirv_storage_class"); + parseContext.requireExtensions((yyvsp[0].interm.type).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier"); + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 6827 "MachineIndependent/glslang_tab.cpp" + break; + + case 163: /* single_type_qualifier: spirv_decorate_qualifier */ +#line 1409 "MachineIndependent/glslang.y" + { + parseContext.requireExtensions((yyvsp[0].interm.type).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier"); + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 6836 "MachineIndependent/glslang_tab.cpp" + break; + + case 164: /* single_type_qualifier: SPIRV_BY_REFERENCE */ +#line 1413 "MachineIndependent/glslang.y" + { + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.setSpirvByReference(); + } +#line 6846 "MachineIndependent/glslang_tab.cpp" + break; + + case 165: /* single_type_qualifier: SPIRV_LITERAL */ +#line 1418 "MachineIndependent/glslang.y" + { + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.setSpirvLiteral(); + } +#line 6856 "MachineIndependent/glslang_tab.cpp" + break; + + case 166: /* storage_qualifier: CONST */ +#line 1427 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant } -#line 5737 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6865 "MachineIndependent/glslang_tab.cpp" break; - case 157: -#line 1280 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 167: /* storage_qualifier: INOUT */ +#line 1431 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "inout"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqInOut; + } +#line 6875 "MachineIndependent/glslang_tab.cpp" + break; + + case 168: /* storage_qualifier: IN */ +#line 1436 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "in"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later + (yyval.interm.type).qualifier.storage = EvqIn; + } +#line 6886 "MachineIndependent/glslang_tab.cpp" + break; + + case 169: /* storage_qualifier: OUT */ +#line 1442 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "out"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later + (yyval.interm.type).qualifier.storage = EvqOut; + } +#line 6897 "MachineIndependent/glslang_tab.cpp" + break; + + case 170: /* storage_qualifier: CENTROID */ +#line 1448 "MachineIndependent/glslang.y" + { + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 120, 0, "centroid"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "centroid"); + parseContext.globalCheck((yyvsp[0].lex).loc, "centroid"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.centroid = true; + } +#line 6909 "MachineIndependent/glslang_tab.cpp" + break; + + case 171: /* storage_qualifier: UNIFORM */ +#line 1455 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "uniform"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqUniform; + } +#line 6919 "MachineIndependent/glslang_tab.cpp" + break; + + case 172: /* storage_qualifier: SHARED */ +#line 1460 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "shared"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 310, 0, "shared"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqShared; + } +#line 6932 "MachineIndependent/glslang_tab.cpp" + break; + + case 173: /* storage_qualifier: BUFFER */ +#line 1468 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "buffer"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqBuffer; + } +#line 6942 "MachineIndependent/glslang_tab.cpp" + break; + + case 174: /* storage_qualifier: ATTRIBUTE */ +#line 1474 "MachineIndependent/glslang.y" + { parseContext.requireStage((yyvsp[0].lex).loc, EShLangVertex, "attribute"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "attribute"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "attribute"); @@ -5750,12 +6955,12 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 5754 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6959 "MachineIndependent/glslang_tab.cpp" break; - case 158: -#line 1292 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 175: /* storage_qualifier: VARYING */ +#line 1486 "MachineIndependent/glslang.y" + { parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "varying"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "varying"); parseContext.requireNotRemoved((yyvsp[0].lex).loc, ECoreProfile, 420, "varying"); @@ -5769,3476 +6974,3735 @@ yyreduce: else (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 5773 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6978 "MachineIndependent/glslang_tab.cpp" break; - case 159: -#line 1306 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.globalCheck((yyvsp[0].lex).loc, "inout"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqInOut; - } -#line 5783 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 160: -#line 1311 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.globalCheck((yyvsp[0].lex).loc, "in"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later - (yyval.interm.type).qualifier.storage = EvqIn; - } -#line 5794 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 161: -#line 1317 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.globalCheck((yyvsp[0].lex).loc, "out"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later - (yyval.interm.type).qualifier.storage = EvqOut; - } -#line 5805 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 162: -#line 1323 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 120, 0, "centroid"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "centroid"); - parseContext.globalCheck((yyvsp[0].lex).loc, "centroid"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.centroid = true; - } -#line 5817 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 163: -#line 1330 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 176: /* storage_qualifier: PATCH */ +#line 1500 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "patch"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.patch = true; } -#line 5828 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6989 "MachineIndependent/glslang_tab.cpp" break; - case 164: -#line 1336 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 177: /* storage_qualifier: SAMPLE */ +#line 1506 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "sample"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.sample = true; } -#line 5838 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6999 "MachineIndependent/glslang_tab.cpp" break; - case 165: -#line 1341 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.globalCheck((yyvsp[0].lex).loc, "uniform"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqUniform; - } -#line 5848 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 166: -#line 1346 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.globalCheck((yyvsp[0].lex).loc, "buffer"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqBuffer; - } -#line 5858 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 167: -#line 1351 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 178: /* storage_qualifier: HITATTRNV */ +#line 1511 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangClosestHitNVMask - | EShLangAnyHitNVMask), "hitAttributeNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask + | EShLangAnyHitMask), "hitAttributeNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqHitAttrNV; -#endif + (yyval.interm.type).qualifier.storage = EvqHitAttr; } -#line 5873 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7012 "MachineIndependent/glslang_tab.cpp" break; - case 168: -#line 1361 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 179: /* storage_qualifier: HITATTREXT */ +#line 1519 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask + | EShLangAnyHitMask), "hitAttributeEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "hitAttributeNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqHitAttr; + } +#line 7025 "MachineIndependent/glslang_tab.cpp" + break; + + case 180: /* storage_qualifier: PAYLOADNV */ +#line 1527 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | - EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqPayloadNV; -#endif + (yyval.interm.type).qualifier.storage = EvqPayload; } -#line 5888 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7038 "MachineIndependent/glslang_tab.cpp" break; - case 169: -#line 1371 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 181: /* storage_qualifier: PAYLOADEXT */ +#line 1535 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "rayPayloadEXT"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqPayload; + } +#line 7051 "MachineIndependent/glslang_tab.cpp" + break; + + case 182: /* storage_qualifier: PAYLOADINNV */ +#line 1543 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitNVMask | - EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadInNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadInNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqPayloadInNV; -#endif + (yyval.interm.type).qualifier.storage = EvqPayloadIn; } -#line 5903 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7064 "MachineIndependent/glslang_tab.cpp" break; - case 170: -#line 1381 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 183: /* storage_qualifier: PAYLOADINEXT */ +#line 1551 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadInEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "rayPayloadInEXT"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqPayloadIn; + } +#line 7077 "MachineIndependent/glslang_tab.cpp" + break; + + case 184: /* storage_qualifier: CALLDATANV */ +#line 1559 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenNVMask | - EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), "callableDataNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | + EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqCallableDataNV; -#endif + (yyval.interm.type).qualifier.storage = EvqCallableData; } -#line 5918 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7090 "MachineIndependent/glslang_tab.cpp" break; - case 171: -#line 1391 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 185: /* storage_qualifier: CALLDATAEXT */ +#line 1567 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | + EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "callableDataEXT"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqCallableData; + } +#line 7103 "MachineIndependent/glslang_tab.cpp" + break; + + case 186: /* storage_qualifier: CALLDATAINNV */ +#line 1575 "MachineIndependent/glslang.y" + { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqCallableDataInNV; -#endif + (yyval.interm.type).qualifier.storage = EvqCallableDataIn; } -#line 5932 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7115 "MachineIndependent/glslang_tab.cpp" break; - case 172: -#line 1400 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.globalCheck((yyvsp[0].lex).loc, "shared"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 310, 0, "shared"); -#ifdef NV_EXTENSIONS - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); -#else - parseContext.requireStage((yyvsp[0].lex).loc, EShLangCompute, "shared"); -#endif + case 187: /* storage_qualifier: CALLDATAINEXT */ +#line 1582 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "callableDataInEXT"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqShared; + (yyval.interm.type).qualifier.storage = EvqCallableDataIn; } -#line 5949 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7127 "MachineIndependent/glslang_tab.cpp" break; - case 173: -#line 1412 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 188: /* storage_qualifier: COHERENT */ +#line 1589 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.coherent = true; } -#line 5958 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7136 "MachineIndependent/glslang_tab.cpp" break; - case 174: -#line 1416 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 189: /* storage_qualifier: DEVICECOHERENT */ +#line 1593 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent"); (yyval.interm.type).qualifier.devicecoherent = true; } -#line 5968 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7146 "MachineIndependent/glslang_tab.cpp" break; - case 175: -#line 1421 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 190: /* storage_qualifier: QUEUEFAMILYCOHERENT */ +#line 1598 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent"); (yyval.interm.type).qualifier.queuefamilycoherent = true; } -#line 5978 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7156 "MachineIndependent/glslang_tab.cpp" break; - case 176: -#line 1426 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 191: /* storage_qualifier: WORKGROUPCOHERENT */ +#line 1603 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent"); (yyval.interm.type).qualifier.workgroupcoherent = true; } -#line 5988 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7166 "MachineIndependent/glslang_tab.cpp" break; - case 177: -#line 1431 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 192: /* storage_qualifier: SUBGROUPCOHERENT */ +#line 1608 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent"); (yyval.interm.type).qualifier.subgroupcoherent = true; } -#line 5998 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7176 "MachineIndependent/glslang_tab.cpp" break; - case 178: -#line 1436 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 193: /* storage_qualifier: NONPRIVATE */ +#line 1613 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate"); (yyval.interm.type).qualifier.nonprivate = true; } -#line 6008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7186 "MachineIndependent/glslang_tab.cpp" break; - case 179: -#line 1441 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 194: /* storage_qualifier: SHADERCALLCOHERENT */ +#line 1618 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_ray_tracing, "shadercallcoherent"); + (yyval.interm.type).qualifier.shadercallcoherent = true; + } +#line 7196 "MachineIndependent/glslang_tab.cpp" + break; + + case 195: /* storage_qualifier: VOLATILE */ +#line 1623 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.volatil = true; } -#line 6017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7205 "MachineIndependent/glslang_tab.cpp" break; - case 180: -#line 1445 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 196: /* storage_qualifier: RESTRICT */ +#line 1627 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.restrict = true; } -#line 6026 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7214 "MachineIndependent/glslang_tab.cpp" break; - case 181: -#line 1449 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 197: /* storage_qualifier: READONLY */ +#line 1631 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.readonly = true; } -#line 6035 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7223 "MachineIndependent/glslang_tab.cpp" break; - case 182: -#line 1453 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 198: /* storage_qualifier: WRITEONLY */ +#line 1635 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.writeonly = true; } -#line 6044 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7232 "MachineIndependent/glslang_tab.cpp" break; - case 183: -#line 1457 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 199: /* storage_qualifier: SUBROUTINE */ +#line 1639 "MachineIndependent/glslang.y" + { parseContext.spvRemoved((yyvsp[0].lex).loc, "subroutine"); parseContext.globalCheck((yyvsp[0].lex).loc, "subroutine"); parseContext.unimplemented((yyvsp[0].lex).loc, "subroutine"); (yyval.interm.type).init((yyvsp[0].lex).loc); } -#line 6055 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7243 "MachineIndependent/glslang_tab.cpp" break; - case 184: -#line 1463 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 200: /* storage_qualifier: SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN */ +#line 1645 "MachineIndependent/glslang.y" + { parseContext.spvRemoved((yyvsp[-3].lex).loc, "subroutine"); parseContext.globalCheck((yyvsp[-3].lex).loc, "subroutine"); parseContext.unimplemented((yyvsp[-3].lex).loc, "subroutine"); (yyval.interm.type).init((yyvsp[-3].lex).loc); } -#line 6066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7254 "MachineIndependent/glslang_tab.cpp" break; - case 185: -#line 1472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 201: /* non_uniform_qualifier: NONUNIFORM */ +#line 1656 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nonUniform = true; } -#line 6075 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7263 "MachineIndependent/glslang_tab.cpp" break; - case 186: -#line 1479 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 202: /* type_name_list: IDENTIFIER */ +#line 1663 "MachineIndependent/glslang.y" + { // TODO } -#line 6083 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7271 "MachineIndependent/glslang_tab.cpp" break; - case 187: -#line 1482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 203: /* type_name_list: type_name_list COMMA IDENTIFIER */ +#line 1666 "MachineIndependent/glslang.y" + { // TODO: 4.0 semantics: subroutines // 1) make sure each identifier is a type declared earlier with SUBROUTINE // 2) save all of the identifiers for future comparison with the declared function } -#line 6093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7281 "MachineIndependent/glslang_tab.cpp" break; - case 188: -#line 1490 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type) = (yyvsp[0].interm.type); - (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); - } -#line 6102 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 189: -#line 1494 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.arrayOfArrayVersionCheck((yyvsp[0].interm).loc, (yyvsp[0].interm).arraySizes); + case 204: /* type_specifier: type_specifier_nonarray type_parameter_specifier_opt */ +#line 1675 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[-1].interm.type); (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); - (yyval.interm.type).arraySizes = (yyvsp[0].interm).arraySizes; + (yyval.interm.type).typeParameters = (yyvsp[0].interm.typeParameters); } -#line 6113 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7291 "MachineIndependent/glslang_tab.cpp" break; - case 190: -#line 1503 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 205: /* type_specifier: type_specifier_nonarray type_parameter_specifier_opt array_specifier */ +#line 1680 "MachineIndependent/glslang.y" + { + parseContext.arrayOfArrayVersionCheck((yyvsp[0].interm).loc, (yyvsp[0].interm).arraySizes); + (yyval.interm.type) = (yyvsp[-2].interm.type); + (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); + (yyval.interm.type).typeParameters = (yyvsp[-1].interm.typeParameters); + (yyval.interm.type).arraySizes = (yyvsp[0].interm).arraySizes; + } +#line 7303 "MachineIndependent/glslang_tab.cpp" + break; + + case 206: /* array_specifier: LEFT_BRACKET RIGHT_BRACKET */ +#line 1690 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).arraySizes = new TArraySizes; (yyval.interm).arraySizes->addInnerSize(); } -#line 6123 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7313 "MachineIndependent/glslang_tab.cpp" break; - case 191: -#line 1508 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 207: /* array_specifier: LEFT_BRACKET conditional_expression RIGHT_BRACKET */ +#line 1695 "MachineIndependent/glslang.y" + { (yyval.interm).loc = (yyvsp[-2].lex).loc; (yyval.interm).arraySizes = new TArraySizes; TArraySize size; - parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size); + parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 6136 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7326 "MachineIndependent/glslang_tab.cpp" break; - case 192: -#line 1516 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 208: /* array_specifier: array_specifier LEFT_BRACKET RIGHT_BRACKET */ +#line 1703 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[-2].interm); (yyval.interm).arraySizes->addInnerSize(); } -#line 6145 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7335 "MachineIndependent/glslang_tab.cpp" break; - case 193: -#line 1520 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 209: /* array_specifier: array_specifier LEFT_BRACKET conditional_expression RIGHT_BRACKET */ +#line 1707 "MachineIndependent/glslang.y" + { (yyval.interm) = (yyvsp[-3].interm); TArraySize size; - parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size); + parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 6157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7347 "MachineIndependent/glslang_tab.cpp" break; - case 194: -#line 1530 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 210: /* type_parameter_specifier_opt: type_parameter_specifier */ +#line 1717 "MachineIndependent/glslang.y" + { + (yyval.interm.typeParameters) = (yyvsp[0].interm.typeParameters); + } +#line 7355 "MachineIndependent/glslang_tab.cpp" + break; + + case 211: /* type_parameter_specifier_opt: %empty */ +#line 1720 "MachineIndependent/glslang.y" + { + (yyval.interm.typeParameters) = 0; + } +#line 7363 "MachineIndependent/glslang_tab.cpp" + break; + + case 212: /* type_parameter_specifier: LEFT_ANGLE type_parameter_specifier_list RIGHT_ANGLE */ +#line 1726 "MachineIndependent/glslang.y" + { + (yyval.interm.typeParameters) = (yyvsp[-1].interm.typeParameters); + } +#line 7371 "MachineIndependent/glslang_tab.cpp" + break; + + case 213: /* type_parameter_specifier_list: unary_expression */ +#line 1732 "MachineIndependent/glslang.y" + { + (yyval.interm.typeParameters) = new TArraySizes; + + TArraySize size; + parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); + (yyval.interm.typeParameters)->addInnerSize(size); + } +#line 7383 "MachineIndependent/glslang_tab.cpp" + break; + + case 214: /* type_parameter_specifier_list: type_parameter_specifier_list COMMA unary_expression */ +#line 1739 "MachineIndependent/glslang.y" + { + (yyval.interm.typeParameters) = (yyvsp[-2].interm.typeParameters); + + TArraySize size; + parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); + (yyval.interm.typeParameters)->addInnerSize(size); + } +#line 7395 "MachineIndependent/glslang_tab.cpp" + break; + + case 215: /* type_specifier_nonarray: VOID */ +#line 1749 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtVoid; } -#line 6166 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7404 "MachineIndependent/glslang_tab.cpp" break; - case 195: -#line 1534 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 216: /* type_specifier_nonarray: FLOAT */ +#line 1753 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; } -#line 6175 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7413 "MachineIndependent/glslang_tab.cpp" break; - case 196: -#line 1538 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - } -#line 6185 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 197: -#line 1543 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - } -#line 6195 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 198: -#line 1548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - } -#line 6205 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 199: -#line 1553 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - } -#line 6215 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 200: -#line 1558 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 217: /* type_specifier_nonarray: INT */ +#line 1757 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; } -#line 6224 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7422 "MachineIndependent/glslang_tab.cpp" break; - case 201: -#line 1562 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 218: /* type_specifier_nonarray: UINT */ +#line 1761 "MachineIndependent/glslang.y" + { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; } -#line 6234 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7432 "MachineIndependent/glslang_tab.cpp" break; - case 202: -#line 1567 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 219: /* type_specifier_nonarray: BOOL */ +#line 1766 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + } +#line 7441 "MachineIndependent/glslang_tab.cpp" + break; + + case 220: /* type_specifier_nonarray: VEC2 */ +#line 1770 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(2); + } +#line 7451 "MachineIndependent/glslang_tab.cpp" + break; + + case 221: /* type_specifier_nonarray: VEC3 */ +#line 1775 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(3); + } +#line 7461 "MachineIndependent/glslang_tab.cpp" + break; + + case 222: /* type_specifier_nonarray: VEC4 */ +#line 1780 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(4); + } +#line 7471 "MachineIndependent/glslang_tab.cpp" + break; + + case 223: /* type_specifier_nonarray: BVEC2 */ +#line 1785 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(2); + } +#line 7481 "MachineIndependent/glslang_tab.cpp" + break; + + case 224: /* type_specifier_nonarray: BVEC3 */ +#line 1790 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(3); + } +#line 7491 "MachineIndependent/glslang_tab.cpp" + break; + + case 225: /* type_specifier_nonarray: BVEC4 */ +#line 1795 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(4); + } +#line 7501 "MachineIndependent/glslang_tab.cpp" + break; + + case 226: /* type_specifier_nonarray: IVEC2 */ +#line 1800 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(2); + } +#line 7511 "MachineIndependent/glslang_tab.cpp" + break; + + case 227: /* type_specifier_nonarray: IVEC3 */ +#line 1805 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(3); + } +#line 7521 "MachineIndependent/glslang_tab.cpp" + break; + + case 228: /* type_specifier_nonarray: IVEC4 */ +#line 1810 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(4); + } +#line 7531 "MachineIndependent/glslang_tab.cpp" + break; + + case 229: /* type_specifier_nonarray: UVEC2 */ +#line 1815 "MachineIndependent/glslang.y" + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(2); + } +#line 7542 "MachineIndependent/glslang_tab.cpp" + break; + + case 230: /* type_specifier_nonarray: UVEC3 */ +#line 1821 "MachineIndependent/glslang.y" + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(3); + } +#line 7553 "MachineIndependent/glslang_tab.cpp" + break; + + case 231: /* type_specifier_nonarray: UVEC4 */ +#line 1827 "MachineIndependent/glslang.y" + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(4); + } +#line 7564 "MachineIndependent/glslang_tab.cpp" + break; + + case 232: /* type_specifier_nonarray: MAT2 */ +#line 1833 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 2); + } +#line 7574 "MachineIndependent/glslang_tab.cpp" + break; + + case 233: /* type_specifier_nonarray: MAT3 */ +#line 1838 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 3); + } +#line 7584 "MachineIndependent/glslang_tab.cpp" + break; + + case 234: /* type_specifier_nonarray: MAT4 */ +#line 1843 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 4); + } +#line 7594 "MachineIndependent/glslang_tab.cpp" + break; + + case 235: /* type_specifier_nonarray: MAT2X2 */ +#line 1848 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 2); + } +#line 7604 "MachineIndependent/glslang_tab.cpp" + break; + + case 236: /* type_specifier_nonarray: MAT2X3 */ +#line 1853 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 3); + } +#line 7614 "MachineIndependent/glslang_tab.cpp" + break; + + case 237: /* type_specifier_nonarray: MAT2X4 */ +#line 1858 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 4); + } +#line 7624 "MachineIndependent/glslang_tab.cpp" + break; + + case 238: /* type_specifier_nonarray: MAT3X2 */ +#line 1863 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 2); + } +#line 7634 "MachineIndependent/glslang_tab.cpp" + break; + + case 239: /* type_specifier_nonarray: MAT3X3 */ +#line 1868 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 3); + } +#line 7644 "MachineIndependent/glslang_tab.cpp" + break; + + case 240: /* type_specifier_nonarray: MAT3X4 */ +#line 1873 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 4); + } +#line 7654 "MachineIndependent/glslang_tab.cpp" + break; + + case 241: /* type_specifier_nonarray: MAT4X2 */ +#line 1878 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 2); + } +#line 7664 "MachineIndependent/glslang_tab.cpp" + break; + + case 242: /* type_specifier_nonarray: MAT4X3 */ +#line 1883 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 3); + } +#line 7674 "MachineIndependent/glslang_tab.cpp" + break; + + case 243: /* type_specifier_nonarray: MAT4X4 */ +#line 1888 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 4); + } +#line 7684 "MachineIndependent/glslang_tab.cpp" + break; + + case 244: /* type_specifier_nonarray: DOUBLE */ +#line 1894 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + } +#line 7696 "MachineIndependent/glslang_tab.cpp" + break; + + case 245: /* type_specifier_nonarray: FLOAT16_T */ +#line 1901 "MachineIndependent/glslang.y" + { + parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + } +#line 7706 "MachineIndependent/glslang_tab.cpp" + break; + + case 246: /* type_specifier_nonarray: FLOAT32_T */ +#line 1906 "MachineIndependent/glslang.y" + { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + } +#line 7716 "MachineIndependent/glslang_tab.cpp" + break; + + case 247: /* type_specifier_nonarray: FLOAT64_T */ +#line 1911 "MachineIndependent/glslang.y" + { + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + } +#line 7726 "MachineIndependent/glslang_tab.cpp" + break; + + case 248: /* type_specifier_nonarray: INT8_T */ +#line 1916 "MachineIndependent/glslang.y" + { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; } -#line 6244 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7736 "MachineIndependent/glslang_tab.cpp" break; - case 203: -#line 1572 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 249: /* type_specifier_nonarray: UINT8_T */ +#line 1921 "MachineIndependent/glslang.y" + { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; } -#line 6254 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7746 "MachineIndependent/glslang_tab.cpp" break; - case 204: -#line 1577 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 250: /* type_specifier_nonarray: INT16_T */ +#line 1926 "MachineIndependent/glslang.y" + { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; } -#line 6264 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7756 "MachineIndependent/glslang_tab.cpp" break; - case 205: -#line 1582 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 251: /* type_specifier_nonarray: UINT16_T */ +#line 1931 "MachineIndependent/glslang.y" + { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; } -#line 6274 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7766 "MachineIndependent/glslang_tab.cpp" break; - case 206: -#line 1587 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 252: /* type_specifier_nonarray: INT32_T */ +#line 1936 "MachineIndependent/glslang.y" + { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; } -#line 6284 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7776 "MachineIndependent/glslang_tab.cpp" break; - case 207: -#line 1592 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 253: /* type_specifier_nonarray: UINT32_T */ +#line 1941 "MachineIndependent/glslang.y" + { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; } -#line 6294 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7786 "MachineIndependent/glslang_tab.cpp" break; - case 208: -#line 1597 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 254: /* type_specifier_nonarray: INT64_T */ +#line 1946 "MachineIndependent/glslang.y" + { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; } -#line 6304 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7796 "MachineIndependent/glslang_tab.cpp" break; - case 209: -#line 1602 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 255: /* type_specifier_nonarray: UINT64_T */ +#line 1951 "MachineIndependent/glslang.y" + { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; } -#line 6314 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7806 "MachineIndependent/glslang_tab.cpp" break; - case 210: -#line 1607 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - } -#line 6323 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 211: -#line 1611 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(2); - } -#line 6333 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 212: -#line 1616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(3); - } -#line 6343 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 213: -#line 1621 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(4); - } -#line 6353 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 214: -#line 1626 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + case 256: /* type_specifier_nonarray: DVEC2 */ +#line 1956 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(2); } -#line 6364 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7819 "MachineIndependent/glslang_tab.cpp" break; - case 215: -#line 1632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + case 257: /* type_specifier_nonarray: DVEC3 */ +#line 1964 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(3); } -#line 6375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7832 "MachineIndependent/glslang_tab.cpp" break; - case 216: -#line 1638 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + case 258: /* type_specifier_nonarray: DVEC4 */ +#line 1972 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(4); } -#line 6386 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7845 "MachineIndependent/glslang_tab.cpp" break; - case 217: -#line 1644 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 259: /* type_specifier_nonarray: F16VEC2 */ +#line 1980 "MachineIndependent/glslang.y" + { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setVector(2); } -#line 6397 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7856 "MachineIndependent/glslang_tab.cpp" break; - case 218: -#line 1650 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 260: /* type_specifier_nonarray: F16VEC3 */ +#line 1986 "MachineIndependent/glslang.y" + { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setVector(3); } -#line 6408 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7867 "MachineIndependent/glslang_tab.cpp" break; - case 219: -#line 1656 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 261: /* type_specifier_nonarray: F16VEC4 */ +#line 1992 "MachineIndependent/glslang.y" + { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setVector(4); } -#line 6419 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7878 "MachineIndependent/glslang_tab.cpp" break; - case 220: -#line 1662 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 262: /* type_specifier_nonarray: F32VEC2 */ +#line 1998 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(2); } -#line 6430 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7889 "MachineIndependent/glslang_tab.cpp" break; - case 221: -#line 1668 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 263: /* type_specifier_nonarray: F32VEC3 */ +#line 2004 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(3); } -#line 6441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7900 "MachineIndependent/glslang_tab.cpp" break; - case 222: -#line 1674 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 264: /* type_specifier_nonarray: F32VEC4 */ +#line 2010 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(4); } -#line 6452 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7911 "MachineIndependent/glslang_tab.cpp" break; - case 223: -#line 1680 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 265: /* type_specifier_nonarray: F64VEC2 */ +#line 2016 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(2); } -#line 6463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7922 "MachineIndependent/glslang_tab.cpp" break; - case 224: -#line 1686 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 266: /* type_specifier_nonarray: F64VEC3 */ +#line 2022 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(3); } -#line 6474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7933 "MachineIndependent/glslang_tab.cpp" break; - case 225: -#line 1692 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 267: /* type_specifier_nonarray: F64VEC4 */ +#line 2028 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(4); } -#line 6485 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7944 "MachineIndependent/glslang_tab.cpp" break; - case 226: -#line 1698 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - (yyval.interm.type).setVector(2); - } -#line 6495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 227: -#line 1703 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - (yyval.interm.type).setVector(3); - } -#line 6505 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 228: -#line 1708 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - (yyval.interm.type).setVector(4); - } -#line 6515 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 229: -#line 1713 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(2); - } -#line 6525 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 230: -#line 1718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(3); - } -#line 6535 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 231: -#line 1723 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(4); - } -#line 6545 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 232: -#line 1728 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 268: /* type_specifier_nonarray: I8VEC2 */ +#line 2034 "MachineIndependent/glslang.y" + { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(2); } -#line 6556 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7955 "MachineIndependent/glslang_tab.cpp" break; - case 233: -#line 1734 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 269: /* type_specifier_nonarray: I8VEC3 */ +#line 2040 "MachineIndependent/glslang.y" + { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(3); } -#line 6567 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7966 "MachineIndependent/glslang_tab.cpp" break; - case 234: -#line 1740 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 270: /* type_specifier_nonarray: I8VEC4 */ +#line 2046 "MachineIndependent/glslang.y" + { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(4); } -#line 6578 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7977 "MachineIndependent/glslang_tab.cpp" break; - case 235: -#line 1746 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 271: /* type_specifier_nonarray: I16VEC2 */ +#line 2052 "MachineIndependent/glslang.y" + { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; (yyval.interm.type).setVector(2); } -#line 6589 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7988 "MachineIndependent/glslang_tab.cpp" break; - case 236: -#line 1752 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 272: /* type_specifier_nonarray: I16VEC3 */ +#line 2058 "MachineIndependent/glslang.y" + { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; (yyval.interm.type).setVector(3); } -#line 6600 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7999 "MachineIndependent/glslang_tab.cpp" break; - case 237: -#line 1758 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 273: /* type_specifier_nonarray: I16VEC4 */ +#line 2064 "MachineIndependent/glslang.y" + { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; (yyval.interm.type).setVector(4); } -#line 6611 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8010 "MachineIndependent/glslang_tab.cpp" break; - case 238: -#line 1764 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 274: /* type_specifier_nonarray: I32VEC2 */ +#line 2070 "MachineIndependent/glslang.y" + { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(2); } -#line 6622 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8021 "MachineIndependent/glslang_tab.cpp" break; - case 239: -#line 1770 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 275: /* type_specifier_nonarray: I32VEC3 */ +#line 2076 "MachineIndependent/glslang.y" + { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(3); } -#line 6633 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8032 "MachineIndependent/glslang_tab.cpp" break; - case 240: -#line 1776 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 276: /* type_specifier_nonarray: I32VEC4 */ +#line 2082 "MachineIndependent/glslang.y" + { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(4); } -#line 6644 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8043 "MachineIndependent/glslang_tab.cpp" break; - case 241: -#line 1782 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 277: /* type_specifier_nonarray: I64VEC2 */ +#line 2088 "MachineIndependent/glslang.y" + { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(2); } -#line 6655 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8054 "MachineIndependent/glslang_tab.cpp" break; - case 242: -#line 1788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 278: /* type_specifier_nonarray: I64VEC3 */ +#line 2094 "MachineIndependent/glslang.y" + { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(3); } -#line 6666 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8065 "MachineIndependent/glslang_tab.cpp" break; - case 243: -#line 1794 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 279: /* type_specifier_nonarray: I64VEC4 */ +#line 2100 "MachineIndependent/glslang.y" + { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(4); } -#line 6677 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8076 "MachineIndependent/glslang_tab.cpp" break; - case 244: -#line 1800 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint; - (yyval.interm.type).setVector(2); - } -#line 6688 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 245: -#line 1806 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint; - (yyval.interm.type).setVector(3); - } -#line 6699 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 246: -#line 1812 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint; - (yyval.interm.type).setVector(4); - } -#line 6710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 247: -#line 1818 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 280: /* type_specifier_nonarray: U8VEC2 */ +#line 2106 "MachineIndependent/glslang.y" + { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; (yyval.interm.type).setVector(2); } -#line 6721 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8087 "MachineIndependent/glslang_tab.cpp" break; - case 248: -#line 1824 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 281: /* type_specifier_nonarray: U8VEC3 */ +#line 2112 "MachineIndependent/glslang.y" + { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; (yyval.interm.type).setVector(3); } -#line 6732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8098 "MachineIndependent/glslang_tab.cpp" break; - case 249: -#line 1830 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 282: /* type_specifier_nonarray: U8VEC4 */ +#line 2118 "MachineIndependent/glslang.y" + { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; (yyval.interm.type).setVector(4); } -#line 6743 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8109 "MachineIndependent/glslang_tab.cpp" break; - case 250: -#line 1836 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 283: /* type_specifier_nonarray: U16VEC2 */ +#line 2124 "MachineIndependent/glslang.y" + { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; (yyval.interm.type).setVector(2); } -#line 6754 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8120 "MachineIndependent/glslang_tab.cpp" break; - case 251: -#line 1842 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 284: /* type_specifier_nonarray: U16VEC3 */ +#line 2130 "MachineIndependent/glslang.y" + { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; (yyval.interm.type).setVector(3); } -#line 6765 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8131 "MachineIndependent/glslang_tab.cpp" break; - case 252: -#line 1848 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 285: /* type_specifier_nonarray: U16VEC4 */ +#line 2136 "MachineIndependent/glslang.y" + { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; (yyval.interm.type).setVector(4); } -#line 6776 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8142 "MachineIndependent/glslang_tab.cpp" break; - case 253: -#line 1854 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 286: /* type_specifier_nonarray: U32VEC2 */ +#line 2142 "MachineIndependent/glslang.y" + { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(2); } -#line 6787 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8153 "MachineIndependent/glslang_tab.cpp" break; - case 254: -#line 1860 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 287: /* type_specifier_nonarray: U32VEC3 */ +#line 2148 "MachineIndependent/glslang.y" + { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(3); } -#line 6798 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8164 "MachineIndependent/glslang_tab.cpp" break; - case 255: -#line 1866 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 288: /* type_specifier_nonarray: U32VEC4 */ +#line 2154 "MachineIndependent/glslang.y" + { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(4); } -#line 6809 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8175 "MachineIndependent/glslang_tab.cpp" break; - case 256: -#line 1872 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 289: /* type_specifier_nonarray: U64VEC2 */ +#line 2160 "MachineIndependent/glslang.y" + { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(2); } -#line 6820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8186 "MachineIndependent/glslang_tab.cpp" break; - case 257: -#line 1878 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 290: /* type_specifier_nonarray: U64VEC3 */ +#line 2166 "MachineIndependent/glslang.y" + { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(3); } -#line 6831 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8197 "MachineIndependent/glslang_tab.cpp" break; - case 258: -#line 1884 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 291: /* type_specifier_nonarray: U64VEC4 */ +#line 2172 "MachineIndependent/glslang.y" + { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(4); } -#line 6842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8208 "MachineIndependent/glslang_tab.cpp" break; - case 259: -#line 1890 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(2, 2); - } -#line 6852 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 260: -#line 1895 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(3, 3); - } -#line 6862 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 261: -#line 1900 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(4, 4); - } -#line 6872 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 262: -#line 1905 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(2, 2); - } -#line 6882 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 263: -#line 1910 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(2, 3); - } -#line 6892 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 264: -#line 1915 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(2, 4); - } -#line 6902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 265: -#line 1920 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(3, 2); - } -#line 6912 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 266: -#line 1925 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(3, 3); - } -#line 6922 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 267: -#line 1930 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(3, 4); - } -#line 6932 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 268: -#line 1935 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(4, 2); - } -#line 6942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 269: -#line 1940 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(4, 3); - } -#line 6952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 270: -#line 1945 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(4, 4); - } -#line 6962 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 271: -#line 1950 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 292: /* type_specifier_nonarray: DMAT2 */ +#line 2178 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 6973 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8221 "MachineIndependent/glslang_tab.cpp" break; - case 272: -#line 1956 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 293: /* type_specifier_nonarray: DMAT3 */ +#line 2186 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 6984 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8234 "MachineIndependent/glslang_tab.cpp" break; - case 273: -#line 1962 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 294: /* type_specifier_nonarray: DMAT4 */ +#line 2194 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 6995 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8247 "MachineIndependent/glslang_tab.cpp" break; - case 274: -#line 1968 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 295: /* type_specifier_nonarray: DMAT2X2 */ +#line 2202 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 7006 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8260 "MachineIndependent/glslang_tab.cpp" break; - case 275: -#line 1974 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 296: /* type_specifier_nonarray: DMAT2X3 */ +#line 2210 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 3); } -#line 7017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8273 "MachineIndependent/glslang_tab.cpp" break; - case 276: -#line 1980 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 297: /* type_specifier_nonarray: DMAT2X4 */ +#line 2218 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 4); } -#line 7028 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8286 "MachineIndependent/glslang_tab.cpp" break; - case 277: -#line 1986 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 298: /* type_specifier_nonarray: DMAT3X2 */ +#line 2226 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 2); } -#line 7039 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8299 "MachineIndependent/glslang_tab.cpp" break; - case 278: -#line 1992 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 299: /* type_specifier_nonarray: DMAT3X3 */ +#line 2234 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 7050 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8312 "MachineIndependent/glslang_tab.cpp" break; - case 279: -#line 1998 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 300: /* type_specifier_nonarray: DMAT3X4 */ +#line 2242 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 4); } -#line 7061 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8325 "MachineIndependent/glslang_tab.cpp" break; - case 280: -#line 2004 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 301: /* type_specifier_nonarray: DMAT4X2 */ +#line 2250 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 2); } -#line 7072 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8338 "MachineIndependent/glslang_tab.cpp" break; - case 281: -#line 2010 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 302: /* type_specifier_nonarray: DMAT4X3 */ +#line 2258 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 3); } -#line 7083 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8351 "MachineIndependent/glslang_tab.cpp" break; - case 282: -#line 2016 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + case 303: /* type_specifier_nonarray: DMAT4X4 */ +#line 2266 "MachineIndependent/glslang.y" + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 7094 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8364 "MachineIndependent/glslang_tab.cpp" break; - case 283: -#line 2022 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 304: /* type_specifier_nonarray: F16MAT2 */ +#line 2274 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 2); } -#line 7105 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8375 "MachineIndependent/glslang_tab.cpp" break; - case 284: -#line 2028 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 305: /* type_specifier_nonarray: F16MAT3 */ +#line 2280 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 3); } -#line 7116 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8386 "MachineIndependent/glslang_tab.cpp" break; - case 285: -#line 2034 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 306: /* type_specifier_nonarray: F16MAT4 */ +#line 2286 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 4); } -#line 7127 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8397 "MachineIndependent/glslang_tab.cpp" break; - case 286: -#line 2040 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 307: /* type_specifier_nonarray: F16MAT2X2 */ +#line 2292 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 2); } -#line 7138 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8408 "MachineIndependent/glslang_tab.cpp" break; - case 287: -#line 2046 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 308: /* type_specifier_nonarray: F16MAT2X3 */ +#line 2298 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 3); } -#line 7149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8419 "MachineIndependent/glslang_tab.cpp" break; - case 288: -#line 2052 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 309: /* type_specifier_nonarray: F16MAT2X4 */ +#line 2304 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 4); } -#line 7160 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8430 "MachineIndependent/glslang_tab.cpp" break; - case 289: -#line 2058 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 310: /* type_specifier_nonarray: F16MAT3X2 */ +#line 2310 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 2); } -#line 7171 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8441 "MachineIndependent/glslang_tab.cpp" break; - case 290: -#line 2064 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 311: /* type_specifier_nonarray: F16MAT3X3 */ +#line 2316 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 3); } -#line 7182 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8452 "MachineIndependent/glslang_tab.cpp" break; - case 291: -#line 2070 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 312: /* type_specifier_nonarray: F16MAT3X4 */ +#line 2322 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 4); } -#line 7193 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8463 "MachineIndependent/glslang_tab.cpp" break; - case 292: -#line 2076 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 313: /* type_specifier_nonarray: F16MAT4X2 */ +#line 2328 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 2); } -#line 7204 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8474 "MachineIndependent/glslang_tab.cpp" break; - case 293: -#line 2082 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 314: /* type_specifier_nonarray: F16MAT4X3 */ +#line 2334 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 3); } -#line 7215 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8485 "MachineIndependent/glslang_tab.cpp" break; - case 294: -#line 2088 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 315: /* type_specifier_nonarray: F16MAT4X4 */ +#line 2340 "MachineIndependent/glslang.y" + { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 4); } -#line 7226 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8496 "MachineIndependent/glslang_tab.cpp" break; - case 295: -#line 2094 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 316: /* type_specifier_nonarray: F32MAT2 */ +#line 2346 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 7237 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8507 "MachineIndependent/glslang_tab.cpp" break; - case 296: -#line 2100 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 317: /* type_specifier_nonarray: F32MAT3 */ +#line 2352 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 7248 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8518 "MachineIndependent/glslang_tab.cpp" break; - case 297: -#line 2106 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 318: /* type_specifier_nonarray: F32MAT4 */ +#line 2358 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 7259 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8529 "MachineIndependent/glslang_tab.cpp" break; - case 298: -#line 2112 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 319: /* type_specifier_nonarray: F32MAT2X2 */ +#line 2364 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 7270 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8540 "MachineIndependent/glslang_tab.cpp" break; - case 299: -#line 2118 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 320: /* type_specifier_nonarray: F32MAT2X3 */ +#line 2370 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 3); } -#line 7281 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8551 "MachineIndependent/glslang_tab.cpp" break; - case 300: -#line 2124 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 321: /* type_specifier_nonarray: F32MAT2X4 */ +#line 2376 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 4); } -#line 7292 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8562 "MachineIndependent/glslang_tab.cpp" break; - case 301: -#line 2130 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 322: /* type_specifier_nonarray: F32MAT3X2 */ +#line 2382 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 2); } -#line 7303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8573 "MachineIndependent/glslang_tab.cpp" break; - case 302: -#line 2136 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 323: /* type_specifier_nonarray: F32MAT3X3 */ +#line 2388 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 7314 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8584 "MachineIndependent/glslang_tab.cpp" break; - case 303: -#line 2142 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 324: /* type_specifier_nonarray: F32MAT3X4 */ +#line 2394 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 4); } -#line 7325 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8595 "MachineIndependent/glslang_tab.cpp" break; - case 304: -#line 2148 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 325: /* type_specifier_nonarray: F32MAT4X2 */ +#line 2400 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 2); } -#line 7336 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8606 "MachineIndependent/glslang_tab.cpp" break; - case 305: -#line 2154 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 326: /* type_specifier_nonarray: F32MAT4X3 */ +#line 2406 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 3); } -#line 7347 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8617 "MachineIndependent/glslang_tab.cpp" break; - case 306: -#line 2160 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 327: /* type_specifier_nonarray: F32MAT4X4 */ +#line 2412 "MachineIndependent/glslang.y" + { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 7358 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8628 "MachineIndependent/glslang_tab.cpp" break; - case 307: -#line 2166 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 328: /* type_specifier_nonarray: F64MAT2 */ +#line 2418 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 7369 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8639 "MachineIndependent/glslang_tab.cpp" break; - case 308: -#line 2172 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 329: /* type_specifier_nonarray: F64MAT3 */ +#line 2424 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 7380 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8650 "MachineIndependent/glslang_tab.cpp" break; - case 309: -#line 2178 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 330: /* type_specifier_nonarray: F64MAT4 */ +#line 2430 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 7391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8661 "MachineIndependent/glslang_tab.cpp" break; - case 310: -#line 2184 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 331: /* type_specifier_nonarray: F64MAT2X2 */ +#line 2436 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 7402 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8672 "MachineIndependent/glslang_tab.cpp" break; - case 311: -#line 2190 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 332: /* type_specifier_nonarray: F64MAT2X3 */ +#line 2442 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 3); } -#line 7413 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8683 "MachineIndependent/glslang_tab.cpp" break; - case 312: -#line 2196 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 333: /* type_specifier_nonarray: F64MAT2X4 */ +#line 2448 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 4); } -#line 7424 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8694 "MachineIndependent/glslang_tab.cpp" break; - case 313: -#line 2202 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 334: /* type_specifier_nonarray: F64MAT3X2 */ +#line 2454 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 2); } -#line 7435 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8705 "MachineIndependent/glslang_tab.cpp" break; - case 314: -#line 2208 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 335: /* type_specifier_nonarray: F64MAT3X3 */ +#line 2460 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 7446 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8716 "MachineIndependent/glslang_tab.cpp" break; - case 315: -#line 2214 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 336: /* type_specifier_nonarray: F64MAT3X4 */ +#line 2466 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 4); } -#line 7457 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8727 "MachineIndependent/glslang_tab.cpp" break; - case 316: -#line 2220 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 337: /* type_specifier_nonarray: F64MAT4X2 */ +#line 2472 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 2); } -#line 7468 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8738 "MachineIndependent/glslang_tab.cpp" break; - case 317: -#line 2226 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 338: /* type_specifier_nonarray: F64MAT4X3 */ +#line 2478 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 3); } -#line 7479 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8749 "MachineIndependent/glslang_tab.cpp" break; - case 318: -#line 2232 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 339: /* type_specifier_nonarray: F64MAT4X4 */ +#line 2484 "MachineIndependent/glslang.y" + { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 7490 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8760 "MachineIndependent/glslang_tab.cpp" break; - case 319: -#line 2238 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef NV_EXTENSIONS + case 340: /* type_specifier_nonarray: ACCSTRUCTNV */ +#line 2490 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtAccStructNV; -#endif + (yyval.interm.type).basicType = EbtAccStruct; } -#line 7501 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8769 "MachineIndependent/glslang_tab.cpp" break; - case 320: -#line 2244 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 341: /* type_specifier_nonarray: ACCSTRUCTEXT */ +#line 2494 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtAccStruct; + } +#line 8778 "MachineIndependent/glslang_tab.cpp" + break; + + case 342: /* type_specifier_nonarray: RAYQUERYEXT */ +#line 2498 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtRayQuery; + } +#line 8787 "MachineIndependent/glslang_tab.cpp" + break; + + case 343: /* type_specifier_nonarray: ATOMIC_UINT */ +#line 2502 "MachineIndependent/glslang.y" + { parseContext.vulkanRemoved((yyvsp[0].lex).loc, "atomic counter types"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtAtomicUint; } -#line 7511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8797 "MachineIndependent/glslang_tab.cpp" break; - case 321: -#line 2249 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 344: /* type_specifier_nonarray: SAMPLER1D */ +#line 2507 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D); } -#line 7521 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8807 "MachineIndependent/glslang_tab.cpp" break; - case 322: -#line 2254 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 345: /* type_specifier_nonarray: SAMPLER2D */ +#line 2513 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); } -#line 7531 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8817 "MachineIndependent/glslang_tab.cpp" break; - case 323: -#line 2259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 346: /* type_specifier_nonarray: SAMPLER3D */ +#line 2518 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd3D); } -#line 7541 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8827 "MachineIndependent/glslang_tab.cpp" break; - case 324: -#line 2264 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 347: /* type_specifier_nonarray: SAMPLERCUBE */ +#line 2523 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube); } -#line 7551 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8837 "MachineIndependent/glslang_tab.cpp" break; - case 325: -#line 2269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd1D, false, true); - } -#line 7561 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 326: -#line 2274 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 348: /* type_specifier_nonarray: SAMPLER2DSHADOW */ +#line 2528 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, true); } -#line 7571 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8847 "MachineIndependent/glslang_tab.cpp" break; - case 327: -#line 2279 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 349: /* type_specifier_nonarray: SAMPLERCUBESHADOW */ +#line 2533 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, false, true); } -#line 7581 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8857 "MachineIndependent/glslang_tab.cpp" break; - case 328: -#line 2284 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true); - } -#line 7591 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 329: -#line 2289 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 350: /* type_specifier_nonarray: SAMPLER2DARRAY */ +#line 2538 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true); } -#line 7601 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8867 "MachineIndependent/glslang_tab.cpp" break; - case 330: -#line 2294 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true, true); - } -#line 7611 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 331: -#line 2299 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 351: /* type_specifier_nonarray: SAMPLER2DARRAYSHADOW */ +#line 2543 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, true); } -#line 7621 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8877 "MachineIndependent/glslang_tab.cpp" break; - case 332: -#line 2304 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 352: /* type_specifier_nonarray: SAMPLER1DSHADOW */ +#line 2549 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D, false, true); + } +#line 8887 "MachineIndependent/glslang_tab.cpp" + break; + + case 353: /* type_specifier_nonarray: SAMPLER1DARRAY */ +#line 2554 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true); + } +#line 8897 "MachineIndependent/glslang_tab.cpp" + break; + + case 354: /* type_specifier_nonarray: SAMPLER1DARRAYSHADOW */ +#line 2559 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true, true); + } +#line 8907 "MachineIndependent/glslang_tab.cpp" + break; + + case 355: /* type_specifier_nonarray: SAMPLERCUBEARRAY */ +#line 2564 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true); } -#line 7631 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8917 "MachineIndependent/glslang_tab.cpp" break; - case 333: -#line 2309 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 356: /* type_specifier_nonarray: SAMPLERCUBEARRAYSHADOW */ +#line 2569 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true, true); } -#line 7641 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8927 "MachineIndependent/glslang_tab.cpp" break; - case 334: -#line 2314 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 357: /* type_specifier_nonarray: F16SAMPLER1D */ +#line 2574 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D); -#endif } -#line 7654 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8938 "MachineIndependent/glslang_tab.cpp" break; - case 335: -#line 2322 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 358: /* type_specifier_nonarray: F16SAMPLER2D */ +#line 2580 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D); -#endif } -#line 7667 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8949 "MachineIndependent/glslang_tab.cpp" break; - case 336: -#line 2330 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 359: /* type_specifier_nonarray: F16SAMPLER3D */ +#line 2586 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd3D); -#endif } -#line 7680 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8960 "MachineIndependent/glslang_tab.cpp" break; - case 337: -#line 2338 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 360: /* type_specifier_nonarray: F16SAMPLERCUBE */ +#line 2592 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube); -#endif } -#line 7693 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8971 "MachineIndependent/glslang_tab.cpp" break; - case 338: -#line 2346 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 361: /* type_specifier_nonarray: F16SAMPLER1DSHADOW */ +#line 2598 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, false, true); -#endif } -#line 7706 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8982 "MachineIndependent/glslang_tab.cpp" break; - case 339: -#line 2354 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 362: /* type_specifier_nonarray: F16SAMPLER2DSHADOW */ +#line 2604 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, true); -#endif } -#line 7719 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8993 "MachineIndependent/glslang_tab.cpp" break; - case 340: -#line 2362 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 363: /* type_specifier_nonarray: F16SAMPLERCUBESHADOW */ +#line 2610 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, false, true); -#endif } -#line 7732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9004 "MachineIndependent/glslang_tab.cpp" break; - case 341: -#line 2370 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 364: /* type_specifier_nonarray: F16SAMPLER1DARRAY */ +#line 2616 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true); -#endif } -#line 7745 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9015 "MachineIndependent/glslang_tab.cpp" break; - case 342: -#line 2378 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 365: /* type_specifier_nonarray: F16SAMPLER2DARRAY */ +#line 2622 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true); -#endif } -#line 7758 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9026 "MachineIndependent/glslang_tab.cpp" break; - case 343: -#line 2386 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 366: /* type_specifier_nonarray: F16SAMPLER1DARRAYSHADOW */ +#line 2628 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true, true); -#endif } -#line 7771 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9037 "MachineIndependent/glslang_tab.cpp" break; - case 344: -#line 2394 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 367: /* type_specifier_nonarray: F16SAMPLER2DARRAYSHADOW */ +#line 2634 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, true); -#endif } -#line 7784 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9048 "MachineIndependent/glslang_tab.cpp" break; - case 345: -#line 2402 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 368: /* type_specifier_nonarray: F16SAMPLERCUBEARRAY */ +#line 2640 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true); -#endif } -#line 7797 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9059 "MachineIndependent/glslang_tab.cpp" break; - case 346: -#line 2410 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 369: /* type_specifier_nonarray: F16SAMPLERCUBEARRAYSHADOW */ +#line 2646 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true, true); -#endif } -#line 7810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9070 "MachineIndependent/glslang_tab.cpp" break; - case 347: -#line 2418 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 370: /* type_specifier_nonarray: ISAMPLER1D */ +#line 2652 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd1D); } -#line 7820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9080 "MachineIndependent/glslang_tab.cpp" break; - case 348: -#line 2423 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 371: /* type_specifier_nonarray: ISAMPLER2D */ +#line 2658 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D); } -#line 7830 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9090 "MachineIndependent/glslang_tab.cpp" break; - case 349: -#line 2428 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 372: /* type_specifier_nonarray: ISAMPLER3D */ +#line 2663 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd3D); } -#line 7840 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9100 "MachineIndependent/glslang_tab.cpp" break; - case 350: -#line 2433 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 373: /* type_specifier_nonarray: ISAMPLERCUBE */ +#line 2668 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdCube); } -#line 7850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9110 "MachineIndependent/glslang_tab.cpp" break; - case 351: -#line 2438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd1D, true); - } -#line 7860 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 352: -#line 2443 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 374: /* type_specifier_nonarray: ISAMPLER2DARRAY */ +#line 2673 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, true); } -#line 7870 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9120 "MachineIndependent/glslang_tab.cpp" break; - case 353: -#line 2448 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, EsdCube, true); - } -#line 7880 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 354: -#line 2453 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd1D); - } -#line 7890 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 355: -#line 2458 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 375: /* type_specifier_nonarray: USAMPLER2D */ +#line 2678 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D); } -#line 7900 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9130 "MachineIndependent/glslang_tab.cpp" break; - case 356: -#line 2463 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 376: /* type_specifier_nonarray: USAMPLER3D */ +#line 2683 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd3D); } -#line 7910 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9140 "MachineIndependent/glslang_tab.cpp" break; - case 357: -#line 2468 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 377: /* type_specifier_nonarray: USAMPLERCUBE */ +#line 2688 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdCube); } -#line 7920 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9150 "MachineIndependent/glslang_tab.cpp" break; - case 358: -#line 2473 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 378: /* type_specifier_nonarray: ISAMPLER1DARRAY */ +#line 2694 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd1D, true); + } +#line 9160 "MachineIndependent/glslang_tab.cpp" + break; + + case 379: /* type_specifier_nonarray: ISAMPLERCUBEARRAY */ +#line 2699 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, EsdCube, true); + } +#line 9170 "MachineIndependent/glslang_tab.cpp" + break; + + case 380: /* type_specifier_nonarray: USAMPLER1D */ +#line 2704 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd1D); + } +#line 9180 "MachineIndependent/glslang_tab.cpp" + break; + + case 381: /* type_specifier_nonarray: USAMPLER1DARRAY */ +#line 2709 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd1D, true); } -#line 7930 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9190 "MachineIndependent/glslang_tab.cpp" break; - case 359: -#line 2478 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd2D, true); - } -#line 7940 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 360: -#line 2483 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 382: /* type_specifier_nonarray: USAMPLERCUBEARRAY */ +#line 2714 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdCube, true); } -#line 7950 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9200 "MachineIndependent/glslang_tab.cpp" break; - case 361: -#line 2488 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdRect); - } -#line 7960 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 362: -#line 2493 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdRect, false, true); - } -#line 7970 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 363: -#line 2498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat16, EsdRect); -#endif - } -#line 7983 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 364: -#line 2506 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat16, EsdRect, false, true); -#endif - } -#line 7996 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 365: -#line 2514 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, EsdRect); - } -#line 8006 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 366: -#line 2519 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, EsdRect); - } -#line 8016 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 367: -#line 2524 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdBuffer); - } -#line 8026 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 368: -#line 2529 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat16, EsdBuffer); -#endif - } -#line 8039 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 369: -#line 2537 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, EsdBuffer); - } -#line 8049 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 370: -#line 2542 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, EsdBuffer); - } -#line 8059 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 371: -#line 2547 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, false, true); - } -#line 8069 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 372: -#line 2552 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, false, true); -#endif - } -#line 8082 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 373: -#line 2560 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd2D, false, false, true); - } -#line 8092 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 374: -#line 2565 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd2D, false, false, true); - } -#line 8102 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 375: -#line 2570 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, false, true); - } -#line 8112 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 376: -#line 2575 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, false, true); -#endif - } -#line 8125 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 377: -#line 2583 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd2D, true, false, true); - } -#line 8135 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 378: -#line 2588 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd2D, true, false, true); - } -#line 8145 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 379: -#line 2593 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setPureSampler(false); - } -#line 8155 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 380: -#line 2598 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setPureSampler(true); - } -#line 8165 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 381: -#line 2603 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D); - } -#line 8175 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 382: -#line 2608 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D); -#endif - } -#line 8188 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 383: -#line 2616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D); - } -#line 8198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 384: -#line 2621 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D); -#endif - } -#line 8211 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 385: -#line 2629 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd3D); - } -#line 8221 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 386: -#line 2634 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd3D); -#endif - } -#line 8234 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 387: -#line 2642 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube); - } -#line 8244 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 388: -#line 2647 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube); -#endif - } -#line 8257 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 389: -#line 2655 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D, true); - } -#line 8267 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 390: -#line 2660 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D, true); -#endif - } -#line 8280 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 391: -#line 2668 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true); - } -#line 8290 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 392: -#line 2673 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true); -#endif - } -#line 8303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 393: -#line 2681 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 383: /* type_specifier_nonarray: TEXTURECUBEARRAY */ +#line 2719 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube, true); } -#line 8313 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9210 "MachineIndependent/glslang_tab.cpp" break; - case 394: -#line 2686 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS - parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube, true); -#endif - } -#line 8326 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 395: -#line 2694 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D); - } -#line 8336 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 396: -#line 2699 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D); - } -#line 8346 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 397: -#line 2704 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtInt, Esd3D); - } -#line 8356 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 398: -#line 2709 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube); - } -#line 8366 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 399: -#line 2714 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D, true); - } -#line 8376 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 400: -#line 2719 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true); - } -#line 8386 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 401: -#line 2724 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 384: /* type_specifier_nonarray: ITEXTURECUBEARRAY */ +#line 2724 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube, true); } -#line 8396 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9220 "MachineIndependent/glslang_tab.cpp" break; - case 402: -#line 2729 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D); - } -#line 8406 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 403: -#line 2734 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D); - } -#line 8416 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 404: -#line 2739 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtUint, Esd3D); - } -#line 8426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 405: -#line 2744 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube); - } -#line 8436 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 406: -#line 2749 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D, true); - } -#line 8446 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 407: -#line 2754 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true); - } -#line 8456 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 408: -#line 2759 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 385: /* type_specifier_nonarray: UTEXTURECUBEARRAY */ +#line 2729 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube, true); } -#line 8466 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9230 "MachineIndependent/glslang_tab.cpp" break; - case 409: -#line 2764 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 386: /* type_specifier_nonarray: USAMPLER2DARRAY */ +#line 2735 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd2D, true); + } +#line 9240 "MachineIndependent/glslang_tab.cpp" + break; + + case 387: /* type_specifier_nonarray: TEXTURE2D */ +#line 2740 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D); + } +#line 9250 "MachineIndependent/glslang_tab.cpp" + break; + + case 388: /* type_specifier_nonarray: TEXTURE3D */ +#line 2745 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd3D); + } +#line 9260 "MachineIndependent/glslang_tab.cpp" + break; + + case 389: /* type_specifier_nonarray: TEXTURE2DARRAY */ +#line 2750 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true); + } +#line 9270 "MachineIndependent/glslang_tab.cpp" + break; + + case 390: /* type_specifier_nonarray: TEXTURECUBE */ +#line 2755 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube); + } +#line 9280 "MachineIndependent/glslang_tab.cpp" + break; + + case 391: /* type_specifier_nonarray: ITEXTURE2D */ +#line 2760 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D); + } +#line 9290 "MachineIndependent/glslang_tab.cpp" + break; + + case 392: /* type_specifier_nonarray: ITEXTURE3D */ +#line 2765 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd3D); + } +#line 9300 "MachineIndependent/glslang_tab.cpp" + break; + + case 393: /* type_specifier_nonarray: ITEXTURECUBE */ +#line 2770 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube); + } +#line 9310 "MachineIndependent/glslang_tab.cpp" + break; + + case 394: /* type_specifier_nonarray: ITEXTURE2DARRAY */ +#line 2775 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true); + } +#line 9320 "MachineIndependent/glslang_tab.cpp" + break; + + case 395: /* type_specifier_nonarray: UTEXTURE2D */ +#line 2780 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D); + } +#line 9330 "MachineIndependent/glslang_tab.cpp" + break; + + case 396: /* type_specifier_nonarray: UTEXTURE3D */ +#line 2785 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd3D); + } +#line 9340 "MachineIndependent/glslang_tab.cpp" + break; + + case 397: /* type_specifier_nonarray: UTEXTURECUBE */ +#line 2790 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube); + } +#line 9350 "MachineIndependent/glslang_tab.cpp" + break; + + case 398: /* type_specifier_nonarray: UTEXTURE2DARRAY */ +#line 2795 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true); + } +#line 9360 "MachineIndependent/glslang_tab.cpp" + break; + + case 399: /* type_specifier_nonarray: SAMPLER */ +#line 2800 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setPureSampler(false); + } +#line 9370 "MachineIndependent/glslang_tab.cpp" + break; + + case 400: /* type_specifier_nonarray: SAMPLERSHADOW */ +#line 2805 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setPureSampler(true); + } +#line 9380 "MachineIndependent/glslang_tab.cpp" + break; + + case 401: /* type_specifier_nonarray: SAMPLER2DRECT */ +#line 2811 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdRect); + } +#line 9390 "MachineIndependent/glslang_tab.cpp" + break; + + case 402: /* type_specifier_nonarray: SAMPLER2DRECTSHADOW */ +#line 2816 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdRect, false, true); + } +#line 9400 "MachineIndependent/glslang_tab.cpp" + break; + + case 403: /* type_specifier_nonarray: F16SAMPLER2DRECT */ +#line 2821 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, EsdRect); + } +#line 9411 "MachineIndependent/glslang_tab.cpp" + break; + + case 404: /* type_specifier_nonarray: F16SAMPLER2DRECTSHADOW */ +#line 2827 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, EsdRect, false, true); + } +#line 9422 "MachineIndependent/glslang_tab.cpp" + break; + + case 405: /* type_specifier_nonarray: ISAMPLER2DRECT */ +#line 2833 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, EsdRect); + } +#line 9432 "MachineIndependent/glslang_tab.cpp" + break; + + case 406: /* type_specifier_nonarray: USAMPLER2DRECT */ +#line 2838 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, EsdRect); + } +#line 9442 "MachineIndependent/glslang_tab.cpp" + break; + + case 407: /* type_specifier_nonarray: SAMPLERBUFFER */ +#line 2843 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdBuffer); + } +#line 9452 "MachineIndependent/glslang_tab.cpp" + break; + + case 408: /* type_specifier_nonarray: F16SAMPLERBUFFER */ +#line 2848 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, EsdBuffer); + } +#line 9463 "MachineIndependent/glslang_tab.cpp" + break; + + case 409: /* type_specifier_nonarray: ISAMPLERBUFFER */ +#line 2854 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, EsdBuffer); + } +#line 9473 "MachineIndependent/glslang_tab.cpp" + break; + + case 410: /* type_specifier_nonarray: USAMPLERBUFFER */ +#line 2859 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, EsdBuffer); + } +#line 9483 "MachineIndependent/glslang_tab.cpp" + break; + + case 411: /* type_specifier_nonarray: SAMPLER2DMS */ +#line 2864 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, false, true); + } +#line 9493 "MachineIndependent/glslang_tab.cpp" + break; + + case 412: /* type_specifier_nonarray: F16SAMPLER2DMS */ +#line 2869 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, false, true); + } +#line 9504 "MachineIndependent/glslang_tab.cpp" + break; + + case 413: /* type_specifier_nonarray: ISAMPLER2DMS */ +#line 2875 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd2D, false, false, true); + } +#line 9514 "MachineIndependent/glslang_tab.cpp" + break; + + case 414: /* type_specifier_nonarray: USAMPLER2DMS */ +#line 2880 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd2D, false, false, true); + } +#line 9524 "MachineIndependent/glslang_tab.cpp" + break; + + case 415: /* type_specifier_nonarray: SAMPLER2DMSARRAY */ +#line 2885 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, false, true); + } +#line 9534 "MachineIndependent/glslang_tab.cpp" + break; + + case 416: /* type_specifier_nonarray: F16SAMPLER2DMSARRAY */ +#line 2890 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, false, true); + } +#line 9545 "MachineIndependent/glslang_tab.cpp" + break; + + case 417: /* type_specifier_nonarray: ISAMPLER2DMSARRAY */ +#line 2896 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd2D, true, false, true); + } +#line 9555 "MachineIndependent/glslang_tab.cpp" + break; + + case 418: /* type_specifier_nonarray: USAMPLER2DMSARRAY */ +#line 2901 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd2D, true, false, true); + } +#line 9565 "MachineIndependent/glslang_tab.cpp" + break; + + case 419: /* type_specifier_nonarray: TEXTURE1D */ +#line 2906 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D); + } +#line 9575 "MachineIndependent/glslang_tab.cpp" + break; + + case 420: /* type_specifier_nonarray: F16TEXTURE1D */ +#line 2911 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D); + } +#line 9586 "MachineIndependent/glslang_tab.cpp" + break; + + case 421: /* type_specifier_nonarray: F16TEXTURE2D */ +#line 2917 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D); + } +#line 9597 "MachineIndependent/glslang_tab.cpp" + break; + + case 422: /* type_specifier_nonarray: F16TEXTURE3D */ +#line 2923 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd3D); + } +#line 9608 "MachineIndependent/glslang_tab.cpp" + break; + + case 423: /* type_specifier_nonarray: F16TEXTURECUBE */ +#line 2929 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube); + } +#line 9619 "MachineIndependent/glslang_tab.cpp" + break; + + case 424: /* type_specifier_nonarray: TEXTURE1DARRAY */ +#line 2935 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D, true); + } +#line 9629 "MachineIndependent/glslang_tab.cpp" + break; + + case 425: /* type_specifier_nonarray: F16TEXTURE1DARRAY */ +#line 2940 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D, true); + } +#line 9640 "MachineIndependent/glslang_tab.cpp" + break; + + case 426: /* type_specifier_nonarray: F16TEXTURE2DARRAY */ +#line 2946 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true); + } +#line 9651 "MachineIndependent/glslang_tab.cpp" + break; + + case 427: /* type_specifier_nonarray: F16TEXTURECUBEARRAY */ +#line 2952 "MachineIndependent/glslang.y" + { + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube, true); + } +#line 9662 "MachineIndependent/glslang_tab.cpp" + break; + + case 428: /* type_specifier_nonarray: ITEXTURE1D */ +#line 2958 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D); + } +#line 9672 "MachineIndependent/glslang_tab.cpp" + break; + + case 429: /* type_specifier_nonarray: ITEXTURE1DARRAY */ +#line 2963 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D, true); + } +#line 9682 "MachineIndependent/glslang_tab.cpp" + break; + + case 430: /* type_specifier_nonarray: UTEXTURE1D */ +#line 2968 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D); + } +#line 9692 "MachineIndependent/glslang_tab.cpp" + break; + + case 431: /* type_specifier_nonarray: UTEXTURE1DARRAY */ +#line 2973 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D, true); + } +#line 9702 "MachineIndependent/glslang_tab.cpp" + break; + + case 432: /* type_specifier_nonarray: TEXTURE2DRECT */ +#line 2978 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdRect); } -#line 8476 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9712 "MachineIndependent/glslang_tab.cpp" break; - case 410: -#line 2769 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 433: /* type_specifier_nonarray: F16TEXTURE2DRECT */ +#line 2983 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdRect); -#endif } -#line 8489 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9723 "MachineIndependent/glslang_tab.cpp" break; - case 411: -#line 2777 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 434: /* type_specifier_nonarray: ITEXTURE2DRECT */ +#line 2989 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdRect); } -#line 8499 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9733 "MachineIndependent/glslang_tab.cpp" break; - case 412: -#line 2782 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 435: /* type_specifier_nonarray: UTEXTURE2DRECT */ +#line 2994 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdRect); } -#line 8509 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9743 "MachineIndependent/glslang_tab.cpp" break; - case 413: -#line 2787 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 436: /* type_specifier_nonarray: TEXTUREBUFFER */ +#line 2999 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdBuffer); } -#line 8519 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9753 "MachineIndependent/glslang_tab.cpp" break; - case 414: -#line 2792 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 437: /* type_specifier_nonarray: F16TEXTUREBUFFER */ +#line 3004 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdBuffer); -#endif } -#line 8532 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9764 "MachineIndependent/glslang_tab.cpp" break; - case 415: -#line 2800 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 438: /* type_specifier_nonarray: ITEXTUREBUFFER */ +#line 3010 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdBuffer); } -#line 8542 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9774 "MachineIndependent/glslang_tab.cpp" break; - case 416: -#line 2805 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 439: /* type_specifier_nonarray: UTEXTUREBUFFER */ +#line 3015 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdBuffer); } -#line 8552 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9784 "MachineIndependent/glslang_tab.cpp" break; - case 417: -#line 2810 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 440: /* type_specifier_nonarray: TEXTURE2DMS */ +#line 3020 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, false, false, true); } -#line 8562 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9794 "MachineIndependent/glslang_tab.cpp" break; - case 418: -#line 2815 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 441: /* type_specifier_nonarray: F16TEXTURE2DMS */ +#line 3025 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, false, false, true); -#endif } -#line 8575 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9805 "MachineIndependent/glslang_tab.cpp" break; - case 419: -#line 2823 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 442: /* type_specifier_nonarray: ITEXTURE2DMS */ +#line 3031 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, false, false, true); } -#line 8585 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9815 "MachineIndependent/glslang_tab.cpp" break; - case 420: -#line 2828 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 443: /* type_specifier_nonarray: UTEXTURE2DMS */ +#line 3036 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, false, false, true); } -#line 8595 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9825 "MachineIndependent/glslang_tab.cpp" break; - case 421: -#line 2833 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 444: /* type_specifier_nonarray: TEXTURE2DMSARRAY */ +#line 3041 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true, false, true); } -#line 8605 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9835 "MachineIndependent/glslang_tab.cpp" break; - case 422: -#line 2838 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 445: /* type_specifier_nonarray: F16TEXTURE2DMSARRAY */ +#line 3046 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true, false, true); -#endif } -#line 8618 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9846 "MachineIndependent/glslang_tab.cpp" break; - case 423: -#line 2846 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 446: /* type_specifier_nonarray: ITEXTURE2DMSARRAY */ +#line 3052 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true, false, true); } -#line 8628 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9856 "MachineIndependent/glslang_tab.cpp" break; - case 424: -#line 2851 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 447: /* type_specifier_nonarray: UTEXTURE2DMSARRAY */ +#line 3057 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true, false, true); } -#line 8638 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9866 "MachineIndependent/glslang_tab.cpp" break; - case 425: -#line 2856 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 448: /* type_specifier_nonarray: IMAGE1D */ +#line 3062 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D); } -#line 8648 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9876 "MachineIndependent/glslang_tab.cpp" break; - case 426: -#line 2861 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 449: /* type_specifier_nonarray: F16IMAGE1D */ +#line 3067 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D); -#endif } -#line 8661 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9887 "MachineIndependent/glslang_tab.cpp" break; - case 427: -#line 2869 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 450: /* type_specifier_nonarray: IIMAGE1D */ +#line 3073 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D); } -#line 8671 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9897 "MachineIndependent/glslang_tab.cpp" break; - case 428: -#line 2874 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 451: /* type_specifier_nonarray: UIMAGE1D */ +#line 3078 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D); } -#line 8681 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9907 "MachineIndependent/glslang_tab.cpp" break; - case 429: -#line 2879 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 452: /* type_specifier_nonarray: IMAGE2D */ +#line 3083 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D); } -#line 8691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9917 "MachineIndependent/glslang_tab.cpp" break; - case 430: -#line 2884 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 453: /* type_specifier_nonarray: F16IMAGE2D */ +#line 3088 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D); -#endif } -#line 8704 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9928 "MachineIndependent/glslang_tab.cpp" break; - case 431: -#line 2892 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 454: /* type_specifier_nonarray: IIMAGE2D */ +#line 3094 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D); } -#line 8714 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9938 "MachineIndependent/glslang_tab.cpp" break; - case 432: -#line 2897 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 455: /* type_specifier_nonarray: UIMAGE2D */ +#line 3099 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D); } -#line 8724 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9948 "MachineIndependent/glslang_tab.cpp" break; - case 433: -#line 2902 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 456: /* type_specifier_nonarray: IMAGE3D */ +#line 3104 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd3D); } -#line 8734 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9958 "MachineIndependent/glslang_tab.cpp" break; - case 434: -#line 2907 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 457: /* type_specifier_nonarray: F16IMAGE3D */ +#line 3109 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd3D); -#endif } -#line 8747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9969 "MachineIndependent/glslang_tab.cpp" break; - case 435: -#line 2915 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 458: /* type_specifier_nonarray: IIMAGE3D */ +#line 3115 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd3D); } -#line 8757 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9979 "MachineIndependent/glslang_tab.cpp" break; - case 436: -#line 2920 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 459: /* type_specifier_nonarray: UIMAGE3D */ +#line 3120 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd3D); } -#line 8767 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9989 "MachineIndependent/glslang_tab.cpp" break; - case 437: -#line 2925 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 460: /* type_specifier_nonarray: IMAGE2DRECT */ +#line 3125 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdRect); } -#line 8777 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9999 "MachineIndependent/glslang_tab.cpp" break; - case 438: -#line 2930 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 461: /* type_specifier_nonarray: F16IMAGE2DRECT */ +#line 3130 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdRect); -#endif } -#line 8790 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10010 "MachineIndependent/glslang_tab.cpp" break; - case 439: -#line 2938 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 462: /* type_specifier_nonarray: IIMAGE2DRECT */ +#line 3136 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdRect); } -#line 8800 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10020 "MachineIndependent/glslang_tab.cpp" break; - case 440: -#line 2943 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 463: /* type_specifier_nonarray: UIMAGE2DRECT */ +#line 3141 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdRect); } -#line 8810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10030 "MachineIndependent/glslang_tab.cpp" break; - case 441: -#line 2948 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 464: /* type_specifier_nonarray: IMAGECUBE */ +#line 3146 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube); } -#line 8820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10040 "MachineIndependent/glslang_tab.cpp" break; - case 442: -#line 2953 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 465: /* type_specifier_nonarray: F16IMAGECUBE */ +#line 3151 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube); -#endif } -#line 8833 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10051 "MachineIndependent/glslang_tab.cpp" break; - case 443: -#line 2961 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 466: /* type_specifier_nonarray: IIMAGECUBE */ +#line 3157 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube); } -#line 8843 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10061 "MachineIndependent/glslang_tab.cpp" break; - case 444: -#line 2966 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 467: /* type_specifier_nonarray: UIMAGECUBE */ +#line 3162 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube); } -#line 8853 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10071 "MachineIndependent/glslang_tab.cpp" break; - case 445: -#line 2971 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 468: /* type_specifier_nonarray: IMAGEBUFFER */ +#line 3167 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdBuffer); } -#line 8863 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10081 "MachineIndependent/glslang_tab.cpp" break; - case 446: -#line 2976 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 469: /* type_specifier_nonarray: F16IMAGEBUFFER */ +#line 3172 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdBuffer); -#endif } -#line 8876 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10092 "MachineIndependent/glslang_tab.cpp" break; - case 447: -#line 2984 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 470: /* type_specifier_nonarray: IIMAGEBUFFER */ +#line 3178 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdBuffer); } -#line 8886 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10102 "MachineIndependent/glslang_tab.cpp" break; - case 448: -#line 2989 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 471: /* type_specifier_nonarray: UIMAGEBUFFER */ +#line 3183 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdBuffer); } -#line 8896 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10112 "MachineIndependent/glslang_tab.cpp" break; - case 449: -#line 2994 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 472: /* type_specifier_nonarray: IMAGE1DARRAY */ +#line 3188 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D, true); } -#line 8906 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10122 "MachineIndependent/glslang_tab.cpp" break; - case 450: -#line 2999 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 473: /* type_specifier_nonarray: F16IMAGE1DARRAY */ +#line 3193 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D, true); -#endif } -#line 8919 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10133 "MachineIndependent/glslang_tab.cpp" break; - case 451: -#line 3007 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 474: /* type_specifier_nonarray: IIMAGE1DARRAY */ +#line 3199 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D, true); } -#line 8929 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10143 "MachineIndependent/glslang_tab.cpp" break; - case 452: -#line 3012 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 475: /* type_specifier_nonarray: UIMAGE1DARRAY */ +#line 3204 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D, true); } -#line 8939 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10153 "MachineIndependent/glslang_tab.cpp" break; - case 453: -#line 3017 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 476: /* type_specifier_nonarray: IMAGE2DARRAY */ +#line 3209 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true); } -#line 8949 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10163 "MachineIndependent/glslang_tab.cpp" break; - case 454: -#line 3022 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 477: /* type_specifier_nonarray: F16IMAGE2DARRAY */ +#line 3214 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true); -#endif } -#line 8962 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10174 "MachineIndependent/glslang_tab.cpp" break; - case 455: -#line 3030 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 478: /* type_specifier_nonarray: IIMAGE2DARRAY */ +#line 3220 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true); } -#line 8972 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10184 "MachineIndependent/glslang_tab.cpp" break; - case 456: -#line 3035 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 479: /* type_specifier_nonarray: UIMAGE2DARRAY */ +#line 3225 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true); } -#line 8982 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10194 "MachineIndependent/glslang_tab.cpp" break; - case 457: -#line 3040 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 480: /* type_specifier_nonarray: IMAGECUBEARRAY */ +#line 3230 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube, true); } -#line 8992 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10204 "MachineIndependent/glslang_tab.cpp" break; - case 458: -#line 3045 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 481: /* type_specifier_nonarray: F16IMAGECUBEARRAY */ +#line 3235 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube, true); -#endif } -#line 9005 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10215 "MachineIndependent/glslang_tab.cpp" break; - case 459: -#line 3053 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 482: /* type_specifier_nonarray: IIMAGECUBEARRAY */ +#line 3241 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube, true); } -#line 9015 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10225 "MachineIndependent/glslang_tab.cpp" break; - case 460: -#line 3058 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 483: /* type_specifier_nonarray: UIMAGECUBEARRAY */ +#line 3246 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube, true); } -#line 9025 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10235 "MachineIndependent/glslang_tab.cpp" break; - case 461: -#line 3063 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 484: /* type_specifier_nonarray: IMAGE2DMS */ +#line 3251 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, false, false, true); } -#line 9035 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10245 "MachineIndependent/glslang_tab.cpp" break; - case 462: -#line 3068 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 485: /* type_specifier_nonarray: F16IMAGE2DMS */ +#line 3256 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, false, false, true); -#endif } -#line 9048 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10256 "MachineIndependent/glslang_tab.cpp" break; - case 463: -#line 3076 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 486: /* type_specifier_nonarray: IIMAGE2DMS */ +#line 3262 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, false, false, true); } -#line 9058 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10266 "MachineIndependent/glslang_tab.cpp" break; - case 464: -#line 3081 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 487: /* type_specifier_nonarray: UIMAGE2DMS */ +#line 3267 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, false, false, true); } -#line 9068 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10276 "MachineIndependent/glslang_tab.cpp" break; - case 465: -#line 3086 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 488: /* type_specifier_nonarray: IMAGE2DMSARRAY */ +#line 3272 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true, false, true); } -#line 9078 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10286 "MachineIndependent/glslang_tab.cpp" break; - case 466: -#line 3091 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 489: /* type_specifier_nonarray: F16IMAGE2DMSARRAY */ +#line 3277 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true, false, true); -#endif } -#line 9091 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10297 "MachineIndependent/glslang_tab.cpp" break; - case 467: -#line 3099 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 490: /* type_specifier_nonarray: IIMAGE2DMSARRAY */ +#line 3283 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true, false, true); } -#line 9101 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10307 "MachineIndependent/glslang_tab.cpp" break; - case 468: -#line 3104 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 491: /* type_specifier_nonarray: UIMAGE2DMSARRAY */ +#line 3288 "MachineIndependent/glslang.y" + { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true, false, true); } -#line 9111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10317 "MachineIndependent/glslang_tab.cpp" break; - case 469: -#line 3109 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { // GL_OES_EGL_image_external + case 492: /* type_specifier_nonarray: I64IMAGE1D */ +#line 3293 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, Esd1D); + } +#line 10327 "MachineIndependent/glslang_tab.cpp" + break; + + case 493: /* type_specifier_nonarray: U64IMAGE1D */ +#line 3298 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, Esd1D); + } +#line 10337 "MachineIndependent/glslang_tab.cpp" + break; + + case 494: /* type_specifier_nonarray: I64IMAGE2D */ +#line 3303 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D); + } +#line 10347 "MachineIndependent/glslang_tab.cpp" + break; + + case 495: /* type_specifier_nonarray: U64IMAGE2D */ +#line 3308 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D); + } +#line 10357 "MachineIndependent/glslang_tab.cpp" + break; + + case 496: /* type_specifier_nonarray: I64IMAGE3D */ +#line 3313 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, Esd3D); + } +#line 10367 "MachineIndependent/glslang_tab.cpp" + break; + + case 497: /* type_specifier_nonarray: U64IMAGE3D */ +#line 3318 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, Esd3D); + } +#line 10377 "MachineIndependent/glslang_tab.cpp" + break; + + case 498: /* type_specifier_nonarray: I64IMAGE2DRECT */ +#line 3323 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, EsdRect); + } +#line 10387 "MachineIndependent/glslang_tab.cpp" + break; + + case 499: /* type_specifier_nonarray: U64IMAGE2DRECT */ +#line 3328 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, EsdRect); + } +#line 10397 "MachineIndependent/glslang_tab.cpp" + break; + + case 500: /* type_specifier_nonarray: I64IMAGECUBE */ +#line 3333 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, EsdCube); + } +#line 10407 "MachineIndependent/glslang_tab.cpp" + break; + + case 501: /* type_specifier_nonarray: U64IMAGECUBE */ +#line 3338 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, EsdCube); + } +#line 10417 "MachineIndependent/glslang_tab.cpp" + break; + + case 502: /* type_specifier_nonarray: I64IMAGEBUFFER */ +#line 3343 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, EsdBuffer); + } +#line 10427 "MachineIndependent/glslang_tab.cpp" + break; + + case 503: /* type_specifier_nonarray: U64IMAGEBUFFER */ +#line 3348 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, EsdBuffer); + } +#line 10437 "MachineIndependent/glslang_tab.cpp" + break; + + case 504: /* type_specifier_nonarray: I64IMAGE1DARRAY */ +#line 3353 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, Esd1D, true); + } +#line 10447 "MachineIndependent/glslang_tab.cpp" + break; + + case 505: /* type_specifier_nonarray: U64IMAGE1DARRAY */ +#line 3358 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, Esd1D, true); + } +#line 10457 "MachineIndependent/glslang_tab.cpp" + break; + + case 506: /* type_specifier_nonarray: I64IMAGE2DARRAY */ +#line 3363 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D, true); + } +#line 10467 "MachineIndependent/glslang_tab.cpp" + break; + + case 507: /* type_specifier_nonarray: U64IMAGE2DARRAY */ +#line 3368 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D, true); + } +#line 10477 "MachineIndependent/glslang_tab.cpp" + break; + + case 508: /* type_specifier_nonarray: I64IMAGECUBEARRAY */ +#line 3373 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, EsdCube, true); + } +#line 10487 "MachineIndependent/glslang_tab.cpp" + break; + + case 509: /* type_specifier_nonarray: U64IMAGECUBEARRAY */ +#line 3378 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, EsdCube, true); + } +#line 10497 "MachineIndependent/glslang_tab.cpp" + break; + + case 510: /* type_specifier_nonarray: I64IMAGE2DMS */ +#line 3383 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D, false, false, true); + } +#line 10507 "MachineIndependent/glslang_tab.cpp" + break; + + case 511: /* type_specifier_nonarray: U64IMAGE2DMS */ +#line 3388 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D, false, false, true); + } +#line 10517 "MachineIndependent/glslang_tab.cpp" + break; + + case 512: /* type_specifier_nonarray: I64IMAGE2DMSARRAY */ +#line 3393 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D, true, false, true); + } +#line 10527 "MachineIndependent/glslang_tab.cpp" + break; + + case 513: /* type_specifier_nonarray: U64IMAGE2DMSARRAY */ +#line 3398 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D, true, false, true); + } +#line 10537 "MachineIndependent/glslang_tab.cpp" + break; + + case 514: /* type_specifier_nonarray: SAMPLEREXTERNALOES */ +#line 3403 "MachineIndependent/glslang.y" + { // GL_OES_EGL_image_external (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); (yyval.interm.type).sampler.external = true; } -#line 9122 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10548 "MachineIndependent/glslang_tab.cpp" break; - case 470: -#line 3115 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { // GL_EXT_YUV_target + case 515: /* type_specifier_nonarray: SAMPLEREXTERNAL2DY2YEXT */ +#line 3409 "MachineIndependent/glslang.y" + { // GL_EXT_YUV_target (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); (yyval.interm.type).sampler.yuv = true; } -#line 9133 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10559 "MachineIndependent/glslang_tab.cpp" break; - case 471: -#line 3121 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 516: /* type_specifier_nonarray: SUBPASSINPUT */ +#line 3415 "MachineIndependent/glslang.y" + { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat); } -#line 9144 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10570 "MachineIndependent/glslang_tab.cpp" break; - case 472: -#line 3127 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 517: /* type_specifier_nonarray: SUBPASSINPUTMS */ +#line 3421 "MachineIndependent/glslang.y" + { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat, true); } -#line 9155 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10581 "MachineIndependent/glslang_tab.cpp" break; - case 473: -#line 3133 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 518: /* type_specifier_nonarray: F16SUBPASSINPUT */ +#line 3427 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16); -#endif } -#line 9169 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10593 "MachineIndependent/glslang_tab.cpp" break; - case 474: -#line 3142 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { -#ifdef AMD_EXTENSIONS + case 519: /* type_specifier_nonarray: F16SUBPASSINPUTMS */ +#line 3434 "MachineIndependent/glslang.y" + { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16, true); -#endif } -#line 9183 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10605 "MachineIndependent/glslang_tab.cpp" break; - case 475: -#line 3151 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 520: /* type_specifier_nonarray: ISUBPASSINPUT */ +#line 3441 "MachineIndependent/glslang.y" + { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt); } -#line 9194 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10616 "MachineIndependent/glslang_tab.cpp" break; - case 476: -#line 3157 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 521: /* type_specifier_nonarray: ISUBPASSINPUTMS */ +#line 3447 "MachineIndependent/glslang.y" + { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt, true); } -#line 9205 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10627 "MachineIndependent/glslang_tab.cpp" break; - case 477: -#line 3163 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 522: /* type_specifier_nonarray: USUBPASSINPUT */ +#line 3453 "MachineIndependent/glslang.y" + { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint); } -#line 9216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10638 "MachineIndependent/glslang_tab.cpp" break; - case 478: -#line 3169 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 523: /* type_specifier_nonarray: USUBPASSINPUTMS */ +#line 3459 "MachineIndependent/glslang.y" + { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint, true); } -#line 9227 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10649 "MachineIndependent/glslang_tab.cpp" break; - case 479: -#line 3175 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 524: /* type_specifier_nonarray: FCOOPMATNV */ +#line 3465 "MachineIndependent/glslang.y" + { + parseContext.fcoopmatCheck((yyvsp[0].lex).loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).coopmat = true; + } +#line 10660 "MachineIndependent/glslang_tab.cpp" + break; + + case 525: /* type_specifier_nonarray: ICOOPMATNV */ +#line 3471 "MachineIndependent/glslang.y" + { + parseContext.intcoopmatCheck((yyvsp[0].lex).loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).coopmat = true; + } +#line 10671 "MachineIndependent/glslang_tab.cpp" + break; + + case 526: /* type_specifier_nonarray: UCOOPMATNV */ +#line 3477 "MachineIndependent/glslang.y" + { + parseContext.intcoopmatCheck((yyvsp[0].lex).loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).coopmat = true; + } +#line 10682 "MachineIndependent/glslang_tab.cpp" + break; + + case 527: /* type_specifier_nonarray: spirv_type_specifier */ +#line 3483 "MachineIndependent/glslang.y" + { + parseContext.requireExtensions((yyvsp[0].interm.type).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier"); + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 10691 "MachineIndependent/glslang_tab.cpp" + break; + + case 528: /* type_specifier_nonarray: struct_specifier */ +#line 3488 "MachineIndependent/glslang.y" + { (yyval.interm.type) = (yyvsp[0].interm.type); (yyval.interm.type).qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; parseContext.structTypeCheck((yyval.interm.type).loc, (yyval.interm.type)); } -#line 9237 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10701 "MachineIndependent/glslang_tab.cpp" break; - case 480: -#line 3180 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 529: /* type_specifier_nonarray: TYPE_NAME */ +#line 3493 "MachineIndependent/glslang.y" + { // // This is for user defined type names. The lexical phase looked up the // type. @@ -9251,48 +10715,48 @@ yyreduce: } else parseContext.error((yyvsp[0].lex).loc, "expected type name", (yyvsp[0].lex).string->c_str(), ""); } -#line 9255 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10719 "MachineIndependent/glslang_tab.cpp" break; - case 481: -#line 3196 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 530: /* precision_qualifier: HIGH_PRECISION */ +#line 3509 "MachineIndependent/glslang.y" + { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "highp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqHigh); } -#line 9265 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10729 "MachineIndependent/glslang_tab.cpp" break; - case 482: -#line 3201 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 531: /* precision_qualifier: MEDIUM_PRECISION */ +#line 3514 "MachineIndependent/glslang.y" + { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "mediump precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqMedium); } -#line 9275 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10739 "MachineIndependent/glslang_tab.cpp" break; - case 483: -#line 3206 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 532: /* precision_qualifier: LOW_PRECISION */ +#line 3519 "MachineIndependent/glslang.y" + { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "lowp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqLow); } -#line 9285 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10749 "MachineIndependent/glslang_tab.cpp" break; - case 484: -#line 3214 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { parseContext.nestedStructCheck((yyvsp[-2].lex).loc); } -#line 9291 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 533: /* $@3: %empty */ +#line 3527 "MachineIndependent/glslang.y" + { parseContext.nestedStructCheck((yyvsp[-2].lex).loc); } +#line 10755 "MachineIndependent/glslang_tab.cpp" break; - case 485: -#line 3214 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 534: /* struct_specifier: STRUCT IDENTIFIER LEFT_BRACE $@3 struct_declaration_list RIGHT_BRACE */ +#line 3527 "MachineIndependent/glslang.y" + { TType* structure = new TType((yyvsp[-1].interm.typeList), *(yyvsp[-4].lex).string); parseContext.structArrayCheck((yyvsp[-4].lex).loc, *structure); TVariable* userTypeDef = new TVariable((yyvsp[-4].lex).string, *structure, true); @@ -9303,38 +10767,38 @@ yyreduce: (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 9307 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10771 "MachineIndependent/glslang_tab.cpp" break; - case 486: -#line 3225 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { parseContext.nestedStructCheck((yyvsp[-1].lex).loc); } -#line 9313 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 535: /* $@4: %empty */ +#line 3538 "MachineIndependent/glslang.y" + { parseContext.nestedStructCheck((yyvsp[-1].lex).loc); } +#line 10777 "MachineIndependent/glslang_tab.cpp" break; - case 487: -#line 3225 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 536: /* struct_specifier: STRUCT LEFT_BRACE $@4 struct_declaration_list RIGHT_BRACE */ +#line 3538 "MachineIndependent/glslang.y" + { TType* structure = new TType((yyvsp[-1].interm.typeList), TString("")); (yyval.interm.type).init((yyvsp[-4].lex).loc); (yyval.interm.type).basicType = EbtStruct; (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 9325 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10789 "MachineIndependent/glslang_tab.cpp" break; - case 488: -#line 3235 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 537: /* struct_declaration_list: struct_declaration */ +#line 3548 "MachineIndependent/glslang.y" + { (yyval.interm.typeList) = (yyvsp[0].interm.typeList); } -#line 9333 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10797 "MachineIndependent/glslang_tab.cpp" break; - case 489: -#line 3238 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 538: /* struct_declaration_list: struct_declaration_list struct_declaration */ +#line 3551 "MachineIndependent/glslang.y" + { (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); for (unsigned int i = 0; i < (yyvsp[0].interm.typeList)->size(); ++i) { for (unsigned int j = 0; j < (yyval.interm.typeList)->size(); ++j) { @@ -9344,16 +10808,16 @@ yyreduce: (yyval.interm.typeList)->push_back((*(yyvsp[0].interm.typeList))[i]); } } -#line 9348 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10812 "MachineIndependent/glslang_tab.cpp" break; - case 490: -#line 3251 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 539: /* struct_declaration: type_specifier struct_declarator_list SEMICOLON */ +#line 3564 "MachineIndependent/glslang.y" + { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); } @@ -9371,16 +10835,16 @@ yyreduce: (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 9375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10839 "MachineIndependent/glslang_tab.cpp" break; - case 491: -#line 3273 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 540: /* struct_declaration: type_qualifier type_specifier struct_declarator_list SEMICOLON */ +#line 3586 "MachineIndependent/glslang.y" + { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); } @@ -9400,39 +10864,39 @@ yyreduce: (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 9404 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10868 "MachineIndependent/glslang_tab.cpp" break; - case 492: -#line 3300 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 541: /* struct_declarator_list: struct_declarator */ +#line 3613 "MachineIndependent/glslang.y" + { (yyval.interm.typeList) = new TTypeList; (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 9413 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10877 "MachineIndependent/glslang_tab.cpp" break; - case 493: -#line 3304 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 542: /* struct_declarator_list: struct_declarator_list COMMA struct_declarator */ +#line 3617 "MachineIndependent/glslang.y" + { (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 9421 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10885 "MachineIndependent/glslang_tab.cpp" break; - case 494: -#line 3310 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 543: /* struct_declarator: IDENTIFIER */ +#line 3623 "MachineIndependent/glslang.y" + { (yyval.interm.typeLine).type = new TType(EbtVoid); (yyval.interm.typeLine).loc = (yyvsp[0].lex).loc; (yyval.interm.typeLine).type->setFieldName(*(yyvsp[0].lex).string); } -#line 9431 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10895 "MachineIndependent/glslang_tab.cpp" break; - case 495: -#line 3315 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 544: /* struct_declarator: IDENTIFIER array_specifier */ +#line 3628 "MachineIndependent/glslang.y" + { parseContext.arrayOfArrayVersionCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes); (yyval.interm.typeLine).type = new TType(EbtVoid); @@ -9440,220 +10904,247 @@ yyreduce: (yyval.interm.typeLine).type->setFieldName(*(yyvsp[-1].lex).string); (yyval.interm.typeLine).type->transferArraySizes((yyvsp[0].interm).arraySizes); } -#line 9444 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10908 "MachineIndependent/glslang_tab.cpp" break; - case 496: -#line 3326 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 545: /* initializer: assignment_expression */ +#line 3639 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 9452 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10916 "MachineIndependent/glslang_tab.cpp" break; - case 497: -#line 3329 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 546: /* initializer: LEFT_BRACE initializer_list RIGHT_BRACE */ +#line 3643 "MachineIndependent/glslang.y" + { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-2].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-2].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); } -#line 9463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10927 "MachineIndependent/glslang_tab.cpp" break; - case 498: -#line 3335 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 547: /* initializer: LEFT_BRACE initializer_list COMMA RIGHT_BRACE */ +#line 3649 "MachineIndependent/glslang.y" + { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-3].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-3].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 9474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10938 "MachineIndependent/glslang_tab.cpp" break; - case 499: -#line 3344 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 548: /* initializer: LEFT_BRACE RIGHT_BRACE */ +#line 3655 "MachineIndependent/glslang.y" + { + const char* initFeature = "empty { } initializer"; + parseContext.profileRequires((yyvsp[-1].lex).loc, EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); + parseContext.profileRequires((yyvsp[-1].lex).loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); + (yyval.interm.intermTypedNode) = parseContext.intermediate.makeAggregate((yyvsp[-1].lex).loc); + } +#line 10949 "MachineIndependent/glslang_tab.cpp" + break; + + case 549: /* initializer_list: initializer */ +#line 3666 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate(0, (yyvsp[0].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)->getLoc()); } -#line 9482 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10957 "MachineIndependent/glslang_tab.cpp" break; - case 500: -#line 3347 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 550: /* initializer_list: initializer_list COMMA initializer */ +#line 3669 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); } -#line 9490 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10965 "MachineIndependent/glslang_tab.cpp" break; - case 501: -#line 3353 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9496 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 551: /* declaration_statement: declaration */ +#line 3676 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 10971 "MachineIndependent/glslang_tab.cpp" break; - case 502: -#line 3357 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9502 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 552: /* statement: compound_statement */ +#line 3680 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 10977 "MachineIndependent/glslang_tab.cpp" break; - case 503: -#line 3358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9508 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 553: /* statement: simple_statement */ +#line 3681 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 10983 "MachineIndependent/glslang_tab.cpp" break; - case 504: -#line 3364 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9514 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 554: /* simple_statement: declaration_statement */ +#line 3687 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 10989 "MachineIndependent/glslang_tab.cpp" break; - case 505: -#line 3365 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 555: /* simple_statement: expression_statement */ +#line 3688 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 10995 "MachineIndependent/glslang_tab.cpp" break; - case 506: -#line 3366 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9526 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 556: /* simple_statement: selection_statement */ +#line 3689 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 11001 "MachineIndependent/glslang_tab.cpp" break; - case 507: -#line 3367 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9532 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 557: /* simple_statement: switch_statement */ +#line 3690 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 11007 "MachineIndependent/glslang_tab.cpp" break; - case 508: -#line 3368 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9538 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 558: /* simple_statement: case_label */ +#line 3691 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 11013 "MachineIndependent/glslang_tab.cpp" break; - case 509: -#line 3369 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9544 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 559: /* simple_statement: iteration_statement */ +#line 3692 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 11019 "MachineIndependent/glslang_tab.cpp" break; - case 510: -#line 3370 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9550 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 560: /* simple_statement: jump_statement */ +#line 3693 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 11025 "MachineIndependent/glslang_tab.cpp" break; - case 511: -#line 3374 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = 0; } -#line 9556 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 561: /* simple_statement: demote_statement */ +#line 3695 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 11031 "MachineIndependent/glslang_tab.cpp" break; - case 512: -#line 3375 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 562: /* demote_statement: DEMOTE SEMICOLON */ +#line 3701 "MachineIndependent/glslang.y" + { + parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "demote"); + parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote"); + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDemote, (yyvsp[-1].lex).loc); + } +#line 11041 "MachineIndependent/glslang_tab.cpp" + break; + + case 563: /* compound_statement: LEFT_BRACE RIGHT_BRACE */ +#line 3710 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = 0; } +#line 11047 "MachineIndependent/glslang_tab.cpp" + break; + + case 564: /* $@5: %empty */ +#line 3711 "MachineIndependent/glslang.y" + { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; } -#line 9565 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11056 "MachineIndependent/glslang_tab.cpp" break; - case 513: -#line 3379 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 565: /* $@6: %empty */ +#line 3715 "MachineIndependent/glslang.y" + { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; } -#line 9574 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11065 "MachineIndependent/glslang_tab.cpp" break; - case 514: -#line 3383 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 566: /* compound_statement: LEFT_BRACE $@5 statement_list $@6 RIGHT_BRACE */ +#line 3719 "MachineIndependent/glslang.y" + { if ((yyvsp[-2].interm.intermNode) && (yyvsp[-2].interm.intermNode)->getAsAggregate()) (yyvsp[-2].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-2].interm.intermNode); } -#line 9584 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11075 "MachineIndependent/glslang_tab.cpp" break; - case 515: -#line 3391 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9590 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 567: /* statement_no_new_scope: compound_statement_no_new_scope */ +#line 3727 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 11081 "MachineIndependent/glslang_tab.cpp" break; - case 516: -#line 3392 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9596 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 568: /* statement_no_new_scope: simple_statement */ +#line 3728 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 11087 "MachineIndependent/glslang_tab.cpp" break; - case 517: -#line 3396 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 569: /* $@7: %empty */ +#line 3732 "MachineIndependent/glslang.y" + { ++parseContext.controlFlowNestingLevel; } -#line 9604 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11095 "MachineIndependent/glslang_tab.cpp" break; - case 518: -#line 3399 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 570: /* statement_scoped: $@7 compound_statement */ +#line 3735 "MachineIndependent/glslang.y" + { --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9613 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11104 "MachineIndependent/glslang_tab.cpp" break; - case 519: -#line 3403 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 571: /* $@8: %empty */ +#line 3739 "MachineIndependent/glslang.y" + { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9623 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11114 "MachineIndependent/glslang_tab.cpp" break; - case 520: -#line 3408 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 572: /* statement_scoped: $@8 simple_statement */ +#line 3744 "MachineIndependent/glslang.y" + { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9634 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11125 "MachineIndependent/glslang_tab.cpp" break; - case 521: -#line 3417 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 573: /* compound_statement_no_new_scope: LEFT_BRACE RIGHT_BRACE */ +#line 3753 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = 0; } -#line 9642 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11133 "MachineIndependent/glslang_tab.cpp" break; - case 522: -#line 3420 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 574: /* compound_statement_no_new_scope: LEFT_BRACE statement_list RIGHT_BRACE */ +#line 3756 "MachineIndependent/glslang.y" + { if ((yyvsp[-1].interm.intermNode) && (yyvsp[-1].interm.intermNode)->getAsAggregate()) (yyvsp[-1].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-1].interm.intermNode); } -#line 9652 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11143 "MachineIndependent/glslang_tab.cpp" break; - case 523: -#line 3428 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 575: /* statement_list: statement */ +#line 3764 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || (yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpDefault)) { @@ -9661,12 +11152,12 @@ yyreduce: (yyval.interm.intermNode) = 0; // start a fresh subsequence for what's after this case } } -#line 9665 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11156 "MachineIndependent/glslang_tab.cpp" break; - case 524: -#line 3436 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 576: /* statement_list: statement_list statement */ +#line 3772 "MachineIndependent/glslang.y" + { if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || (yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpDefault)) { parseContext.wrapupSwitchSubsequence((yyvsp[-1].interm.intermNode) ? (yyvsp[-1].interm.intermNode)->getAsAggregate() : 0, (yyvsp[0].interm.intermNode)); @@ -9674,77 +11165,78 @@ yyreduce: } else (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 9678 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11169 "MachineIndependent/glslang_tab.cpp" break; - case 525: -#line 3447 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = 0; } -#line 9684 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 577: /* expression_statement: SEMICOLON */ +#line 3783 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = 0; } +#line 11175 "MachineIndependent/glslang_tab.cpp" break; - case 526: -#line 3448 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } -#line 9690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 578: /* expression_statement: expression SEMICOLON */ +#line 3784 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } +#line 11181 "MachineIndependent/glslang_tab.cpp" break; - case 527: -#line 3452 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 579: /* selection_statement: selection_statement_nonattributed */ +#line 3788 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9698 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11189 "MachineIndependent/glslang_tab.cpp" break; - case 528: -#line 3455 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 580: /* selection_statement: attribute selection_statement_nonattributed */ +#line 3792 "MachineIndependent/glslang.y" + { + parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleSelectionAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9707 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11199 "MachineIndependent/glslang_tab.cpp" break; - case 529: -#line 3461 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 581: /* selection_statement_nonattributed: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement */ +#line 3800 "MachineIndependent/glslang.y" + { parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-2].interm.intermTypedNode)); (yyval.interm.intermNode) = parseContext.intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yyvsp[-4].lex).loc); } -#line 9716 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11208 "MachineIndependent/glslang_tab.cpp" break; - case 530: -#line 3468 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 582: /* selection_rest_statement: statement_scoped ELSE statement_scoped */ +#line 3807 "MachineIndependent/glslang.y" + { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode); } -#line 9725 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11217 "MachineIndependent/glslang_tab.cpp" break; - case 531: -#line 3472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 583: /* selection_rest_statement: statement_scoped */ +#line 3811 "MachineIndependent/glslang.y" + { (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); (yyval.interm.nodePair).node2 = 0; } -#line 9734 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11226 "MachineIndependent/glslang_tab.cpp" break; - case 532: -#line 3480 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 584: /* condition: expression */ +#line 3819 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); parseContext.boolCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)); } -#line 9743 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11235 "MachineIndependent/glslang_tab.cpp" break; - case 533: -#line 3484 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 585: /* condition: fully_specified_type IDENTIFIER EQUAL initializer */ +#line 3823 "MachineIndependent/glslang.y" + { parseContext.boolCheck((yyvsp[-2].lex).loc, (yyvsp[-3].interm.type)); TType type((yyvsp[-3].interm.type)); @@ -9754,29 +11246,30 @@ yyreduce: else (yyval.interm.intermTypedNode) = 0; } -#line 9758 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11250 "MachineIndependent/glslang_tab.cpp" break; - case 534: -#line 3497 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 586: /* switch_statement: switch_statement_nonattributed */ +#line 3836 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9766 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11258 "MachineIndependent/glslang_tab.cpp" break; - case 535: -#line 3500 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 587: /* switch_statement: attribute switch_statement_nonattributed */ +#line 3840 "MachineIndependent/glslang.y" + { + parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleSwitchAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9775 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11268 "MachineIndependent/glslang_tab.cpp" break; - case 536: -#line 3506 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 588: /* $@9: %empty */ +#line 3848 "MachineIndependent/glslang.y" + { // start new switch sequence on the switch stack ++parseContext.controlFlowNestingLevel; ++parseContext.statementNestingLevel; @@ -9784,12 +11277,12 @@ yyreduce: parseContext.switchLevel.push_back(parseContext.statementNestingLevel); parseContext.symbolTable.push(); } -#line 9788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11281 "MachineIndependent/glslang_tab.cpp" break; - case 537: -#line 3514 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 589: /* switch_statement_nonattributed: SWITCH LEFT_PAREN expression RIGHT_PAREN $@9 LEFT_BRACE switch_statement_list RIGHT_BRACE */ +#line 3856 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = parseContext.addSwitch((yyvsp[-7].lex).loc, (yyvsp[-5].interm.intermTypedNode), (yyvsp[-1].interm.intermNode) ? (yyvsp[-1].interm.intermNode)->getAsAggregate() : 0); delete parseContext.switchSequenceStack.back(); parseContext.switchSequenceStack.pop_back(); @@ -9798,28 +11291,28 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9802 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11295 "MachineIndependent/glslang_tab.cpp" break; - case 538: -#line 3526 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 590: /* switch_statement_list: %empty */ +#line 3868 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = 0; } -#line 9810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11303 "MachineIndependent/glslang_tab.cpp" break; - case 539: -#line 3529 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 591: /* switch_statement_list: statement_list */ +#line 3871 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9818 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11311 "MachineIndependent/glslang_tab.cpp" break; - case 540: -#line 3535 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 592: /* case_label: CASE expression COLON */ +#line 3877 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) parseContext.error((yyvsp[-2].lex).loc, "cannot appear outside switch statement", "case", ""); @@ -9831,12 +11324,12 @@ yyreduce: (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpCase, (yyvsp[-1].interm.intermTypedNode), (yyvsp[-2].lex).loc); } } -#line 9835 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11328 "MachineIndependent/glslang_tab.cpp" break; - case 541: -#line 3547 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 593: /* case_label: DEFAULT COLON */ +#line 3889 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) parseContext.error((yyvsp[-1].lex).loc, "cannot appear outside switch statement", "default", ""); @@ -9845,29 +11338,30 @@ yyreduce: else (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDefault, (yyvsp[-1].lex).loc); } -#line 9849 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11342 "MachineIndependent/glslang_tab.cpp" break; - case 542: -#line 3559 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 594: /* iteration_statement: iteration_statement_nonattributed */ +#line 3901 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9857 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11350 "MachineIndependent/glslang_tab.cpp" break; - case 543: -#line 3562 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 595: /* iteration_statement: attribute iteration_statement_nonattributed */ +#line 3905 "MachineIndependent/glslang.y" + { + parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleLoopAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9866 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11360 "MachineIndependent/glslang_tab.cpp" break; - case 544: -#line 3568 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 596: /* $@10: %empty */ +#line 3913 "MachineIndependent/glslang.y" + { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-1].lex).loc, "while loops not available", "limitation", ""); parseContext.symbolTable.push(); @@ -9875,34 +11369,34 @@ yyreduce: ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9879 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11373 "MachineIndependent/glslang_tab.cpp" break; - case 545: -#line 3576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 597: /* iteration_statement_nonattributed: WHILE LEFT_PAREN $@10 condition RIGHT_PAREN statement_no_new_scope */ +#line 3921 "MachineIndependent/glslang.y" + { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.addLoop((yyvsp[0].interm.intermNode), (yyvsp[-2].interm.intermTypedNode), 0, true, (yyvsp[-5].lex).loc); --parseContext.loopNestingLevel; --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11385 "MachineIndependent/glslang_tab.cpp" break; - case 546: -#line 3583 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 598: /* $@11: %empty */ +#line 3928 "MachineIndependent/glslang.y" + { ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9901 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11395 "MachineIndependent/glslang_tab.cpp" break; - case 547: -#line 3588 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 599: /* iteration_statement_nonattributed: DO $@11 statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON */ +#line 3933 "MachineIndependent/glslang.y" + { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", ""); @@ -9913,23 +11407,23 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9917 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11411 "MachineIndependent/glslang_tab.cpp" break; - case 548: -#line 3599 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 600: /* $@12: %empty */ +#line 3944 "MachineIndependent/glslang.y" + { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9928 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11422 "MachineIndependent/glslang_tab.cpp" break; - case 549: -#line 3605 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 601: /* iteration_statement_nonattributed: FOR LEFT_PAREN $@12 for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope */ +#line 3950 "MachineIndependent/glslang.y" + { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[-3].interm.intermNode), (yyvsp[-5].lex).loc); TIntermLoop* forLoop = parseContext.intermediate.addLoop((yyvsp[0].interm.intermNode), reinterpret_cast((yyvsp[-2].interm.nodePair).node1), reinterpret_cast((yyvsp[-2].interm.nodePair).node2), true, (yyvsp[-6].lex).loc); @@ -9941,166 +11435,201 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9945 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11439 "MachineIndependent/glslang_tab.cpp" break; - case 550: -#line 3620 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 602: /* for_init_statement: expression_statement */ +#line 3965 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9953 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11447 "MachineIndependent/glslang_tab.cpp" break; - case 551: -#line 3623 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 603: /* for_init_statement: declaration_statement */ +#line 3968 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9961 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11455 "MachineIndependent/glslang_tab.cpp" break; - case 552: -#line 3629 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 604: /* conditionopt: condition */ +#line 3974 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 9969 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11463 "MachineIndependent/glslang_tab.cpp" break; - case 553: -#line 3632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 605: /* conditionopt: %empty */ +#line 3977 "MachineIndependent/glslang.y" + { (yyval.interm.intermTypedNode) = 0; } -#line 9977 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11471 "MachineIndependent/glslang_tab.cpp" break; - case 554: -#line 3638 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 606: /* for_rest_statement: conditionopt SEMICOLON */ +#line 3983 "MachineIndependent/glslang.y" + { (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); (yyval.interm.nodePair).node2 = 0; } -#line 9986 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11480 "MachineIndependent/glslang_tab.cpp" break; - case 555: -#line 3642 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 607: /* for_rest_statement: conditionopt SEMICOLON expression */ +#line 3987 "MachineIndependent/glslang.y" + { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode); } -#line 9995 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11489 "MachineIndependent/glslang_tab.cpp" break; - case 556: -#line 3649 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 608: /* jump_statement: CONTINUE SEMICOLON */ +#line 3994 "MachineIndependent/glslang.y" + { if (parseContext.loopNestingLevel <= 0) parseContext.error((yyvsp[-1].lex).loc, "continue statement only allowed in loops", "", ""); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpContinue, (yyvsp[-1].lex).loc); } -#line 10005 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11499 "MachineIndependent/glslang_tab.cpp" break; - case 557: -#line 3654 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 609: /* jump_statement: BREAK SEMICOLON */ +#line 3999 "MachineIndependent/glslang.y" + { if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) parseContext.error((yyvsp[-1].lex).loc, "break statement only allowed in switch and loops", "", ""); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpBreak, (yyvsp[-1].lex).loc); } -#line 10015 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11509 "MachineIndependent/glslang_tab.cpp" break; - case 558: -#line 3659 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 610: /* jump_statement: RETURN SEMICOLON */ +#line 4004 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc); if (parseContext.currentFunctionType->getBasicType() != EbtVoid) parseContext.error((yyvsp[-1].lex).loc, "non-void function must return a value", "return", ""); if (parseContext.inMain) parseContext.postEntryPointReturn = true; } -#line 10027 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11521 "MachineIndependent/glslang_tab.cpp" break; - case 559: -#line 3666 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 611: /* jump_statement: RETURN expression SEMICOLON */ +#line 4011 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode)); } -#line 10035 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11529 "MachineIndependent/glslang_tab.cpp" break; - case 560: -#line 3669 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 612: /* jump_statement: DISCARD SEMICOLON */ +#line 4014 "MachineIndependent/glslang.y" + { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "discard"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpKill, (yyvsp[-1].lex).loc); } -#line 10044 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11538 "MachineIndependent/glslang_tab.cpp" break; - case 561: -#line 3678 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 613: /* jump_statement: TERMINATE_INVOCATION SEMICOLON */ +#line 4018 "MachineIndependent/glslang.y" + { + parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "terminateInvocation"); + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpTerminateInvocation, (yyvsp[-1].lex).loc); + } +#line 11547 "MachineIndependent/glslang_tab.cpp" + break; + + case 614: /* jump_statement: TERMINATE_RAY SEMICOLON */ +#line 4023 "MachineIndependent/glslang.y" + { + parseContext.requireStage((yyvsp[-1].lex).loc, EShLangAnyHit, "terminateRayEXT"); + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpTerminateRayKHR, (yyvsp[-1].lex).loc); + } +#line 11556 "MachineIndependent/glslang_tab.cpp" + break; + + case 615: /* jump_statement: IGNORE_INTERSECTION SEMICOLON */ +#line 4027 "MachineIndependent/glslang.y" + { + parseContext.requireStage((yyvsp[-1].lex).loc, EShLangAnyHit, "ignoreIntersectionEXT"); + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpIgnoreIntersectionKHR, (yyvsp[-1].lex).loc); + } +#line 11565 "MachineIndependent/glslang_tab.cpp" + break; + + case 616: /* translation_unit: external_declaration */ +#line 4037 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } -#line 10053 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11574 "MachineIndependent/glslang_tab.cpp" break; - case 562: -#line 3682 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 617: /* translation_unit: translation_unit external_declaration */ +#line 4041 "MachineIndependent/glslang.y" + { if ((yyvsp[0].interm.intermNode) != nullptr) { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } } -#line 10064 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11585 "MachineIndependent/glslang_tab.cpp" break; - case 563: -#line 3691 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 618: /* external_declaration: function_definition */ +#line 4050 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10072 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11593 "MachineIndependent/glslang_tab.cpp" break; - case 564: -#line 3694 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 619: /* external_declaration: declaration */ +#line 4053 "MachineIndependent/glslang.y" + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10080 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11601 "MachineIndependent/glslang_tab.cpp" break; - case 565: -#line 3697 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 620: /* external_declaration: SEMICOLON */ +#line 4057 "MachineIndependent/glslang.y" + { parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "extraneous semicolon"); parseContext.profileRequires((yyvsp[0].lex).loc, ~EEsProfile, 460, nullptr, "extraneous semicolon"); (yyval.interm.intermNode) = nullptr; } -#line 10090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11611 "MachineIndependent/glslang_tab.cpp" break; - case 566: -#line 3705 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 621: /* $@13: %empty */ +#line 4066 "MachineIndependent/glslang.y" + { (yyvsp[0].interm).function = parseContext.handleFunctionDeclarator((yyvsp[0].interm).loc, *(yyvsp[0].interm).function, false /* not prototype */); (yyvsp[0].interm).intermNode = parseContext.handleFunctionDefinition((yyvsp[0].interm).loc, *(yyvsp[0].interm).function); + + // For ES 100 only, according to ES shading language 100 spec: A function + // body has a scope nested inside the function's definition. + if (parseContext.profile == EEsProfile && parseContext.version == 100) + { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + } } -#line 10099 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11628 "MachineIndependent/glslang_tab.cpp" break; - case 567: -#line 3709 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 622: /* function_definition: function_prototype $@13 compound_statement_no_new_scope */ +#line 4078 "MachineIndependent/glslang.y" + { // May be best done as post process phase on intermediate code if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) parseContext.error((yyvsp[-2].interm).loc, "function does not return a value:", "", (yyvsp[-2].interm).function->getName().c_str()); @@ -10114,53 +11643,576 @@ yyreduce: (yyval.interm.intermNode)->getAsAggregate()->setOptimize(parseContext.contextPragma.optimize); (yyval.interm.intermNode)->getAsAggregate()->setDebug(parseContext.contextPragma.debug); (yyval.interm.intermNode)->getAsAggregate()->setPragmaTable(parseContext.contextPragma.pragmaTable); + + // Set currentFunctionType to empty pointer when goes outside of the function + parseContext.currentFunctionType = nullptr; + + // For ES 100 only, according to ES shading language 100 spec: A function + // body has a scope nested inside the function's definition. + if (parseContext.profile == EEsProfile && parseContext.version == 100) + { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + } } -#line 10119 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11659 "MachineIndependent/glslang_tab.cpp" break; - case 568: -#line 3727 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 623: /* attribute: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET */ +#line 4108 "MachineIndependent/glslang.y" + { (yyval.interm.attributes) = (yyvsp[-2].interm.attributes); - parseContext.requireExtensions((yyvsp[-4].lex).loc, 1, &E_GL_EXT_control_flow_attributes, "attribute"); } -#line 10128 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11667 "MachineIndependent/glslang_tab.cpp" break; - case 569: -#line 3733 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 624: /* attribute_list: single_attribute */ +#line 4113 "MachineIndependent/glslang.y" + { (yyval.interm.attributes) = (yyvsp[0].interm.attributes); } -#line 10136 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11675 "MachineIndependent/glslang_tab.cpp" break; - case 570: -#line 3736 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 625: /* attribute_list: attribute_list COMMA single_attribute */ +#line 4116 "MachineIndependent/glslang.y" + { (yyval.interm.attributes) = parseContext.mergeAttributes((yyvsp[-2].interm.attributes), (yyvsp[0].interm.attributes)); } -#line 10144 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11683 "MachineIndependent/glslang_tab.cpp" break; - case 571: -#line 3741 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 626: /* single_attribute: IDENTIFIER */ +#line 4121 "MachineIndependent/glslang.y" + { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[0].lex).string); } -#line 10152 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11691 "MachineIndependent/glslang_tab.cpp" break; - case 572: -#line 3744 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { + case 627: /* single_attribute: IDENTIFIER LEFT_PAREN constant_expression RIGHT_PAREN */ +#line 4124 "MachineIndependent/glslang.y" + { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[-3].lex).string, (yyvsp[-1].interm.intermTypedNode)); } -#line 10160 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 11699 "MachineIndependent/glslang_tab.cpp" + break; + + case 628: /* spirv_requirements_list: spirv_requirements_parameter */ +#line 4131 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvReq) = (yyvsp[0].interm.spirvReq); + } +#line 11707 "MachineIndependent/glslang_tab.cpp" + break; + + case 629: /* spirv_requirements_list: spirv_requirements_list COMMA spirv_requirements_parameter */ +#line 4134 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvReq) = parseContext.mergeSpirvRequirements((yyvsp[-1].lex).loc, (yyvsp[-2].interm.spirvReq), (yyvsp[0].interm.spirvReq)); + } +#line 11715 "MachineIndependent/glslang_tab.cpp" + break; + + case 630: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET */ +#line 4139 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvReq) = parseContext.makeSpirvRequirement((yyvsp[-3].lex).loc, *(yyvsp[-4].lex).string, (yyvsp[-1].interm.intermNode)->getAsAggregate(), nullptr); + } +#line 11723 "MachineIndependent/glslang_tab.cpp" + break; + + case 631: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET */ +#line 4142 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvReq) = parseContext.makeSpirvRequirement((yyvsp[-3].lex).loc, *(yyvsp[-4].lex).string, nullptr, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + } +#line 11731 "MachineIndependent/glslang_tab.cpp" + break; + + case 632: /* spirv_extension_list: STRING_LITERAL */ +#line 4147 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); + } +#line 11739 "MachineIndependent/glslang_tab.cpp" + break; + + case 633: /* spirv_extension_list: spirv_extension_list COMMA STRING_LITERAL */ +#line 4150 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); + } +#line 11747 "MachineIndependent/glslang_tab.cpp" + break; + + case 634: /* spirv_capability_list: INTCONSTANT */ +#line 4155 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true)); + } +#line 11755 "MachineIndependent/glslang_tab.cpp" + break; + + case 635: /* spirv_capability_list: spirv_capability_list COMMA INTCONSTANT */ +#line 4158 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true)); + } +#line 11763 "MachineIndependent/glslang_tab.cpp" + break; + + case 636: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN */ +#line 4163 "MachineIndependent/glslang.y" + { + parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-1].lex).i); + (yyval.interm.intermNode) = 0; + } +#line 11772 "MachineIndependent/glslang_tab.cpp" + break; + + case 637: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ +#line 4167 "MachineIndependent/glslang.y" + { + parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); + parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-1].lex).i); + (yyval.interm.intermNode) = 0; + } +#line 11782 "MachineIndependent/glslang_tab.cpp" + break; + + case 638: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */ +#line 4172 "MachineIndependent/glslang.y" + { + parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + (yyval.interm.intermNode) = 0; + } +#line 11791 "MachineIndependent/glslang_tab.cpp" + break; + + case 639: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */ +#line 4176 "MachineIndependent/glslang.y" + { + parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); + parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + (yyval.interm.intermNode) = 0; + } +#line 11801 "MachineIndependent/glslang_tab.cpp" + break; + + case 640: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN */ +#line 4181 "MachineIndependent/glslang.y" + { + parseContext.intermediate.insertSpirvExecutionModeId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + (yyval.interm.intermNode) = 0; + } +#line 11810 "MachineIndependent/glslang_tab.cpp" + break; + + case 641: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN */ +#line 4185 "MachineIndependent/glslang.y" + { + parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); + parseContext.intermediate.insertSpirvExecutionModeId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + (yyval.interm.intermNode) = 0; + } +#line 11820 "MachineIndependent/glslang_tab.cpp" + break; + + case 642: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter */ +#line 4192 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); + } +#line 11828 "MachineIndependent/glslang_tab.cpp" + break; + + case 643: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter */ +#line 4195 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode)); + } +#line 11836 "MachineIndependent/glslang_tab.cpp" + break; + + case 644: /* spirv_execution_mode_parameter: FLOATCONSTANT */ +#line 4200 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); + } +#line 11844 "MachineIndependent/glslang_tab.cpp" + break; + + case 645: /* spirv_execution_mode_parameter: INTCONSTANT */ +#line 4203 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 11852 "MachineIndependent/glslang_tab.cpp" + break; + + case 646: /* spirv_execution_mode_parameter: UINTCONSTANT */ +#line 4206 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + } +#line 11860 "MachineIndependent/glslang_tab.cpp" + break; + + case 647: /* spirv_execution_mode_parameter: BOOLCONSTANT */ +#line 4209 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); + } +#line 11868 "MachineIndependent/glslang_tab.cpp" + break; + + case 648: /* spirv_execution_mode_parameter: STRING_LITERAL */ +#line 4212 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true); + } +#line 11876 "MachineIndependent/glslang_tab.cpp" + break; + + case 649: /* spirv_execution_mode_id_parameter_list: constant_expression */ +#line 4217 "MachineIndependent/glslang.y" + { + if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtUint && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtBool && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtString) + parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), ""); + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermTypedNode)); + } +#line 11890 "MachineIndependent/glslang_tab.cpp" + break; + + case 650: /* spirv_execution_mode_id_parameter_list: spirv_execution_mode_id_parameter_list COMMA constant_expression */ +#line 4226 "MachineIndependent/glslang.y" + { + if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtUint && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtBool && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtString) + parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), ""); + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermTypedNode)); + } +#line 11904 "MachineIndependent/glslang_tab.cpp" + break; + + case 651: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN */ +#line 4237 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-3].lex).loc); + (yyval.interm.type).qualifier.storage = EvqSpirvStorageClass; + (yyval.interm.type).qualifier.spirvStorageClass = (yyvsp[-1].lex).i; + } +#line 11914 "MachineIndependent/glslang_tab.cpp" + break; + + case 652: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ +#line 4242 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-5].lex).loc); + parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); + (yyval.interm.type).qualifier.storage = EvqSpirvStorageClass; + (yyval.interm.type).qualifier.spirvStorageClass = (yyvsp[-1].lex).i; + } +#line 11925 "MachineIndependent/glslang_tab.cpp" + break; + + case 653: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN */ +#line 4250 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-3].lex).loc); + (yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-1].lex).i); + } +#line 11934 "MachineIndependent/glslang_tab.cpp" + break; + + case 654: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ +#line 4254 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-5].lex).loc); + parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); + (yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-1].lex).i); + } +#line 11944 "MachineIndependent/glslang_tab.cpp" + break; + + case 655: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */ +#line 4259 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-5].lex).loc); + (yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + } +#line 11953 "MachineIndependent/glslang_tab.cpp" + break; + + case 656: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */ +#line 4263 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-7].lex).loc); + parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); + (yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + } +#line 11963 "MachineIndependent/glslang_tab.cpp" + break; + + case 657: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */ +#line 4268 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-5].lex).loc); + (yyval.interm.type).qualifier.setSpirvDecorateId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + } +#line 11972 "MachineIndependent/glslang_tab.cpp" + break; + + case 658: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */ +#line 4272 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-7].lex).loc); + parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); + (yyval.interm.type).qualifier.setSpirvDecorateId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + } +#line 11982 "MachineIndependent/glslang_tab.cpp" + break; + + case 659: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */ +#line 4277 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-5].lex).loc); + (yyval.interm.type).qualifier.setSpirvDecorateString((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + } +#line 11991 "MachineIndependent/glslang_tab.cpp" + break; + + case 660: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */ +#line 4281 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-7].lex).loc); + parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); + (yyval.interm.type).qualifier.setSpirvDecorateString((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); + } +#line 12001 "MachineIndependent/glslang_tab.cpp" + break; + + case 661: /* spirv_decorate_parameter_list: spirv_decorate_parameter */ +#line 4288 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); + } +#line 12009 "MachineIndependent/glslang_tab.cpp" + break; + + case 662: /* spirv_decorate_parameter_list: spirv_decorate_parameter_list COMMA spirv_decorate_parameter */ +#line 4291 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode)); + } +#line 12017 "MachineIndependent/glslang_tab.cpp" + break; + + case 663: /* spirv_decorate_parameter: FLOATCONSTANT */ +#line 4296 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); + } +#line 12025 "MachineIndependent/glslang_tab.cpp" + break; + + case 664: /* spirv_decorate_parameter: INTCONSTANT */ +#line 4299 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 12033 "MachineIndependent/glslang_tab.cpp" + break; + + case 665: /* spirv_decorate_parameter: UINTCONSTANT */ +#line 4302 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + } +#line 12041 "MachineIndependent/glslang_tab.cpp" + break; + + case 666: /* spirv_decorate_parameter: BOOLCONSTANT */ +#line 4305 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); + } +#line 12049 "MachineIndependent/glslang_tab.cpp" + break; + + case 667: /* spirv_decorate_id_parameter_list: constant_expression */ +#line 4310 "MachineIndependent/glslang.y" + { + if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtUint && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtBool) + parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), ""); + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermTypedNode)); + } +#line 12062 "MachineIndependent/glslang_tab.cpp" + break; + + case 668: /* spirv_decorate_id_parameter_list: spirv_decorate_id_parameter_list COMMA constant_expression */ +#line 4318 "MachineIndependent/glslang.y" + { + if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtUint && + (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtBool) + parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), ""); + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermTypedNode)); + } +#line 12075 "MachineIndependent/glslang_tab.cpp" + break; + + case 669: /* spirv_decorate_string_parameter_list: STRING_LITERAL */ +#line 4328 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate( + parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); + } +#line 12084 "MachineIndependent/glslang_tab.cpp" + break; + + case 670: /* spirv_decorate_string_parameter_list: spirv_decorate_string_parameter_list COMMA STRING_LITERAL */ +#line 4332 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); + } +#line 12092 "MachineIndependent/glslang_tab.cpp" + break; + + case 671: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */ +#line 4337 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-5].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).setSpirvType(*(yyvsp[-3].interm.spirvInst), (yyvsp[-1].interm.spirvTypeParams)); + } +#line 12101 "MachineIndependent/glslang_tab.cpp" + break; + + case 672: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */ +#line 4341 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-7].lex).loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); + (yyval.interm.type).setSpirvType(*(yyvsp[-3].interm.spirvInst), (yyvsp[-1].interm.spirvTypeParams)); + } +#line 12111 "MachineIndependent/glslang_tab.cpp" + break; + + case 673: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */ +#line 4346 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-3].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).setSpirvType(*(yyvsp[-1].interm.spirvInst)); + } +#line 12120 "MachineIndependent/glslang_tab.cpp" + break; + + case 674: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */ +#line 4350 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[-5].lex).loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); + (yyval.interm.type).setSpirvType(*(yyvsp[-1].interm.spirvInst)); + } +#line 12130 "MachineIndependent/glslang_tab.cpp" + break; + + case 675: /* spirv_type_parameter_list: spirv_type_parameter */ +#line 4357 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvTypeParams) = (yyvsp[0].interm.spirvTypeParams); + } +#line 12138 "MachineIndependent/glslang_tab.cpp" + break; + + case 676: /* spirv_type_parameter_list: spirv_type_parameter_list COMMA spirv_type_parameter */ +#line 4360 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvTypeParams) = parseContext.mergeSpirvTypeParameters((yyvsp[-2].interm.spirvTypeParams), (yyvsp[0].interm.spirvTypeParams)); + } +#line 12146 "MachineIndependent/glslang_tab.cpp" + break; + + case 677: /* spirv_type_parameter: constant_expression */ +#line 4365 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvTypeParams) = parseContext.makeSpirvTypeParameters((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)->getAsConstantUnion()); + } +#line 12154 "MachineIndependent/glslang_tab.cpp" + break; + + case 678: /* spirv_type_parameter: type_specifier */ +#line 4368 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvTypeParams) = parseContext.makeSpirvTypeParameters((yyvsp[0].interm.type)); + } +#line 12162 "MachineIndependent/glslang_tab.cpp" + break; + + case 679: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */ +#line 4373 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvInst) = (yyvsp[-1].interm.spirvInst); + } +#line 12170 "MachineIndependent/glslang_tab.cpp" + break; + + case 680: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */ +#line 4376 "MachineIndependent/glslang.y" + { + parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); + (yyval.interm.spirvInst) = (yyvsp[-1].interm.spirvInst); + } +#line 12179 "MachineIndependent/glslang_tab.cpp" + break; + + case 681: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_id */ +#line 4382 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvInst) = (yyvsp[0].interm.spirvInst); + } +#line 12187 "MachineIndependent/glslang_tab.cpp" + break; + + case 682: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id */ +#line 4385 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvInst) = parseContext.mergeSpirvInstruction((yyvsp[-1].lex).loc, (yyvsp[-2].interm.spirvInst), (yyvsp[0].interm.spirvInst)); + } +#line 12195 "MachineIndependent/glslang_tab.cpp" + break; + + case 683: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL STRING_LITERAL */ +#line 4390 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvInst) = parseContext.makeSpirvInstruction((yyvsp[-1].lex).loc, *(yyvsp[-2].lex).string, *(yyvsp[0].lex).string); + } +#line 12203 "MachineIndependent/glslang_tab.cpp" + break; + + case 684: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL INTCONSTANT */ +#line 4393 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvInst) = parseContext.makeSpirvInstruction((yyvsp[-1].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[0].lex).i); + } +#line 12211 "MachineIndependent/glslang_tab.cpp" break; -#line 10164 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 12215 "MachineIndependent/glslang_tab.cpp" + default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -10174,25 +12226,23 @@ yyreduce: case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; - YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } goto yynewstate; @@ -10203,50 +12253,44 @@ yyreduce: yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (pParseContext, YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) { + yypcontext_t yyctx + = {yyssp, yytoken}; char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; + yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); if (yysyntax_error_status == 0) yymsgp = yymsg; - else if (yysyntax_error_status == 1) + else if (yysyntax_error_status == -1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) + yymsg = YY_CAST (char *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); + if (yymsg) { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; + yysyntax_error_status + = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); + yymsgp = yymsg; } else { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = YYENOMEM; } } yyerror (pParseContext, yymsgp); - if (yysyntax_error_status == 2) + if (yysyntax_error_status == YYENOMEM) goto yyexhaustedlab; } -# undef YYSYNTAX_ERROR -#endif } - - if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an @@ -10275,12 +12319,10 @@ yyerrlab: | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -10297,13 +12339,14 @@ yyerrorlab: yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ + /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) @@ -10317,7 +12360,7 @@ yyerrlab1: yydestruct ("Error: popping", - yystos[yystate], yyvsp, pParseContext); + YY_ACCESSING_SYMBOL (yystate), yyvsp, pParseContext); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); @@ -10329,7 +12372,7 @@ yyerrlab1: /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; @@ -10342,6 +12385,7 @@ yyacceptlab: yyresult = 0; goto yyreturn; + /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ @@ -10349,16 +12393,21 @@ yyabortlab: yyresult = 1; goto yyreturn; -#if !defined yyoverflow || YYERROR_VERBOSE + +#if 1 /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (pParseContext, YY_("memory exhausted")); yyresult = 2; - /* Fall through. */ + goto yyreturn; #endif + +/*-------------------------------------------------------. +| yyreturn -- parsing is finished, clean up and return. | +`-------------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { @@ -10375,18 +12424,17 @@ yyreturn: while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, pParseContext); + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, pParseContext); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif -#if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); -#endif return yyresult; } -#line 3748 "MachineIndependent/glslang.y" /* yacc.c:1906 */ + +#line 4398 "MachineIndependent/glslang.y" diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang_tab.cpp.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang_tab.cpp.h index 6fcdd92..596a10e 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang_tab.cpp.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang_tab.cpp.h @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.7.4. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +31,10 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + #ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED # define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED /* Debug traces. */ @@ -40,424 +45,476 @@ extern int yydebug; #endif -/* Token type. */ +/* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { - ATTRIBUTE = 258, - VARYING = 259, - FLOAT16_T = 260, - FLOAT = 261, - FLOAT32_T = 262, - DOUBLE = 263, - FLOAT64_T = 264, - CONST = 265, - BOOL = 266, - INT = 267, - UINT = 268, - INT64_T = 269, - UINT64_T = 270, - INT32_T = 271, - UINT32_T = 272, - INT16_T = 273, - UINT16_T = 274, - INT8_T = 275, - UINT8_T = 276, - BREAK = 277, - CONTINUE = 278, - DO = 279, - ELSE = 280, - FOR = 281, - IF = 282, - DISCARD = 283, - RETURN = 284, - SWITCH = 285, - CASE = 286, - DEFAULT = 287, - SUBROUTINE = 288, - BVEC2 = 289, - BVEC3 = 290, - BVEC4 = 291, - IVEC2 = 292, - IVEC3 = 293, - IVEC4 = 294, - UVEC2 = 295, - UVEC3 = 296, - UVEC4 = 297, - I64VEC2 = 298, - I64VEC3 = 299, - I64VEC4 = 300, - U64VEC2 = 301, - U64VEC3 = 302, - U64VEC4 = 303, - I32VEC2 = 304, - I32VEC3 = 305, - I32VEC4 = 306, - U32VEC2 = 307, - U32VEC3 = 308, - U32VEC4 = 309, - I16VEC2 = 310, - I16VEC3 = 311, - I16VEC4 = 312, - U16VEC2 = 313, - U16VEC3 = 314, - U16VEC4 = 315, - I8VEC2 = 316, - I8VEC3 = 317, - I8VEC4 = 318, - U8VEC2 = 319, - U8VEC3 = 320, - U8VEC4 = 321, - VEC2 = 322, - VEC3 = 323, - VEC4 = 324, - MAT2 = 325, - MAT3 = 326, - MAT4 = 327, - CENTROID = 328, - IN = 329, - OUT = 330, - INOUT = 331, - UNIFORM = 332, - PATCH = 333, - SAMPLE = 334, - BUFFER = 335, - SHARED = 336, - NONUNIFORM = 337, - PAYLOADNV = 338, - PAYLOADINNV = 339, - HITATTRNV = 340, - CALLDATANV = 341, - CALLDATAINNV = 342, - COHERENT = 343, - VOLATILE = 344, - RESTRICT = 345, - READONLY = 346, - WRITEONLY = 347, - DEVICECOHERENT = 348, - QUEUEFAMILYCOHERENT = 349, - WORKGROUPCOHERENT = 350, - SUBGROUPCOHERENT = 351, - NONPRIVATE = 352, - DVEC2 = 353, - DVEC3 = 354, - DVEC4 = 355, - DMAT2 = 356, - DMAT3 = 357, - DMAT4 = 358, - F16VEC2 = 359, - F16VEC3 = 360, - F16VEC4 = 361, - F16MAT2 = 362, - F16MAT3 = 363, - F16MAT4 = 364, - F32VEC2 = 365, - F32VEC3 = 366, - F32VEC4 = 367, - F32MAT2 = 368, - F32MAT3 = 369, - F32MAT4 = 370, - F64VEC2 = 371, - F64VEC3 = 372, - F64VEC4 = 373, - F64MAT2 = 374, - F64MAT3 = 375, - F64MAT4 = 376, - NOPERSPECTIVE = 377, - FLAT = 378, - SMOOTH = 379, - LAYOUT = 380, - EXPLICITINTERPAMD = 381, - PERVERTEXNV = 382, - PERPRIMITIVENV = 383, - PERVIEWNV = 384, - PERTASKNV = 385, - MAT2X2 = 386, - MAT2X3 = 387, - MAT2X4 = 388, - MAT3X2 = 389, - MAT3X3 = 390, - MAT3X4 = 391, - MAT4X2 = 392, - MAT4X3 = 393, - MAT4X4 = 394, - DMAT2X2 = 395, - DMAT2X3 = 396, - DMAT2X4 = 397, - DMAT3X2 = 398, - DMAT3X3 = 399, - DMAT3X4 = 400, - DMAT4X2 = 401, - DMAT4X3 = 402, - DMAT4X4 = 403, - F16MAT2X2 = 404, - F16MAT2X3 = 405, - F16MAT2X4 = 406, - F16MAT3X2 = 407, - F16MAT3X3 = 408, - F16MAT3X4 = 409, - F16MAT4X2 = 410, - F16MAT4X3 = 411, - F16MAT4X4 = 412, - F32MAT2X2 = 413, - F32MAT2X3 = 414, - F32MAT2X4 = 415, - F32MAT3X2 = 416, - F32MAT3X3 = 417, - F32MAT3X4 = 418, - F32MAT4X2 = 419, - F32MAT4X3 = 420, - F32MAT4X4 = 421, - F64MAT2X2 = 422, - F64MAT2X3 = 423, - F64MAT2X4 = 424, - F64MAT3X2 = 425, - F64MAT3X3 = 426, - F64MAT3X4 = 427, - F64MAT4X2 = 428, - F64MAT4X3 = 429, - F64MAT4X4 = 430, - ATOMIC_UINT = 431, - ACCSTRUCTNV = 432, - SAMPLER1D = 433, - SAMPLER2D = 434, - SAMPLER3D = 435, - SAMPLERCUBE = 436, - SAMPLER1DSHADOW = 437, - SAMPLER2DSHADOW = 438, - SAMPLERCUBESHADOW = 439, - SAMPLER1DARRAY = 440, - SAMPLER2DARRAY = 441, - SAMPLER1DARRAYSHADOW = 442, - SAMPLER2DARRAYSHADOW = 443, - ISAMPLER1D = 444, - ISAMPLER2D = 445, - ISAMPLER3D = 446, - ISAMPLERCUBE = 447, - ISAMPLER1DARRAY = 448, - ISAMPLER2DARRAY = 449, - USAMPLER1D = 450, - USAMPLER2D = 451, - USAMPLER3D = 452, - USAMPLERCUBE = 453, - USAMPLER1DARRAY = 454, - USAMPLER2DARRAY = 455, - SAMPLER2DRECT = 456, - SAMPLER2DRECTSHADOW = 457, - ISAMPLER2DRECT = 458, - USAMPLER2DRECT = 459, - SAMPLERBUFFER = 460, - ISAMPLERBUFFER = 461, - USAMPLERBUFFER = 462, - SAMPLERCUBEARRAY = 463, - SAMPLERCUBEARRAYSHADOW = 464, - ISAMPLERCUBEARRAY = 465, - USAMPLERCUBEARRAY = 466, - SAMPLER2DMS = 467, - ISAMPLER2DMS = 468, - USAMPLER2DMS = 469, - SAMPLER2DMSARRAY = 470, - ISAMPLER2DMSARRAY = 471, - USAMPLER2DMSARRAY = 472, - SAMPLEREXTERNALOES = 473, - SAMPLEREXTERNAL2DY2YEXT = 474, - F16SAMPLER1D = 475, - F16SAMPLER2D = 476, - F16SAMPLER3D = 477, - F16SAMPLER2DRECT = 478, - F16SAMPLERCUBE = 479, - F16SAMPLER1DARRAY = 480, - F16SAMPLER2DARRAY = 481, - F16SAMPLERCUBEARRAY = 482, - F16SAMPLERBUFFER = 483, - F16SAMPLER2DMS = 484, - F16SAMPLER2DMSARRAY = 485, - F16SAMPLER1DSHADOW = 486, - F16SAMPLER2DSHADOW = 487, - F16SAMPLER1DARRAYSHADOW = 488, - F16SAMPLER2DARRAYSHADOW = 489, - F16SAMPLER2DRECTSHADOW = 490, - F16SAMPLERCUBESHADOW = 491, - F16SAMPLERCUBEARRAYSHADOW = 492, - SAMPLER = 493, - SAMPLERSHADOW = 494, - TEXTURE1D = 495, - TEXTURE2D = 496, - TEXTURE3D = 497, - TEXTURECUBE = 498, - TEXTURE1DARRAY = 499, - TEXTURE2DARRAY = 500, - ITEXTURE1D = 501, - ITEXTURE2D = 502, - ITEXTURE3D = 503, - ITEXTURECUBE = 504, - ITEXTURE1DARRAY = 505, - ITEXTURE2DARRAY = 506, - UTEXTURE1D = 507, - UTEXTURE2D = 508, - UTEXTURE3D = 509, - UTEXTURECUBE = 510, - UTEXTURE1DARRAY = 511, - UTEXTURE2DARRAY = 512, - TEXTURE2DRECT = 513, - ITEXTURE2DRECT = 514, - UTEXTURE2DRECT = 515, - TEXTUREBUFFER = 516, - ITEXTUREBUFFER = 517, - UTEXTUREBUFFER = 518, - TEXTURECUBEARRAY = 519, - ITEXTURECUBEARRAY = 520, - UTEXTURECUBEARRAY = 521, - TEXTURE2DMS = 522, - ITEXTURE2DMS = 523, - UTEXTURE2DMS = 524, - TEXTURE2DMSARRAY = 525, - ITEXTURE2DMSARRAY = 526, - UTEXTURE2DMSARRAY = 527, - F16TEXTURE1D = 528, - F16TEXTURE2D = 529, - F16TEXTURE3D = 530, - F16TEXTURE2DRECT = 531, - F16TEXTURECUBE = 532, - F16TEXTURE1DARRAY = 533, - F16TEXTURE2DARRAY = 534, - F16TEXTURECUBEARRAY = 535, - F16TEXTUREBUFFER = 536, - F16TEXTURE2DMS = 537, - F16TEXTURE2DMSARRAY = 538, - SUBPASSINPUT = 539, - SUBPASSINPUTMS = 540, - ISUBPASSINPUT = 541, - ISUBPASSINPUTMS = 542, - USUBPASSINPUT = 543, - USUBPASSINPUTMS = 544, - F16SUBPASSINPUT = 545, - F16SUBPASSINPUTMS = 546, - IMAGE1D = 547, - IIMAGE1D = 548, - UIMAGE1D = 549, - IMAGE2D = 550, - IIMAGE2D = 551, - UIMAGE2D = 552, - IMAGE3D = 553, - IIMAGE3D = 554, - UIMAGE3D = 555, - IMAGE2DRECT = 556, - IIMAGE2DRECT = 557, - UIMAGE2DRECT = 558, - IMAGECUBE = 559, - IIMAGECUBE = 560, - UIMAGECUBE = 561, - IMAGEBUFFER = 562, - IIMAGEBUFFER = 563, - UIMAGEBUFFER = 564, - IMAGE1DARRAY = 565, - IIMAGE1DARRAY = 566, - UIMAGE1DARRAY = 567, - IMAGE2DARRAY = 568, - IIMAGE2DARRAY = 569, - UIMAGE2DARRAY = 570, - IMAGECUBEARRAY = 571, - IIMAGECUBEARRAY = 572, - UIMAGECUBEARRAY = 573, - IMAGE2DMS = 574, - IIMAGE2DMS = 575, - UIMAGE2DMS = 576, - IMAGE2DMSARRAY = 577, - IIMAGE2DMSARRAY = 578, - UIMAGE2DMSARRAY = 579, - F16IMAGE1D = 580, - F16IMAGE2D = 581, - F16IMAGE3D = 582, - F16IMAGE2DRECT = 583, - F16IMAGECUBE = 584, - F16IMAGE1DARRAY = 585, - F16IMAGE2DARRAY = 586, - F16IMAGECUBEARRAY = 587, - F16IMAGEBUFFER = 588, - F16IMAGE2DMS = 589, - F16IMAGE2DMSARRAY = 590, - STRUCT = 591, - VOID = 592, - WHILE = 593, - IDENTIFIER = 594, - TYPE_NAME = 595, - FLOATCONSTANT = 596, - DOUBLECONSTANT = 597, - INT16CONSTANT = 598, - UINT16CONSTANT = 599, - INT32CONSTANT = 600, - UINT32CONSTANT = 601, - INTCONSTANT = 602, - UINTCONSTANT = 603, - INT64CONSTANT = 604, - UINT64CONSTANT = 605, - BOOLCONSTANT = 606, - FLOAT16CONSTANT = 607, - LEFT_OP = 608, - RIGHT_OP = 609, - INC_OP = 610, - DEC_OP = 611, - LE_OP = 612, - GE_OP = 613, - EQ_OP = 614, - NE_OP = 615, - AND_OP = 616, - OR_OP = 617, - XOR_OP = 618, - MUL_ASSIGN = 619, - DIV_ASSIGN = 620, - ADD_ASSIGN = 621, - MOD_ASSIGN = 622, - LEFT_ASSIGN = 623, - RIGHT_ASSIGN = 624, - AND_ASSIGN = 625, - XOR_ASSIGN = 626, - OR_ASSIGN = 627, - SUB_ASSIGN = 628, - LEFT_PAREN = 629, - RIGHT_PAREN = 630, - LEFT_BRACKET = 631, - RIGHT_BRACKET = 632, - LEFT_BRACE = 633, - RIGHT_BRACE = 634, - DOT = 635, - COMMA = 636, - COLON = 637, - EQUAL = 638, - SEMICOLON = 639, - BANG = 640, - DASH = 641, - TILDE = 642, - PLUS = 643, - STAR = 644, - SLASH = 645, - PERCENT = 646, - LEFT_ANGLE = 647, - RIGHT_ANGLE = 648, - VERTICAL_BAR = 649, - CARET = 650, - AMPERSAND = 651, - QUESTION = 652, - INVARIANT = 653, - PRECISE = 654, - HIGH_PRECISION = 655, - MEDIUM_PRECISION = 656, - LOW_PRECISION = 657, - PRECISION = 658, - PACKED = 659, - RESOURCE = 660, - SUPERP = 661 + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + CONST = 258, /* CONST */ + BOOL = 259, /* BOOL */ + INT = 260, /* INT */ + UINT = 261, /* UINT */ + FLOAT = 262, /* FLOAT */ + BVEC2 = 263, /* BVEC2 */ + BVEC3 = 264, /* BVEC3 */ + BVEC4 = 265, /* BVEC4 */ + IVEC2 = 266, /* IVEC2 */ + IVEC3 = 267, /* IVEC3 */ + IVEC4 = 268, /* IVEC4 */ + UVEC2 = 269, /* UVEC2 */ + UVEC3 = 270, /* UVEC3 */ + UVEC4 = 271, /* UVEC4 */ + VEC2 = 272, /* VEC2 */ + VEC3 = 273, /* VEC3 */ + VEC4 = 274, /* VEC4 */ + MAT2 = 275, /* MAT2 */ + MAT3 = 276, /* MAT3 */ + MAT4 = 277, /* MAT4 */ + MAT2X2 = 278, /* MAT2X2 */ + MAT2X3 = 279, /* MAT2X3 */ + MAT2X4 = 280, /* MAT2X4 */ + MAT3X2 = 281, /* MAT3X2 */ + MAT3X3 = 282, /* MAT3X3 */ + MAT3X4 = 283, /* MAT3X4 */ + MAT4X2 = 284, /* MAT4X2 */ + MAT4X3 = 285, /* MAT4X3 */ + MAT4X4 = 286, /* MAT4X4 */ + SAMPLER2D = 287, /* SAMPLER2D */ + SAMPLER3D = 288, /* SAMPLER3D */ + SAMPLERCUBE = 289, /* SAMPLERCUBE */ + SAMPLER2DSHADOW = 290, /* SAMPLER2DSHADOW */ + SAMPLERCUBESHADOW = 291, /* SAMPLERCUBESHADOW */ + SAMPLER2DARRAY = 292, /* SAMPLER2DARRAY */ + SAMPLER2DARRAYSHADOW = 293, /* SAMPLER2DARRAYSHADOW */ + ISAMPLER2D = 294, /* ISAMPLER2D */ + ISAMPLER3D = 295, /* ISAMPLER3D */ + ISAMPLERCUBE = 296, /* ISAMPLERCUBE */ + ISAMPLER2DARRAY = 297, /* ISAMPLER2DARRAY */ + USAMPLER2D = 298, /* USAMPLER2D */ + USAMPLER3D = 299, /* USAMPLER3D */ + USAMPLERCUBE = 300, /* USAMPLERCUBE */ + USAMPLER2DARRAY = 301, /* USAMPLER2DARRAY */ + SAMPLER = 302, /* SAMPLER */ + SAMPLERSHADOW = 303, /* SAMPLERSHADOW */ + TEXTURE2D = 304, /* TEXTURE2D */ + TEXTURE3D = 305, /* TEXTURE3D */ + TEXTURECUBE = 306, /* TEXTURECUBE */ + TEXTURE2DARRAY = 307, /* TEXTURE2DARRAY */ + ITEXTURE2D = 308, /* ITEXTURE2D */ + ITEXTURE3D = 309, /* ITEXTURE3D */ + ITEXTURECUBE = 310, /* ITEXTURECUBE */ + ITEXTURE2DARRAY = 311, /* ITEXTURE2DARRAY */ + UTEXTURE2D = 312, /* UTEXTURE2D */ + UTEXTURE3D = 313, /* UTEXTURE3D */ + UTEXTURECUBE = 314, /* UTEXTURECUBE */ + UTEXTURE2DARRAY = 315, /* UTEXTURE2DARRAY */ + ATTRIBUTE = 316, /* ATTRIBUTE */ + VARYING = 317, /* VARYING */ + FLOAT16_T = 318, /* FLOAT16_T */ + FLOAT32_T = 319, /* FLOAT32_T */ + DOUBLE = 320, /* DOUBLE */ + FLOAT64_T = 321, /* FLOAT64_T */ + INT64_T = 322, /* INT64_T */ + UINT64_T = 323, /* UINT64_T */ + INT32_T = 324, /* INT32_T */ + UINT32_T = 325, /* UINT32_T */ + INT16_T = 326, /* INT16_T */ + UINT16_T = 327, /* UINT16_T */ + INT8_T = 328, /* INT8_T */ + UINT8_T = 329, /* UINT8_T */ + I64VEC2 = 330, /* I64VEC2 */ + I64VEC3 = 331, /* I64VEC3 */ + I64VEC4 = 332, /* I64VEC4 */ + U64VEC2 = 333, /* U64VEC2 */ + U64VEC3 = 334, /* U64VEC3 */ + U64VEC4 = 335, /* U64VEC4 */ + I32VEC2 = 336, /* I32VEC2 */ + I32VEC3 = 337, /* I32VEC3 */ + I32VEC4 = 338, /* I32VEC4 */ + U32VEC2 = 339, /* U32VEC2 */ + U32VEC3 = 340, /* U32VEC3 */ + U32VEC4 = 341, /* U32VEC4 */ + I16VEC2 = 342, /* I16VEC2 */ + I16VEC3 = 343, /* I16VEC3 */ + I16VEC4 = 344, /* I16VEC4 */ + U16VEC2 = 345, /* U16VEC2 */ + U16VEC3 = 346, /* U16VEC3 */ + U16VEC4 = 347, /* U16VEC4 */ + I8VEC2 = 348, /* I8VEC2 */ + I8VEC3 = 349, /* I8VEC3 */ + I8VEC4 = 350, /* I8VEC4 */ + U8VEC2 = 351, /* U8VEC2 */ + U8VEC3 = 352, /* U8VEC3 */ + U8VEC4 = 353, /* U8VEC4 */ + DVEC2 = 354, /* DVEC2 */ + DVEC3 = 355, /* DVEC3 */ + DVEC4 = 356, /* DVEC4 */ + DMAT2 = 357, /* DMAT2 */ + DMAT3 = 358, /* DMAT3 */ + DMAT4 = 359, /* DMAT4 */ + F16VEC2 = 360, /* F16VEC2 */ + F16VEC3 = 361, /* F16VEC3 */ + F16VEC4 = 362, /* F16VEC4 */ + F16MAT2 = 363, /* F16MAT2 */ + F16MAT3 = 364, /* F16MAT3 */ + F16MAT4 = 365, /* F16MAT4 */ + F32VEC2 = 366, /* F32VEC2 */ + F32VEC3 = 367, /* F32VEC3 */ + F32VEC4 = 368, /* F32VEC4 */ + F32MAT2 = 369, /* F32MAT2 */ + F32MAT3 = 370, /* F32MAT3 */ + F32MAT4 = 371, /* F32MAT4 */ + F64VEC2 = 372, /* F64VEC2 */ + F64VEC3 = 373, /* F64VEC3 */ + F64VEC4 = 374, /* F64VEC4 */ + F64MAT2 = 375, /* F64MAT2 */ + F64MAT3 = 376, /* F64MAT3 */ + F64MAT4 = 377, /* F64MAT4 */ + DMAT2X2 = 378, /* DMAT2X2 */ + DMAT2X3 = 379, /* DMAT2X3 */ + DMAT2X4 = 380, /* DMAT2X4 */ + DMAT3X2 = 381, /* DMAT3X2 */ + DMAT3X3 = 382, /* DMAT3X3 */ + DMAT3X4 = 383, /* DMAT3X4 */ + DMAT4X2 = 384, /* DMAT4X2 */ + DMAT4X3 = 385, /* DMAT4X3 */ + DMAT4X4 = 386, /* DMAT4X4 */ + F16MAT2X2 = 387, /* F16MAT2X2 */ + F16MAT2X3 = 388, /* F16MAT2X3 */ + F16MAT2X4 = 389, /* F16MAT2X4 */ + F16MAT3X2 = 390, /* F16MAT3X2 */ + F16MAT3X3 = 391, /* F16MAT3X3 */ + F16MAT3X4 = 392, /* F16MAT3X4 */ + F16MAT4X2 = 393, /* F16MAT4X2 */ + F16MAT4X3 = 394, /* F16MAT4X3 */ + F16MAT4X4 = 395, /* F16MAT4X4 */ + F32MAT2X2 = 396, /* F32MAT2X2 */ + F32MAT2X3 = 397, /* F32MAT2X3 */ + F32MAT2X4 = 398, /* F32MAT2X4 */ + F32MAT3X2 = 399, /* F32MAT3X2 */ + F32MAT3X3 = 400, /* F32MAT3X3 */ + F32MAT3X4 = 401, /* F32MAT3X4 */ + F32MAT4X2 = 402, /* F32MAT4X2 */ + F32MAT4X3 = 403, /* F32MAT4X3 */ + F32MAT4X4 = 404, /* F32MAT4X4 */ + F64MAT2X2 = 405, /* F64MAT2X2 */ + F64MAT2X3 = 406, /* F64MAT2X3 */ + F64MAT2X4 = 407, /* F64MAT2X4 */ + F64MAT3X2 = 408, /* F64MAT3X2 */ + F64MAT3X3 = 409, /* F64MAT3X3 */ + F64MAT3X4 = 410, /* F64MAT3X4 */ + F64MAT4X2 = 411, /* F64MAT4X2 */ + F64MAT4X3 = 412, /* F64MAT4X3 */ + F64MAT4X4 = 413, /* F64MAT4X4 */ + ATOMIC_UINT = 414, /* ATOMIC_UINT */ + ACCSTRUCTNV = 415, /* ACCSTRUCTNV */ + ACCSTRUCTEXT = 416, /* ACCSTRUCTEXT */ + RAYQUERYEXT = 417, /* RAYQUERYEXT */ + FCOOPMATNV = 418, /* FCOOPMATNV */ + ICOOPMATNV = 419, /* ICOOPMATNV */ + UCOOPMATNV = 420, /* UCOOPMATNV */ + SAMPLERCUBEARRAY = 421, /* SAMPLERCUBEARRAY */ + SAMPLERCUBEARRAYSHADOW = 422, /* SAMPLERCUBEARRAYSHADOW */ + ISAMPLERCUBEARRAY = 423, /* ISAMPLERCUBEARRAY */ + USAMPLERCUBEARRAY = 424, /* USAMPLERCUBEARRAY */ + SAMPLER1D = 425, /* SAMPLER1D */ + SAMPLER1DARRAY = 426, /* SAMPLER1DARRAY */ + SAMPLER1DARRAYSHADOW = 427, /* SAMPLER1DARRAYSHADOW */ + ISAMPLER1D = 428, /* ISAMPLER1D */ + SAMPLER1DSHADOW = 429, /* SAMPLER1DSHADOW */ + SAMPLER2DRECT = 430, /* SAMPLER2DRECT */ + SAMPLER2DRECTSHADOW = 431, /* SAMPLER2DRECTSHADOW */ + ISAMPLER2DRECT = 432, /* ISAMPLER2DRECT */ + USAMPLER2DRECT = 433, /* USAMPLER2DRECT */ + SAMPLERBUFFER = 434, /* SAMPLERBUFFER */ + ISAMPLERBUFFER = 435, /* ISAMPLERBUFFER */ + USAMPLERBUFFER = 436, /* USAMPLERBUFFER */ + SAMPLER2DMS = 437, /* SAMPLER2DMS */ + ISAMPLER2DMS = 438, /* ISAMPLER2DMS */ + USAMPLER2DMS = 439, /* USAMPLER2DMS */ + SAMPLER2DMSARRAY = 440, /* SAMPLER2DMSARRAY */ + ISAMPLER2DMSARRAY = 441, /* ISAMPLER2DMSARRAY */ + USAMPLER2DMSARRAY = 442, /* USAMPLER2DMSARRAY */ + SAMPLEREXTERNALOES = 443, /* SAMPLEREXTERNALOES */ + SAMPLEREXTERNAL2DY2YEXT = 444, /* SAMPLEREXTERNAL2DY2YEXT */ + ISAMPLER1DARRAY = 445, /* ISAMPLER1DARRAY */ + USAMPLER1D = 446, /* USAMPLER1D */ + USAMPLER1DARRAY = 447, /* USAMPLER1DARRAY */ + F16SAMPLER1D = 448, /* F16SAMPLER1D */ + F16SAMPLER2D = 449, /* F16SAMPLER2D */ + F16SAMPLER3D = 450, /* F16SAMPLER3D */ + F16SAMPLER2DRECT = 451, /* F16SAMPLER2DRECT */ + F16SAMPLERCUBE = 452, /* F16SAMPLERCUBE */ + F16SAMPLER1DARRAY = 453, /* F16SAMPLER1DARRAY */ + F16SAMPLER2DARRAY = 454, /* F16SAMPLER2DARRAY */ + F16SAMPLERCUBEARRAY = 455, /* F16SAMPLERCUBEARRAY */ + F16SAMPLERBUFFER = 456, /* F16SAMPLERBUFFER */ + F16SAMPLER2DMS = 457, /* F16SAMPLER2DMS */ + F16SAMPLER2DMSARRAY = 458, /* F16SAMPLER2DMSARRAY */ + F16SAMPLER1DSHADOW = 459, /* F16SAMPLER1DSHADOW */ + F16SAMPLER2DSHADOW = 460, /* F16SAMPLER2DSHADOW */ + F16SAMPLER1DARRAYSHADOW = 461, /* F16SAMPLER1DARRAYSHADOW */ + F16SAMPLER2DARRAYSHADOW = 462, /* F16SAMPLER2DARRAYSHADOW */ + F16SAMPLER2DRECTSHADOW = 463, /* F16SAMPLER2DRECTSHADOW */ + F16SAMPLERCUBESHADOW = 464, /* F16SAMPLERCUBESHADOW */ + F16SAMPLERCUBEARRAYSHADOW = 465, /* F16SAMPLERCUBEARRAYSHADOW */ + IMAGE1D = 466, /* IMAGE1D */ + IIMAGE1D = 467, /* IIMAGE1D */ + UIMAGE1D = 468, /* UIMAGE1D */ + IMAGE2D = 469, /* IMAGE2D */ + IIMAGE2D = 470, /* IIMAGE2D */ + UIMAGE2D = 471, /* UIMAGE2D */ + IMAGE3D = 472, /* IMAGE3D */ + IIMAGE3D = 473, /* IIMAGE3D */ + UIMAGE3D = 474, /* UIMAGE3D */ + IMAGE2DRECT = 475, /* IMAGE2DRECT */ + IIMAGE2DRECT = 476, /* IIMAGE2DRECT */ + UIMAGE2DRECT = 477, /* UIMAGE2DRECT */ + IMAGECUBE = 478, /* IMAGECUBE */ + IIMAGECUBE = 479, /* IIMAGECUBE */ + UIMAGECUBE = 480, /* UIMAGECUBE */ + IMAGEBUFFER = 481, /* IMAGEBUFFER */ + IIMAGEBUFFER = 482, /* IIMAGEBUFFER */ + UIMAGEBUFFER = 483, /* UIMAGEBUFFER */ + IMAGE1DARRAY = 484, /* IMAGE1DARRAY */ + IIMAGE1DARRAY = 485, /* IIMAGE1DARRAY */ + UIMAGE1DARRAY = 486, /* UIMAGE1DARRAY */ + IMAGE2DARRAY = 487, /* IMAGE2DARRAY */ + IIMAGE2DARRAY = 488, /* IIMAGE2DARRAY */ + UIMAGE2DARRAY = 489, /* UIMAGE2DARRAY */ + IMAGECUBEARRAY = 490, /* IMAGECUBEARRAY */ + IIMAGECUBEARRAY = 491, /* IIMAGECUBEARRAY */ + UIMAGECUBEARRAY = 492, /* UIMAGECUBEARRAY */ + IMAGE2DMS = 493, /* IMAGE2DMS */ + IIMAGE2DMS = 494, /* IIMAGE2DMS */ + UIMAGE2DMS = 495, /* UIMAGE2DMS */ + IMAGE2DMSARRAY = 496, /* IMAGE2DMSARRAY */ + IIMAGE2DMSARRAY = 497, /* IIMAGE2DMSARRAY */ + UIMAGE2DMSARRAY = 498, /* UIMAGE2DMSARRAY */ + F16IMAGE1D = 499, /* F16IMAGE1D */ + F16IMAGE2D = 500, /* F16IMAGE2D */ + F16IMAGE3D = 501, /* F16IMAGE3D */ + F16IMAGE2DRECT = 502, /* F16IMAGE2DRECT */ + F16IMAGECUBE = 503, /* F16IMAGECUBE */ + F16IMAGE1DARRAY = 504, /* F16IMAGE1DARRAY */ + F16IMAGE2DARRAY = 505, /* F16IMAGE2DARRAY */ + F16IMAGECUBEARRAY = 506, /* F16IMAGECUBEARRAY */ + F16IMAGEBUFFER = 507, /* F16IMAGEBUFFER */ + F16IMAGE2DMS = 508, /* F16IMAGE2DMS */ + F16IMAGE2DMSARRAY = 509, /* F16IMAGE2DMSARRAY */ + I64IMAGE1D = 510, /* I64IMAGE1D */ + U64IMAGE1D = 511, /* U64IMAGE1D */ + I64IMAGE2D = 512, /* I64IMAGE2D */ + U64IMAGE2D = 513, /* U64IMAGE2D */ + I64IMAGE3D = 514, /* I64IMAGE3D */ + U64IMAGE3D = 515, /* U64IMAGE3D */ + I64IMAGE2DRECT = 516, /* I64IMAGE2DRECT */ + U64IMAGE2DRECT = 517, /* U64IMAGE2DRECT */ + I64IMAGECUBE = 518, /* I64IMAGECUBE */ + U64IMAGECUBE = 519, /* U64IMAGECUBE */ + I64IMAGEBUFFER = 520, /* I64IMAGEBUFFER */ + U64IMAGEBUFFER = 521, /* U64IMAGEBUFFER */ + I64IMAGE1DARRAY = 522, /* I64IMAGE1DARRAY */ + U64IMAGE1DARRAY = 523, /* U64IMAGE1DARRAY */ + I64IMAGE2DARRAY = 524, /* I64IMAGE2DARRAY */ + U64IMAGE2DARRAY = 525, /* U64IMAGE2DARRAY */ + I64IMAGECUBEARRAY = 526, /* I64IMAGECUBEARRAY */ + U64IMAGECUBEARRAY = 527, /* U64IMAGECUBEARRAY */ + I64IMAGE2DMS = 528, /* I64IMAGE2DMS */ + U64IMAGE2DMS = 529, /* U64IMAGE2DMS */ + I64IMAGE2DMSARRAY = 530, /* I64IMAGE2DMSARRAY */ + U64IMAGE2DMSARRAY = 531, /* U64IMAGE2DMSARRAY */ + TEXTURECUBEARRAY = 532, /* TEXTURECUBEARRAY */ + ITEXTURECUBEARRAY = 533, /* ITEXTURECUBEARRAY */ + UTEXTURECUBEARRAY = 534, /* UTEXTURECUBEARRAY */ + TEXTURE1D = 535, /* TEXTURE1D */ + ITEXTURE1D = 536, /* ITEXTURE1D */ + UTEXTURE1D = 537, /* UTEXTURE1D */ + TEXTURE1DARRAY = 538, /* TEXTURE1DARRAY */ + ITEXTURE1DARRAY = 539, /* ITEXTURE1DARRAY */ + UTEXTURE1DARRAY = 540, /* UTEXTURE1DARRAY */ + TEXTURE2DRECT = 541, /* TEXTURE2DRECT */ + ITEXTURE2DRECT = 542, /* ITEXTURE2DRECT */ + UTEXTURE2DRECT = 543, /* UTEXTURE2DRECT */ + TEXTUREBUFFER = 544, /* TEXTUREBUFFER */ + ITEXTUREBUFFER = 545, /* ITEXTUREBUFFER */ + UTEXTUREBUFFER = 546, /* UTEXTUREBUFFER */ + TEXTURE2DMS = 547, /* TEXTURE2DMS */ + ITEXTURE2DMS = 548, /* ITEXTURE2DMS */ + UTEXTURE2DMS = 549, /* UTEXTURE2DMS */ + TEXTURE2DMSARRAY = 550, /* TEXTURE2DMSARRAY */ + ITEXTURE2DMSARRAY = 551, /* ITEXTURE2DMSARRAY */ + UTEXTURE2DMSARRAY = 552, /* UTEXTURE2DMSARRAY */ + F16TEXTURE1D = 553, /* F16TEXTURE1D */ + F16TEXTURE2D = 554, /* F16TEXTURE2D */ + F16TEXTURE3D = 555, /* F16TEXTURE3D */ + F16TEXTURE2DRECT = 556, /* F16TEXTURE2DRECT */ + F16TEXTURECUBE = 557, /* F16TEXTURECUBE */ + F16TEXTURE1DARRAY = 558, /* F16TEXTURE1DARRAY */ + F16TEXTURE2DARRAY = 559, /* F16TEXTURE2DARRAY */ + F16TEXTURECUBEARRAY = 560, /* F16TEXTURECUBEARRAY */ + F16TEXTUREBUFFER = 561, /* F16TEXTUREBUFFER */ + F16TEXTURE2DMS = 562, /* F16TEXTURE2DMS */ + F16TEXTURE2DMSARRAY = 563, /* F16TEXTURE2DMSARRAY */ + SUBPASSINPUT = 564, /* SUBPASSINPUT */ + SUBPASSINPUTMS = 565, /* SUBPASSINPUTMS */ + ISUBPASSINPUT = 566, /* ISUBPASSINPUT */ + ISUBPASSINPUTMS = 567, /* ISUBPASSINPUTMS */ + USUBPASSINPUT = 568, /* USUBPASSINPUT */ + USUBPASSINPUTMS = 569, /* USUBPASSINPUTMS */ + F16SUBPASSINPUT = 570, /* F16SUBPASSINPUT */ + F16SUBPASSINPUTMS = 571, /* F16SUBPASSINPUTMS */ + SPIRV_INSTRUCTION = 572, /* SPIRV_INSTRUCTION */ + SPIRV_EXECUTION_MODE = 573, /* SPIRV_EXECUTION_MODE */ + SPIRV_EXECUTION_MODE_ID = 574, /* SPIRV_EXECUTION_MODE_ID */ + SPIRV_DECORATE = 575, /* SPIRV_DECORATE */ + SPIRV_DECORATE_ID = 576, /* SPIRV_DECORATE_ID */ + SPIRV_DECORATE_STRING = 577, /* SPIRV_DECORATE_STRING */ + SPIRV_TYPE = 578, /* SPIRV_TYPE */ + SPIRV_STORAGE_CLASS = 579, /* SPIRV_STORAGE_CLASS */ + SPIRV_BY_REFERENCE = 580, /* SPIRV_BY_REFERENCE */ + SPIRV_LITERAL = 581, /* SPIRV_LITERAL */ + LEFT_OP = 582, /* LEFT_OP */ + RIGHT_OP = 583, /* RIGHT_OP */ + INC_OP = 584, /* INC_OP */ + DEC_OP = 585, /* DEC_OP */ + LE_OP = 586, /* LE_OP */ + GE_OP = 587, /* GE_OP */ + EQ_OP = 588, /* EQ_OP */ + NE_OP = 589, /* NE_OP */ + AND_OP = 590, /* AND_OP */ + OR_OP = 591, /* OR_OP */ + XOR_OP = 592, /* XOR_OP */ + MUL_ASSIGN = 593, /* MUL_ASSIGN */ + DIV_ASSIGN = 594, /* DIV_ASSIGN */ + ADD_ASSIGN = 595, /* ADD_ASSIGN */ + MOD_ASSIGN = 596, /* MOD_ASSIGN */ + LEFT_ASSIGN = 597, /* LEFT_ASSIGN */ + RIGHT_ASSIGN = 598, /* RIGHT_ASSIGN */ + AND_ASSIGN = 599, /* AND_ASSIGN */ + XOR_ASSIGN = 600, /* XOR_ASSIGN */ + OR_ASSIGN = 601, /* OR_ASSIGN */ + SUB_ASSIGN = 602, /* SUB_ASSIGN */ + STRING_LITERAL = 603, /* STRING_LITERAL */ + LEFT_PAREN = 604, /* LEFT_PAREN */ + RIGHT_PAREN = 605, /* RIGHT_PAREN */ + LEFT_BRACKET = 606, /* LEFT_BRACKET */ + RIGHT_BRACKET = 607, /* RIGHT_BRACKET */ + LEFT_BRACE = 608, /* LEFT_BRACE */ + RIGHT_BRACE = 609, /* RIGHT_BRACE */ + DOT = 610, /* DOT */ + COMMA = 611, /* COMMA */ + COLON = 612, /* COLON */ + EQUAL = 613, /* EQUAL */ + SEMICOLON = 614, /* SEMICOLON */ + BANG = 615, /* BANG */ + DASH = 616, /* DASH */ + TILDE = 617, /* TILDE */ + PLUS = 618, /* PLUS */ + STAR = 619, /* STAR */ + SLASH = 620, /* SLASH */ + PERCENT = 621, /* PERCENT */ + LEFT_ANGLE = 622, /* LEFT_ANGLE */ + RIGHT_ANGLE = 623, /* RIGHT_ANGLE */ + VERTICAL_BAR = 624, /* VERTICAL_BAR */ + CARET = 625, /* CARET */ + AMPERSAND = 626, /* AMPERSAND */ + QUESTION = 627, /* QUESTION */ + INVARIANT = 628, /* INVARIANT */ + HIGH_PRECISION = 629, /* HIGH_PRECISION */ + MEDIUM_PRECISION = 630, /* MEDIUM_PRECISION */ + LOW_PRECISION = 631, /* LOW_PRECISION */ + PRECISION = 632, /* PRECISION */ + PACKED = 633, /* PACKED */ + RESOURCE = 634, /* RESOURCE */ + SUPERP = 635, /* SUPERP */ + FLOATCONSTANT = 636, /* FLOATCONSTANT */ + INTCONSTANT = 637, /* INTCONSTANT */ + UINTCONSTANT = 638, /* UINTCONSTANT */ + BOOLCONSTANT = 639, /* BOOLCONSTANT */ + IDENTIFIER = 640, /* IDENTIFIER */ + TYPE_NAME = 641, /* TYPE_NAME */ + CENTROID = 642, /* CENTROID */ + IN = 643, /* IN */ + OUT = 644, /* OUT */ + INOUT = 645, /* INOUT */ + STRUCT = 646, /* STRUCT */ + VOID = 647, /* VOID */ + WHILE = 648, /* WHILE */ + BREAK = 649, /* BREAK */ + CONTINUE = 650, /* CONTINUE */ + DO = 651, /* DO */ + ELSE = 652, /* ELSE */ + FOR = 653, /* FOR */ + IF = 654, /* IF */ + DISCARD = 655, /* DISCARD */ + RETURN = 656, /* RETURN */ + SWITCH = 657, /* SWITCH */ + CASE = 658, /* CASE */ + DEFAULT = 659, /* DEFAULT */ + TERMINATE_INVOCATION = 660, /* TERMINATE_INVOCATION */ + TERMINATE_RAY = 661, /* TERMINATE_RAY */ + IGNORE_INTERSECTION = 662, /* IGNORE_INTERSECTION */ + UNIFORM = 663, /* UNIFORM */ + SHARED = 664, /* SHARED */ + BUFFER = 665, /* BUFFER */ + FLAT = 666, /* FLAT */ + SMOOTH = 667, /* SMOOTH */ + LAYOUT = 668, /* LAYOUT */ + DOUBLECONSTANT = 669, /* DOUBLECONSTANT */ + INT16CONSTANT = 670, /* INT16CONSTANT */ + UINT16CONSTANT = 671, /* UINT16CONSTANT */ + FLOAT16CONSTANT = 672, /* FLOAT16CONSTANT */ + INT32CONSTANT = 673, /* INT32CONSTANT */ + UINT32CONSTANT = 674, /* UINT32CONSTANT */ + INT64CONSTANT = 675, /* INT64CONSTANT */ + UINT64CONSTANT = 676, /* UINT64CONSTANT */ + SUBROUTINE = 677, /* SUBROUTINE */ + DEMOTE = 678, /* DEMOTE */ + PAYLOADNV = 679, /* PAYLOADNV */ + PAYLOADINNV = 680, /* PAYLOADINNV */ + HITATTRNV = 681, /* HITATTRNV */ + CALLDATANV = 682, /* CALLDATANV */ + CALLDATAINNV = 683, /* CALLDATAINNV */ + PAYLOADEXT = 684, /* PAYLOADEXT */ + PAYLOADINEXT = 685, /* PAYLOADINEXT */ + HITATTREXT = 686, /* HITATTREXT */ + CALLDATAEXT = 687, /* CALLDATAEXT */ + CALLDATAINEXT = 688, /* CALLDATAINEXT */ + PATCH = 689, /* PATCH */ + SAMPLE = 690, /* SAMPLE */ + NONUNIFORM = 691, /* NONUNIFORM */ + COHERENT = 692, /* COHERENT */ + VOLATILE = 693, /* VOLATILE */ + RESTRICT = 694, /* RESTRICT */ + READONLY = 695, /* READONLY */ + WRITEONLY = 696, /* WRITEONLY */ + DEVICECOHERENT = 697, /* DEVICECOHERENT */ + QUEUEFAMILYCOHERENT = 698, /* QUEUEFAMILYCOHERENT */ + WORKGROUPCOHERENT = 699, /* WORKGROUPCOHERENT */ + SUBGROUPCOHERENT = 700, /* SUBGROUPCOHERENT */ + NONPRIVATE = 701, /* NONPRIVATE */ + SHADERCALLCOHERENT = 702, /* SHADERCALLCOHERENT */ + NOPERSPECTIVE = 703, /* NOPERSPECTIVE */ + EXPLICITINTERPAMD = 704, /* EXPLICITINTERPAMD */ + PERVERTEXNV = 705, /* PERVERTEXNV */ + PERPRIMITIVENV = 706, /* PERPRIMITIVENV */ + PERVIEWNV = 707, /* PERVIEWNV */ + PERTASKNV = 708, /* PERTASKNV */ + PRECISE = 709 /* PRECISE */ }; + typedef enum yytokentype yytoken_kind_t; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - union YYSTYPE { -#line 71 "MachineIndependent/glslang.y" /* yacc.c:1909 */ +#line 97 "MachineIndependent/glslang.y" struct { glslang::TSourceLoc loc; @@ -480,6 +537,9 @@ union YYSTYPE glslang::TIntermNodePair nodePair; glslang::TIntermTyped* intermTypedNode; glslang::TAttributes* attributes; + glslang::TSpirvRequirement* spirvReq; + glslang::TSpirvInstruction* spirvInst; + glslang::TSpirvTypeParameters* spirvTypeParams; }; union { glslang::TPublicType type; @@ -490,11 +550,12 @@ union YYSTYPE glslang::TArraySizes* arraySizes; glslang::TIdentifierList* identifierList; }; + glslang::TArraySizes* typeParameters; } interm; -#line 496 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ -}; +#line 557 "MachineIndependent/glslang_tab.cpp.h" +}; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/intermOut.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/intermOut.cpp index f74b90a..a0fade1 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/intermOut.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/intermOut.cpp @@ -2,6 +2,7 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -35,6 +36,8 @@ // POSSIBILITY OF SUCH DAMAGE. // +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + #include "localintermediate.h" #include "../Include/InfoSink.h" @@ -43,6 +46,7 @@ #else #include #endif +#include namespace { @@ -173,7 +177,7 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) case EOpIndexIndirect: out.debug << "indirect index"; break; case EOpIndexDirectStruct: { - bool reference = node->getLeft()->getType().getBasicType() == EbtReference; + bool reference = node->getLeft()->getType().isReference(); const TTypeList *members = reference ? node->getLeft()->getType().getReferentType()->getStruct() : node->getLeft()->getType().getStruct(); out.debug << (*members)[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName(); out.debug << ": direct index for structure"; break; @@ -210,6 +214,13 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) case EOpLogicalXor: out.debug << "logical-xor"; break; case EOpLogicalAnd: out.debug << "logical-and"; break; + case EOpAbsDifference: out.debug << "absoluteDifference"; break; + case EOpAddSaturate: out.debug << "addSaturate"; break; + case EOpSubSaturate: out.debug << "subtractSaturate"; break; + case EOpAverage: out.debug << "average"; break; + case EOpAverageRounded: out.debug << "averageRounded"; break; + case EOpMul32x16: out.debug << "multiply32x16"; break; + default: out.debug << ""; } @@ -236,6 +247,7 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpPostDecrement: out.debug << "Post-Decrement"; break; case EOpPreIncrement: out.debug << "Pre-Increment"; break; case EOpPreDecrement: out.debug << "Pre-Decrement"; break; + case EOpCopyObject: out.debug << "copy object"; break; // * -> bool case EOpConvInt8ToBool: out.debug << "Convert int8_t to bool"; break; @@ -426,6 +438,9 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpConvUint64ToPtr: out.debug << "Convert uint64_t to pointer"; break; case EOpConvPtrToUint64: out.debug << "Convert pointer to uint64_t"; break; + case EOpConvUint64ToAccStruct: out.debug << "Convert uint64_t to acceleration structure"; break; + case EOpConvUvec2ToAccStruct: out.debug << "Convert uvec2 to acceleration strucuture "; break; + case EOpRadians: out.debug << "radians"; break; case EOpDegrees: out.debug << "degrees"; break; case EOpSin: out.debug << "sine"; break; @@ -553,6 +568,9 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpFindLSB: out.debug << "findLSB"; break; case EOpFindMSB: out.debug << "findMSB"; break; + case EOpCountLeadingZeros: out.debug << "countLeadingZeros"; break; + case EOpCountTrailingZeros: out.debug << "countTrailingZeros"; break; + case EOpNoise: out.debug << "noise"; break; case EOpBallot: out.debug << "ballot"; break; @@ -613,7 +631,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break; case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break; -#ifdef NV_EXTENSIONS case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break; case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break; case EOpSubgroupPartitionedMul: out.debug << "subgroupPartitionedMulNV"; break; @@ -636,7 +653,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpSubgroupPartitionedExclusiveAnd: out.debug << "subgroupPartitionedExclusiveAndNV"; break; case EOpSubgroupPartitionedExclusiveOr: out.debug << "subgroupPartitionedExclusiveOrNV"; break; case EOpSubgroupPartitionedExclusiveXor: out.debug << "subgroupPartitionedExclusiveXorNV"; break; -#endif case EOpClip: out.debug << "clip"; break; case EOpIsFinite: out.debug << "isfinite"; break; @@ -646,7 +662,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break; -#ifdef AMD_EXTENSIONS case EOpMinInvocations: out.debug << "minInvocations"; break; case EOpMaxInvocations: out.debug << "maxInvocations"; break; case EOpAddInvocations: out.debug << "addInvocations"; break; @@ -675,13 +690,16 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break; case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break; -#endif case EOpSubpassLoad: out.debug << "subpassLoad"; break; case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; case EOpConstructReference: out.debug << "Construct reference type"; break; +#ifndef GLSLANG_WEB + case EOpSpirvInst: out.debug << "spirv_instruction"; break; +#endif + default: out.debug.message(EPrefixError, "Bad unary op"); } @@ -817,6 +835,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpConstructStruct: out.debug << "Construct structure"; break; case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break; case EOpConstructReference: out.debug << "Construct reference"; break; + case EOpConstructCooperativeMatrix: out.debug << "Construct cooperative matrix"; break; + case EOpConstructAccStruct: out.debug << "Construct acceleration structure"; break; case EOpLessThan: out.debug << "Compare Less Than"; break; case EOpGreaterThan: out.debug << "Compare Greater Than"; break; @@ -860,7 +880,6 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpReadInvocation: out.debug << "readInvocation"; break; -#ifdef AMD_EXTENSIONS case EOpSwizzleInvocations: out.debug << "swizzleInvocations"; break; case EOpSwizzleInvocationsMasked: out.debug << "swizzleInvocationsMasked"; break; case EOpWriteInvocation: out.debug << "writeInvocation"; break; @@ -868,11 +887,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpMin3: out.debug << "min3"; break; case EOpMax3: out.debug << "max3"; break; case EOpMid3: out.debug << "mid3"; break; - case EOpTime: out.debug << "time"; break; -#endif case EOpAtomicAdd: out.debug << "AtomicAdd"; break; + case EOpAtomicSubtract: out.debug << "AtomicSubtract"; break; case EOpAtomicMin: out.debug << "AtomicMin"; break; case EOpAtomicMax: out.debug << "AtomicMax"; break; case EOpAtomicAnd: out.debug << "AtomicAnd"; break; @@ -907,10 +925,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break; case EOpImageAtomicLoad: out.debug << "imageAtomicLoad"; break; case EOpImageAtomicStore: out.debug << "imageAtomicStore"; break; -#ifdef AMD_EXTENSIONS case EOpImageLoadLod: out.debug << "imageLoadLod"; break; case EOpImageStoreLod: out.debug << "imageStoreLod"; break; -#endif case EOpTextureQuerySize: out.debug << "textureSize"; break; case EOpTextureQueryLod: out.debug << "textureQueryLod"; break; @@ -937,11 +953,9 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpTextureOffsetClamp: out.debug << "textureOffsetClamp"; break; case EOpTextureGradClamp: out.debug << "textureGradClamp"; break; case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break; -#ifdef AMD_EXTENSIONS case EOpTextureGatherLod: out.debug << "textureGatherLod"; break; case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break; case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break; -#endif case EOpSparseTexture: out.debug << "sparseTexture"; break; case EOpSparseTextureOffset: out.debug << "sparseTextureOffset"; break; @@ -959,19 +973,15 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpSparseTextureOffsetClamp: out.debug << "sparseTextureOffsetClamp"; break; case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break; case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break; -#ifdef AMD_EXTENSIONS case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break; case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break; case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break; case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break; -#endif -#ifdef NV_EXTENSIONS case EOpImageSampleFootprintNV: out.debug << "imageSampleFootprintNV"; break; case EOpImageSampleFootprintClampNV: out.debug << "imageSampleFootprintClampNV"; break; case EOpImageSampleFootprintLodNV: out.debug << "imageSampleFootprintLodNV"; break; case EOpImageSampleFootprintGradNV: out.debug << "imageSampleFootprintGradNV"; break; case EOpImageSampleFootprintGradClampNV: out.debug << "mageSampleFootprintGradClampNV"; break; -#endif case EOpAddCarry: out.debug << "addCarry"; break; case EOpSubBorrow: out.debug << "subBorrow"; break; case EOpUMulExtended: out.debug << "uMulExtended"; break; @@ -985,9 +995,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break; case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break; -#ifdef AMD_EXTENSIONS case EOpInterpolateAtVertex: out.debug << "interpolateAtVertex"; break; -#endif case EOpSinCos: out.debug << "sincos"; break; case EOpGenMul: out.debug << "mul"; break; @@ -1054,16 +1062,77 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break; case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break; + case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break; + case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break; + case EOpSubgroupPartitionedMul: out.debug << "subgroupPartitionedMulNV"; break; + case EOpSubgroupPartitionedMin: out.debug << "subgroupPartitionedMinNV"; break; + case EOpSubgroupPartitionedMax: out.debug << "subgroupPartitionedMaxNV"; break; + case EOpSubgroupPartitionedAnd: out.debug << "subgroupPartitionedAndNV"; break; + case EOpSubgroupPartitionedOr: out.debug << "subgroupPartitionedOrNV"; break; + case EOpSubgroupPartitionedXor: out.debug << "subgroupPartitionedXorNV"; break; + case EOpSubgroupPartitionedInclusiveAdd: out.debug << "subgroupPartitionedInclusiveAddNV"; break; + case EOpSubgroupPartitionedInclusiveMul: out.debug << "subgroupPartitionedInclusiveMulNV"; break; + case EOpSubgroupPartitionedInclusiveMin: out.debug << "subgroupPartitionedInclusiveMinNV"; break; + case EOpSubgroupPartitionedInclusiveMax: out.debug << "subgroupPartitionedInclusiveMaxNV"; break; + case EOpSubgroupPartitionedInclusiveAnd: out.debug << "subgroupPartitionedInclusiveAndNV"; break; + case EOpSubgroupPartitionedInclusiveOr: out.debug << "subgroupPartitionedInclusiveOrNV"; break; + case EOpSubgroupPartitionedInclusiveXor: out.debug << "subgroupPartitionedInclusiveXorNV"; break; + case EOpSubgroupPartitionedExclusiveAdd: out.debug << "subgroupPartitionedExclusiveAddNV"; break; + case EOpSubgroupPartitionedExclusiveMul: out.debug << "subgroupPartitionedExclusiveMulNV"; break; + case EOpSubgroupPartitionedExclusiveMin: out.debug << "subgroupPartitionedExclusiveMinNV"; break; + case EOpSubgroupPartitionedExclusiveMax: out.debug << "subgroupPartitionedExclusiveMaxNV"; break; + case EOpSubgroupPartitionedExclusiveAnd: out.debug << "subgroupPartitionedExclusiveAndNV"; break; + case EOpSubgroupPartitionedExclusiveOr: out.debug << "subgroupPartitionedExclusiveOrNV"; break; + case EOpSubgroupPartitionedExclusiveXor: out.debug << "subgroupPartitionedExclusiveXorNV"; break; + case EOpSubpassLoad: out.debug << "subpassLoad"; break; case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; -#ifdef NV_EXTENSIONS case EOpTraceNV: out.debug << "traceNV"; break; - case EOpReportIntersectionNV: out.debug << "reportIntersectionNV"; break; + case EOpTraceRayMotionNV: out.debug << "traceRayMotionNV"; break; + case EOpTraceKHR: out.debug << "traceRayKHR"; break; + case EOpReportIntersection: out.debug << "reportIntersectionNV"; break; case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break; + case EOpIgnoreIntersectionKHR: out.debug << "ignoreIntersectionKHR"; break; case EOpTerminateRayNV: out.debug << "terminateRayNV"; break; + case EOpTerminateRayKHR: out.debug << "terminateRayKHR"; break; case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break; + case EOpExecuteCallableKHR: out.debug << "executeCallableKHR"; break; case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break; + + case EOpRayQueryInitialize: out.debug << "rayQueryInitializeEXT"; break; + case EOpRayQueryTerminate: out.debug << "rayQueryTerminateEXT"; break; + case EOpRayQueryGenerateIntersection: out.debug << "rayQueryGenerateIntersectionEXT"; break; + case EOpRayQueryConfirmIntersection: out.debug << "rayQueryConfirmIntersectionEXT"; break; + case EOpRayQueryProceed: out.debug << "rayQueryProceedEXT"; break; + case EOpRayQueryGetIntersectionType: out.debug << "rayQueryGetIntersectionTypeEXT"; break; + case EOpRayQueryGetRayTMin: out.debug << "rayQueryGetRayTMinEXT"; break; + case EOpRayQueryGetRayFlags: out.debug << "rayQueryGetRayFlagsEXT"; break; + case EOpRayQueryGetIntersectionT: out.debug << "rayQueryGetIntersectionTEXT"; break; + case EOpRayQueryGetIntersectionInstanceCustomIndex: out.debug << "rayQueryGetIntersectionInstanceCustomIndexEXT"; break; + case EOpRayQueryGetIntersectionInstanceId: out.debug << "rayQueryGetIntersectionInstanceIdEXT"; break; + case EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: out.debug << "rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT"; break; + case EOpRayQueryGetIntersectionGeometryIndex: out.debug << "rayQueryGetIntersectionGeometryIndexEXT"; break; + case EOpRayQueryGetIntersectionPrimitiveIndex: out.debug << "rayQueryGetIntersectionPrimitiveIndexEXT"; break; + case EOpRayQueryGetIntersectionBarycentrics: out.debug << "rayQueryGetIntersectionBarycentricsEXT"; break; + case EOpRayQueryGetIntersectionFrontFace: out.debug << "rayQueryGetIntersectionFrontFaceEXT"; break; + case EOpRayQueryGetIntersectionCandidateAABBOpaque: out.debug << "rayQueryGetIntersectionCandidateAABBOpaqueEXT"; break; + case EOpRayQueryGetIntersectionObjectRayDirection: out.debug << "rayQueryGetIntersectionObjectRayDirectionEXT"; break; + case EOpRayQueryGetIntersectionObjectRayOrigin: out.debug << "rayQueryGetIntersectionObjectRayOriginEXT"; break; + case EOpRayQueryGetWorldRayDirection: out.debug << "rayQueryGetWorldRayDirectionEXT"; break; + case EOpRayQueryGetWorldRayOrigin: out.debug << "rayQueryGetWorldRayOriginEXT"; break; + case EOpRayQueryGetIntersectionObjectToWorld: out.debug << "rayQueryGetIntersectionObjectToWorldEXT"; break; + case EOpRayQueryGetIntersectionWorldToObject: out.debug << "rayQueryGetIntersectionWorldToObjectEXT"; break; + + case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break; + case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break; + case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break; + + case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break; + case EOpDebugPrintf: out.debug << "Debug printf"; break; + +#ifndef GLSLANG_WEB + case EOpSpirvInst: out.debug << "spirv_instruction"; break; #endif default: out.debug.message(EPrefixError, "Bad aggregation op"); @@ -1157,8 +1226,11 @@ static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraO switch (extra) { case TOutputTraverser::BinaryDoubleOutput: { + uint64_t b; + static_assert(sizeof(b) == sizeof(value), "sizeof(uint64_t) != sizeof(double)"); + memcpy(&b, &value, sizeof(b)); + out.debug << " : "; - long long b = *reinterpret_cast(&value); for (size_t i = 0; i < 8 * sizeof(value); ++i, ++b) { out.debug << ((b & 0x8000000000000000) != 0 ? "1" : "0"); b <<= 1; @@ -1267,6 +1339,9 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const out.debug << buf << "\n"; } break; + case EbtString: + out.debug << "\"" << constUnion[i].getSConst()->c_str() << "\"\n"; + break; default: out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc()); break; @@ -1352,13 +1427,17 @@ bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node) OutputTreeText(out, node, depth); switch (node->getFlowOp()) { - case EOpKill: out.debug << "Branch: Kill"; break; - case EOpBreak: out.debug << "Branch: Break"; break; - case EOpContinue: out.debug << "Branch: Continue"; break; - case EOpReturn: out.debug << "Branch: Return"; break; - case EOpCase: out.debug << "case: "; break; - case EOpDefault: out.debug << "default: "; break; - default: out.debug << "Branch: Unknown Branch"; break; + case EOpKill: out.debug << "Branch: Kill"; break; + case EOpTerminateInvocation: out.debug << "Branch: TerminateInvocation"; break; + case EOpIgnoreIntersectionKHR: out.debug << "Branch: IgnoreIntersectionKHR"; break; + case EOpTerminateRayKHR: out.debug << "Branch: TerminateRayKHR"; break; + case EOpBreak: out.debug << "Branch: Break"; break; + case EOpContinue: out.debug << "Branch: Continue"; break; + case EOpReturn: out.debug << "Branch: Return"; break; + case EOpCase: out.debug << "case: "; break; + case EOpDemote: out.debug << "Demote"; break; + case EOpDefault: out.debug << "default: "; break; + default: out.debug << "Branch: Unknown Branch"; break; } if (node->getExpression()) { @@ -1417,6 +1496,9 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) if (xfbMode) infoSink.debug << "in xfb mode\n"; + if (getSubgroupUniformControlFlow()) + infoSink.debug << "subgroup_uniform_control_flow\n"; + switch (language) { case EShLangVertex: break; @@ -1467,18 +1549,17 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) } infoSink.debug << "\n"; } + if (interlockOrdering != EioNone) + infoSink.debug << "interlock ordering = " << TQualifier::getInterlockOrderingString(interlockOrdering) << "\n"; break; -#ifdef NV_EXTENSIONS case EShLangMeshNV: infoSink.debug << "max_vertices = " << vertices << "\n"; infoSink.debug << "max_primitives = " << primitives << "\n"; infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n"; // Fall through - case EShLangTaskNV: // Fall through -#endif case EShLangCompute: infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n"; { @@ -1507,3 +1588,5 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) } } // end namespace glslang + +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/iomapper.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/iomapper.cpp index 46c7558..7e12864 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/iomapper.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/iomapper.cpp @@ -33,16 +33,15 @@ // POSSIBILITY OF SUCH DAMAGE. // +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + #include "../Include/Common.h" #include "../Include/InfoSink.h" -#include "iomapper.h" -#include "LiveTraverser.h" -#include "localintermediate.h" +#include "../Include/Types.h" #include "gl_types.h" - -#include -#include +#include "iomapper.h" +#include "SymbolTable.h" // // Map IO bindings. @@ -61,60 +60,9 @@ // c. implicit dead bindings are left un-bound. // - namespace glslang { -struct TVarEntryInfo -{ - int id; - TIntermSymbol* symbol; - bool live; - int newBinding; - int newSet; - int newLocation; - int newComponent; - int newIndex; - - struct TOrderById - { - inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) - { - return l.id < r.id; - } - }; - - struct TOrderByPriority - { - // ordering: - // 1) has both binding and set - // 2) has binding but no set - // 3) has no binding but set - // 4) has no binding and no set - inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) - { - const TQualifier& lq = l.symbol->getQualifier(); - const TQualifier& rq = r.symbol->getQualifier(); - - // simple rules: - // has binding gives 2 points - // has set gives 1 point - // who has the most points is more important. - int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); - int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); - - if (lPoints == rPoints) - return l.id < r.id; - return lPoints > rPoints; - } - }; -}; - - - -typedef std::vector TVarLiveMap; - -class TVarGatherTraverser : public TLiveTraverser -{ +class TVarGatherTraverser : public TLiveTraverser { public: TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList) : TLiveTraverser(i, traverseDeadCode, true, true, false) @@ -124,7 +72,6 @@ public: { } - virtual void visitSymbol(TIntermSymbol* base) { TVarLiveMap* target = nullptr; @@ -132,16 +79,22 @@ public: target = &inputList; else if (base->getQualifier().storage == EvqVaryingOut) target = &outputList; - else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().layoutPushConstant) + else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant()) target = &uniformList; + // If a global is being visited, then we should also traverse it incase it's evaluation + // ends up visiting inputs we want to tag as live + else if (base->getQualifier().storage == EvqGlobal) + addGlobalReference(base->getAccessName()); if (target) { - TVarEntryInfo ent = { base->getId(), base, !traverseAll }; - TVarLiveMap::iterator at = std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById()); - if (at != target->end() && at->id == ent.id) - at->live = at->live || !traverseAll; // update live state + TVarEntryInfo ent = {base->getId(), base, ! traverseAll}; + ent.stage = intermediate.getStage(); + TVarLiveMap::iterator at = target->find( + ent.symbol->getAccessName()); // std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById()); + if (at != target->end() && at->second.id == ent.id) + at->second.live = at->second.live || ! traverseAll; // update live state else - target->insert(at, ent); + (*target)[ent.symbol->getAccessName()] = ent; } } @@ -162,9 +115,7 @@ public: { } - - virtual void visitSymbol(TIntermSymbol* base) - { + virtual void visitSymbol(TIntermSymbol* base) { const TVarLiveMap* source; if (base->getQualifier().storage == EvqVaryingIn) source = &inputList; @@ -176,23 +127,24 @@ public: return; TVarEntryInfo ent = { base->getId() }; - TVarLiveMap::const_iterator at = std::lower_bound(source->begin(), source->end(), ent, TVarEntryInfo::TOrderById()); + // Fix a defect, when block has no instance name, we need to find its block name + TVarLiveMap::const_iterator at = source->find(base->getAccessName()); if (at == source->end()) return; - if (at->id != ent.id) + if (at->second.id != ent.id) return; - if (at->newBinding != -1) - base->getWritableType().getQualifier().layoutBinding = at->newBinding; - if (at->newSet != -1) - base->getWritableType().getQualifier().layoutSet = at->newSet; - if (at->newLocation != -1) - base->getWritableType().getQualifier().layoutLocation = at->newLocation; - if (at->newComponent != -1) - base->getWritableType().getQualifier().layoutComponent = at->newComponent; - if (at->newIndex != -1) - base->getWritableType().getQualifier().layoutIndex = at->newIndex; + if (at->second.newBinding != -1) + base->getWritableType().getQualifier().layoutBinding = at->second.newBinding; + if (at->second.newSet != -1) + base->getWritableType().getQualifier().layoutSet = at->second.newSet; + if (at->second.newLocation != -1) + base->getWritableType().getQualifier().layoutLocation = at->second.newLocation; + if (at->second.newComponent != -1) + base->getWritableType().getQualifier().layoutComponent = at->second.newComponent; + if (at->second.newIndex != -1) + base->getWritableType().getQualifier().layoutIndex = at->second.newIndex; } private: @@ -210,126 +162,135 @@ struct TNotifyUniformAdaptor , resolver(r) { } - inline void operator()(TVarEntryInfo& ent) + + inline void operator()(std::pair& entKey) { - resolver.notifyBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); + resolver.notifyBinding(stage, entKey.second); } + private: - TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&); + TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&) = delete; }; struct TNotifyInOutAdaptor { EShLanguage stage; TIoMapResolver& resolver; - inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r) + inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r) : stage(s) , resolver(r) { } - inline void operator()(TVarEntryInfo& ent) + + inline void operator()(std::pair& entKey) { - resolver.notifyInOut(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); + resolver.notifyInOut(entKey.second.stage, entKey.second); } + private: - TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&); + TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&) = delete; }; -struct TResolverUniformAdaptor -{ - TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm) +struct TResolverUniformAdaptor { + TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TVarLiveMap* uniform[EShLangCount], TInfoSink& i, bool& e) : stage(s) , resolver(r) , infoSink(i) , error(e) - , intermediate(interm) { + memcpy(uniformVarMap, uniform, EShLangCount * (sizeof(TVarLiveMap*))); } - inline void operator()(TVarEntryInfo& ent) - { + inline void operator()(std::pair& entKey) { + TVarEntryInfo& ent = entKey.second; ent.newLocation = -1; ent.newComponent = -1; ent.newBinding = -1; ent.newSet = -1; ent.newIndex = -1; - const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), - ent.live); + const bool isValid = resolver.validateBinding(stage, ent); if (isValid) { - ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), - ent.live); - ent.newSet = resolver.resolveSet(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); - ent.newLocation = resolver.resolveUniformLocation(stage, ent.symbol->getName().c_str(), - ent.symbol->getType(), ent.live); + resolver.resolveSet(ent.stage, ent); + resolver.resolveBinding(ent.stage, ent); + resolver.resolveUniformLocation(ent.stage, ent); if (ent.newBinding != -1) { if (ent.newBinding >= int(TQualifier::layoutBindingEnd)) { - TString err = "mapped binding out of range: " + ent.symbol->getName(); + TString err = "mapped binding out of range: " + entKey.first; infoSink.info.message(EPrefixInternalError, err.c_str()); error = true; } + + if (ent.symbol->getQualifier().hasBinding()) { + for (uint32_t idx = EShLangVertex; idx < EShLangCount; ++idx) { + if (idx == ent.stage || uniformVarMap[idx] == nullptr) + continue; + auto entKey2 = uniformVarMap[idx]->find(entKey.first); + if (entKey2 != uniformVarMap[idx]->end()) { + entKey2->second.newBinding = ent.newBinding; + } + } + } } if (ent.newSet != -1) { if (ent.newSet >= int(TQualifier::layoutSetEnd)) { - TString err = "mapped set out of range: " + ent.symbol->getName(); + TString err = "mapped set out of range: " + entKey.first; infoSink.info.message(EPrefixInternalError, err.c_str()); error = true; } + if (ent.symbol->getQualifier().hasSet()) { + for (uint32_t idx = EShLangVertex; idx < EShLangCount; ++idx) { + if ((idx == stage) || (uniformVarMap[idx] == nullptr)) + continue; + auto entKey2 = uniformVarMap[idx]->find(entKey.first); + if (entKey2 != uniformVarMap[idx]->end()) { + entKey2->second.newSet = ent.newSet; + } + } + } } } else { - TString errorMsg = "Invalid binding: " + ent.symbol->getName(); + TString errorMsg = "Invalid binding: " + entKey.first; infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); error = true; } } + inline void setStage(EShLanguage s) { stage = s; } + EShLanguage stage; TIoMapResolver& resolver; TInfoSink& infoSink; bool& error; - TIntermediate& intermediate; - + TVarLiveMap* uniformVarMap[EShLangCount]; private: - TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&); + TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&) = delete; }; -struct TResolverInOutAdaptor -{ - TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm) +struct TResolverInOutAdaptor { + TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e) : stage(s) , resolver(r) , infoSink(i) , error(e) - , intermediate(interm) { } - inline void operator()(TVarEntryInfo& ent) + inline void operator()(std::pair& entKey) { + TVarEntryInfo& ent = entKey.second; ent.newLocation = -1; ent.newComponent = -1; ent.newBinding = -1; ent.newSet = -1; ent.newIndex = -1; - const bool isValid = resolver.validateInOut(stage, - ent.symbol->getName().c_str(), - ent.symbol->getType(), - ent.live); + const bool isValid = resolver.validateInOut(ent.stage, ent); if (isValid) { - ent.newLocation = resolver.resolveInOutLocation(stage, - ent.symbol->getName().c_str(), - ent.symbol->getType(), - ent.live); - ent.newComponent = resolver.resolveInOutComponent(stage, - ent.symbol->getName().c_str(), - ent.symbol->getType(), - ent.live); - ent.newIndex = resolver.resolveInOutIndex(stage, - ent.symbol->getName().c_str(), - ent.symbol->getType(), - ent.live); + resolver.resolveInOutLocation(stage, ent); + resolver.resolveInOutComponent(stage, ent); + resolver.resolveInOutIndex(stage, ent); } else { TString errorMsg; if (ent.symbol->getType().getQualifier().semanticName != nullptr) { @@ -344,219 +305,951 @@ struct TResolverInOutAdaptor } } + inline void setStage(EShLanguage s) { stage = s; } + EShLanguage stage; TIoMapResolver& resolver; TInfoSink& infoSink; bool& error; - TIntermediate& intermediate; private: - TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&); + TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&) = delete; }; -// Base class for shared TIoMapResolver services, used by several derivations. -struct TDefaultIoResolverBase : public glslang::TIoMapResolver +// The class is used for reserving explicit uniform locations and ubo/ssbo/opaque bindings +// xxTODO: maybe this logic should be moved into the resolver's "validateInOut" and "validateUniform" + +struct TSymbolValidater { - TDefaultIoResolverBase(const TIntermediate &intermediate) : - intermediate(intermediate), - nextUniformLocation(intermediate.getUniformLocationBase()), - nextInputLocation(0), - nextOutputLocation(0) - { } + TSymbolValidater(TIoMapResolver& r, TInfoSink& i, TVarLiveMap* in[EShLangCount], TVarLiveMap* out[EShLangCount], + TVarLiveMap* uniform[EShLangCount], bool& hadError, EProfile profile, int version) + : resolver(r) + , infoSink(i) + , hadError(hadError) + , profile(profile) + , version(version) + { + memcpy(inVarMaps, in, EShLangCount * (sizeof(TVarLiveMap*))); + memcpy(outVarMaps, out, EShLangCount * (sizeof(TVarLiveMap*))); + memcpy(uniformVarMap, uniform, EShLangCount * (sizeof(TVarLiveMap*))); - int getBaseBinding(TResourceType res, unsigned int set) const { - return selectBaseBinding(intermediate.getShiftBinding(res), - intermediate.getShiftBindingForSet(res, set)); + std::map anonymousMemberMap; + std::vector usedUniformLocation; + std::vector usedUniformName; + usedUniformLocation.clear(); + usedUniformName.clear(); + for (int i = 0; i < EShLangCount; i++) { + if (uniformVarMap[i]) { + for (auto uniformVar : *uniformVarMap[i]) + { + TIntermSymbol* pSymbol = uniformVar.second.symbol; + TQualifier qualifier = uniformVar.second.symbol->getQualifier(); + TString symbolName = pSymbol->getAccessName(); + + // All the uniform needs multi-stage location check (block/default) + int uniformLocation = qualifier.layoutLocation; + + if (uniformLocation != TQualifier::layoutLocationEnd) { + // Total size of current uniform, could be block, struct or other types. + int size = TIntermediate::computeTypeUniformLocationSize(pSymbol->getType()); + + TRange locationRange(uniformLocation, uniformLocation + size - 1); + + // Combine location and component ranges + int overlapLocation = -1; + bool diffLocation = false; + + // Check for collisions, except for vertex inputs on desktop targeting OpenGL + overlapLocation = checkLocationOverlap(locationRange, usedUniformLocation, symbolName, usedUniformName, diffLocation); + + // Overlap locations of uniforms, regardless of components (multi stages) + if (overlapLocation == -1) { + usedUniformLocation.push_back(locationRange); + usedUniformName.push_back(symbolName); + } + else if (overlapLocation >= 0) { + if (diffLocation == true) { + TString err = ("Uniform location should be equal for same uniforms: " +std::to_string(overlapLocation)).c_str(); + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + break; + } + else { + TString err = ("Uniform location overlaps across stages: " + std::to_string(overlapLocation)).c_str(); + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + break; + } + } + } + + if ((uniformVar.second.symbol->getBasicType() == EbtBlock) && + IsAnonymous(uniformVar.second.symbol->getName())) + { + auto blockType = uniformVar.second.symbol->getType().getStruct(); + for (size_t memberIdx = 0; memberIdx < blockType->size(); ++memberIdx) { + auto memberName = (*blockType)[memberIdx].type->getFieldName(); + if (anonymousMemberMap.find(memberName) != anonymousMemberMap.end()) + { + if (anonymousMemberMap[memberName] != uniformVar.second.symbol->getType().getTypeName()) + { + TString err = "Invalid block member name: " + memberName; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + break; + } + } + else + { + anonymousMemberMap[memberName] = uniformVar.second.symbol->getType().getTypeName(); + } + } + } + if (hadError) + break; + } + } + } } - const std::vector& getResourceSetBinding() const { return intermediate.getResourceSetBinding(); } - - bool doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); } - bool doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); } - - typedef std::vector TSlotSet; - typedef std::unordered_map TSlotSetMap; - TSlotSetMap slots; - - TSlotSet::iterator findSlot(int set, int slot) + // In case we need to new an intermediate, which costs too much + int checkLocationOverlap(const TRange& locationRange, std::vector& usedUniformLocation, const TString symbolName, std::vector& usedUniformName, bool& diffLocation) { - return std::lower_bound(slots[set].begin(), slots[set].end(), slot); - } - - bool checkEmpty(int set, int slot) - { - TSlotSet::iterator at = findSlot(set, slot); - return !(at != slots[set].end() && *at == slot); - } - - int reserveSlot(int set, int slot, int size = 1) - { - TSlotSet::iterator at = findSlot(set, slot); - - // tolerate aliasing, by not double-recording aliases - // (policy about appropriateness of the alias is higher up) - for (int i = 0; i < size; i++) { - if (at == slots[set].end() || *at != slot + i) - at = slots[set].insert(at, slot + i); - ++at; + for (size_t r = 0; r < usedUniformLocation.size(); ++r) { + if (usedUniformName[r] == symbolName) { + diffLocation = true; + return (usedUniformLocation[r].start == locationRange.start && + usedUniformLocation[r].last == locationRange.last) + ? -2 : std::max(locationRange.start, usedUniformLocation[r].start); + } + if (locationRange.overlap(usedUniformLocation[r])) { + // there is a collision; pick one + return std::max(locationRange.start, usedUniformLocation[r].start); + } } - return slot; + return -1; // no collision } - int getFreeSlot(int set, int base, int size = 1) - { - TSlotSet::iterator at = findSlot(set, base); - if (at == slots[set].end()) - return reserveSlot(set, base, size); + inline void operator()(std::pair& entKey) { + TVarEntryInfo& ent1 = entKey.second; + TIntermSymbol* base = ent1.symbol; + const TType& type = ent1.symbol->getType(); + const TString& name = entKey.first; + TString mangleName1, mangleName2; + EShLanguage stage = ent1.stage; + EShLanguage preStage, currentStage, nextStage; - // look for a big enough gap - for (; at != slots[set].end(); ++at) { - if (*at - base >= size) + preStage = EShLangCount; + for (int i = stage - 1; i >= 0; i--) { + if (inVarMaps[i] != nullptr) { + preStage = static_cast(i); break; - base = *at + 1; + } } - return reserveSlot(set, base, size); - } - - virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0; - - virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0; - - int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override - { - if (type.getQualifier().hasSet()) - return type.getQualifier().layoutSet; - - // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN) - if (getResourceSetBinding().size() == 1) - return atoi(getResourceSetBinding()[0].c_str()); - - return 0; - } - int resolveUniformLocation(EShLanguage /*stage*/, const char* name, const glslang::TType& type, bool /*is_live*/) override - { - // kick out of not doing this - if (!doAutoLocationMapping()) - return -1; - - // no locations added if already present, a built-in variable, a block, or an opaque - if (type.getQualifier().hasLocation() || type.isBuiltIn() || - type.getBasicType() == EbtBlock || - type.getBasicType() == EbtAtomicUint || - (type.containsOpaque() && intermediate.getSpv().openGl == 0)) - return -1; - - // no locations on blocks of built-in variables - if (type.isStruct()) { - if (type.getStruct()->size() < 1) - return -1; - if ((*type.getStruct())[0].type->isBuiltIn()) - return -1; + currentStage = stage; + nextStage = EShLangCount; + for (int i = stage + 1; i < EShLangCount; i++) { + if (inVarMaps[i] != nullptr) { + nextStage = static_cast(i); + break; + } } - int location = intermediate.getUniformLocationOverride(name); - if (location != -1) - return location; - - location = nextUniformLocation; - - nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type); - - return location; - } - bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override - { - return true; - } - int resolveInOutLocation(EShLanguage stage, const char* /*name*/, const TType& type, bool /*is_live*/) override - { - // kick out of not doing this - if (!doAutoLocationMapping()) - return -1; - - // no locations added if already present, or a built-in variable - if (type.getQualifier().hasLocation() || type.isBuiltIn()) - return -1; - - // no locations on blocks of built-in variables - if (type.isStruct()) { - if (type.getStruct()->size() < 1) - return -1; - if ((*type.getStruct())[0].type->isBuiltIn()) - return -1; - } - - // point to the right input or output location counter - int& nextLocation = type.getQualifier().isPipeInput() ? nextInputLocation : nextOutputLocation; - - // Placeholder. This does not do proper cross-stage lining up, nor - // work with mixed location/no-location declarations. - int location = nextLocation; - int typeLocationSize; - // Don’t take into account the outer-most array if the stage’s - // interface is automatically an array. if (type.getQualifier().isArrayedIo(stage)) { - TType elementType(type, 0); - typeLocationSize = TIntermediate::computeTypeLocationSize(elementType, stage); + TType subType(type, 0); + subType.appendMangledName(mangleName1); } else { - typeLocationSize = TIntermediate::computeTypeLocationSize(type, stage); + type.appendMangledName(mangleName1); } - nextLocation += typeLocationSize; - return location; + + // basic checking that symbols match + // more extensive checking in the link stage + if (base->getQualifier().storage == EvqVaryingIn) { + // validate stage in; + if (preStage == EShLangCount) + return; + if (TSymbolTable::isBuiltInSymbol(base->getId())) + return; + if (outVarMaps[preStage] != nullptr) { + auto ent2 = outVarMaps[preStage]->find(name); + uint32_t location = base->getType().getQualifier().layoutLocation; + if (ent2 == outVarMaps[preStage]->end() && + location != glslang::TQualifier::layoutLocationEnd) { + for (auto var = outVarMaps[preStage]->begin(); var != ent2; var++) { + if (var->second.symbol->getType().getQualifier().layoutLocation == location) { + ent2 = var; + break; + } + } + } + if (ent2 != outVarMaps[preStage]->end()) { + auto& type1 = base->getType(); + auto& type2 = ent2->second.symbol->getType(); + hadError = hadError || typeCheck(&type1, &type2, name.c_str(), false); + if (ent2->second.symbol->getType().getQualifier().isArrayedIo(preStage)) { + TType subType(ent2->second.symbol->getType(), 0); + subType.appendMangledName(mangleName2); + } else { + ent2->second.symbol->getType().appendMangledName(mangleName2); + } + + if (mangleName1 == mangleName2) { + // For ES 3.0 only, other versions have no such restrictions + // According to ES 3.0 spec: The type and presence of the interpolation qualifiers and + // storage qualifiers of variables with the same name declared in all linked shaders must + // match, otherwise the link command will fail. + if (profile == EEsProfile && version == 300) { + // Don't need to check smooth qualifier, as it uses the default interpolation mode + if (ent1.stage == EShLangFragment && type1.isBuiltIn() == false) { + if (type1.getQualifier().flat != type2.getQualifier().flat || + type1.getQualifier().nopersp != type2.getQualifier().nopersp) { + TString err = "Interpolation qualifier mismatch : " + entKey.first; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + } + } + } + return; + } + else { + TString err = "Invalid In/Out variable type : " + entKey.first; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + } + } + else if (!base->getType().isBuiltIn()) { + // According to spec: A link error is generated if any statically referenced input variable + // or block does not have a matching output + if (profile == EEsProfile && ent1.live) { + hadError = true; + TString errorStr = name + ": not been declare as a output variable in pre shader stage."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + } + } + return; + } + } else if (base->getQualifier().storage == EvqVaryingOut) { + // validate stage out; + if (nextStage == EShLangCount) + return; + if (TSymbolTable::isBuiltInSymbol(base->getId())) + return; + if (inVarMaps[nextStage] != nullptr) { + auto ent2 = inVarMaps[nextStage]->find(name); + if (ent2 != inVarMaps[nextStage]->end()) { + if (ent2->second.symbol->getType().getQualifier().isArrayedIo(nextStage)) { + TType subType(ent2->second.symbol->getType(), 0); + subType.appendMangledName(mangleName2); + } else { + ent2->second.symbol->getType().appendMangledName(mangleName2); + } + if (mangleName1 == mangleName2) + return; + else { + TString err = "Invalid In/Out variable type : " + entKey.first; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + } + } + return; + } + } else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant()) { + // validate uniform type; + for (int i = 0; i < EShLangCount; i++) { + if (i != currentStage && outVarMaps[i] != nullptr) { + auto ent2 = uniformVarMap[i]->find(name); + if (ent2 != uniformVarMap[i]->end()) { + ent2->second.symbol->getType().appendMangledName(mangleName2); + if (mangleName1 != mangleName2) { + ent2->second.symbol->getType().sameElementType(type); + TString err = "Invalid Uniform variable type : " + entKey.first; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + } + mangleName2.clear(); + + // validate instance name of blocks + if (hadError == false && + base->getType().getBasicType() == EbtBlock && + IsAnonymous(base->getName()) != IsAnonymous(ent2->second.symbol->getName())) { + TString err = "Matched uniform block names must also either all be lacking " + "an instance name or all having an instance name: " + entKey.first; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + } + + // validate uniform block member qualifier and member names + auto& type1 = base->getType(); + auto& type2 = ent2->second.symbol->getType(); + if (hadError == false && base->getType().getBasicType() == EbtBlock) { + hadError = hadError || typeCheck(&type1, &type2, name.c_str(), true); + } + else { + hadError = hadError || typeCheck(&type1, &type2, name.c_str(), false); + } + } + else if (base->getBasicType() == EbtBlock) + { + if (IsAnonymous(base->getName())) + { + // The name of anonymous block member can't same with default uniform variable. + auto blockType1 = base->getType().getStruct(); + for (size_t memberIdx = 0; memberIdx < blockType1->size(); ++memberIdx) { + auto memberName = (*blockType1)[memberIdx].type->getFieldName(); + if (uniformVarMap[i]->find(memberName) != uniformVarMap[i]->end()) + { + TString err = "Invalid Uniform variable name : " + memberName; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + break; + } + } + } + } + } + } + } } - int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + + TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], *uniformVarMap[EShLangCount]; + + // Use for mark current shader stage for resolver + TIoMapResolver& resolver; + TInfoSink& infoSink; + bool& hadError; + EProfile profile; + int version; + +private: + TSymbolValidater& operator=(TSymbolValidater&) = delete; + + bool qualifierCheck(const TType* const type1, const TType* const type2, const std::string& name, bool isBlock) { - return -1; + bool hasError = false; + const TQualifier& qualifier1 = type1->getQualifier(); + const TQualifier& qualifier2 = type2->getQualifier(); + + if (((isBlock == false) && + (type1->getQualifier().storage == EvqUniform && type2->getQualifier().storage == EvqUniform)) || + (type1->getQualifier().storage == EvqGlobal && type2->getQualifier().storage == EvqGlobal)) { + if (qualifier1.precision != qualifier2.precision) { + hasError = true; + std::string errorStr = name + ": have precision conflict cross stage."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + } + if (qualifier1.hasFormat() && qualifier2.hasFormat()) { + if (qualifier1.layoutFormat != qualifier2.layoutFormat) { + hasError = true; + std::string errorStr = name + ": have layout format conflict cross stage."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + } + + } + } + + if (isBlock == true) { + if (qualifier1.layoutPacking != qualifier2.layoutPacking) { + hasError = true; + std::string errorStr = name + ": have layoutPacking conflict cross stage."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + } + if (qualifier1.layoutMatrix != qualifier2.layoutMatrix) { + hasError = true; + std::string errorStr = name + ": have layoutMatrix conflict cross stage."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + } + if (qualifier1.layoutOffset != qualifier2.layoutOffset) { + hasError = true; + std::string errorStr = name + ": have layoutOffset conflict cross stage."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + } + if (qualifier1.layoutAlign != qualifier2.layoutAlign) { + hasError = true; + std::string errorStr = name + ": have layoutAlign conflict cross stage."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + } + } + + return hasError; } - int resolveInOutIndex(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + + bool typeCheck(const TType* const type1, const TType* const type2, const std::string& name, bool isBlock) { - return -1; - } + bool hasError = false; + if (!(type1->isStruct() && type2->isStruct())) { + hasError = hasError || qualifierCheck(type1, type2, name, isBlock); + } + else { + if (type1->getBasicType() == EbtBlock && type2->getBasicType() == EbtBlock) + isBlock = true; + const TTypeList* typeList1 = type1->getStruct(); + const TTypeList* typeList2 = type2->getStruct(); - void notifyBinding(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {} - void notifyInOut(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {} - void endNotifications(EShLanguage) override {} - void beginNotifications(EShLanguage) override {} - void beginResolve(EShLanguage) override {} - void endResolve(EShLanguage) override {} + std::string newName = name; + size_t memberCount = typeList1->size(); + size_t index2 = 0; + for (size_t index = 0; index < memberCount; index++, index2++) { + // Skip inactive member + if (typeList1->at(index).type->getBasicType() == EbtVoid) + continue; + while (index2 < typeList2->size() && typeList2->at(index2).type->getBasicType() == EbtVoid) { + ++index2; + } -protected: - TDefaultIoResolverBase(TDefaultIoResolverBase&); - TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&); + // TypeList1 has more members in list + if (index2 == typeList2->size()) { + std::string errorStr = name + ": struct mismatch."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + hasError = true; + break; + } - const TIntermediate &intermediate; - int nextUniformLocation; - int nextInputLocation; - int nextOutputLocation; + if (typeList1->at(index).type->getFieldName() != typeList2->at(index2).type->getFieldName()) { + std::string errorStr = name + ": member name mismatch."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + hasError = true; + } + else { + newName = typeList1->at(index).type->getFieldName().c_str(); + } + hasError = hasError || typeCheck(typeList1->at(index).type, typeList2->at(index2).type, newName, isBlock); + } - // Return descriptor set specific base if there is one, and the generic base otherwise. - int selectBaseBinding(int base, int descriptorSetBase) const { - return descriptorSetBase != -1 ? descriptorSetBase : base; - } - - static int getLayoutSet(const glslang::TType& type) { - if (type.getQualifier().hasSet()) - return type.getQualifier().layoutSet; - else - return 0; - } - - static bool isSamplerType(const glslang::TType& type) { - return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler(); - } - - static bool isTextureType(const glslang::TType& type) { - return (type.getBasicType() == glslang::EbtSampler && - (type.getSampler().isTexture() || type.getSampler().isSubpass())); - } - - static bool isUboType(const glslang::TType& type) { - return type.getQualifier().storage == EvqUniform; + while (index2 < typeList2->size()) + { + // TypeList2 has more members + if (typeList2->at(index2).type->getBasicType() != EbtVoid) { + std::string errorStr = name + ": struct mismatch."; + infoSink.info.message(EPrefixError, errorStr.c_str()); + hasError = true; + break; + } + ++index2; + } + } + return hasError; } }; +struct TSlotCollector { + TSlotCollector(TIoMapResolver& r, TInfoSink& i) : resolver(r), infoSink(i) { } + + inline void operator()(std::pair& entKey) { + resolver.reserverStorageSlot(entKey.second, infoSink); + resolver.reserverResourceSlot(entKey.second, infoSink); + } + TIoMapResolver& resolver; + TInfoSink& infoSink; + +private: + TSlotCollector& operator=(TSlotCollector&) = delete; +}; + +TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate) + : intermediate(intermediate) + , nextUniformLocation(intermediate.getUniformLocationBase()) + , nextInputLocation(0) + , nextOutputLocation(0) +{ + memset(stageMask, false, sizeof(bool) * (EShLangCount + 1)); + memset(stageIntermediates, 0, sizeof(TIntermediate*) * (EShLangCount)); + stageIntermediates[intermediate.getStage()] = &intermediate; +} + +int TDefaultIoResolverBase::getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const { + return stageIntermediates[stage] ? selectBaseBinding(stageIntermediates[stage]->getShiftBinding(res), stageIntermediates[stage]->getShiftBindingForSet(res, set)) + : selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set)); +} + +const std::vector& TDefaultIoResolverBase::getResourceSetBinding(EShLanguage stage) const { + return stageIntermediates[stage] ? stageIntermediates[stage]->getResourceSetBinding() + : intermediate.getResourceSetBinding(); +} + +bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); } + +bool TDefaultIoResolverBase::doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); } + +TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int set, int slot) { + return std::lower_bound(slots[set].begin(), slots[set].end(), slot); +} + +bool TDefaultIoResolverBase::checkEmpty(int set, int slot) { + TSlotSet::iterator at = findSlot(set, slot); + return ! (at != slots[set].end() && *at == slot); +} + +int TDefaultIoResolverBase::reserveSlot(int set, int slot, int size) { + TSlotSet::iterator at = findSlot(set, slot); + // tolerate aliasing, by not double-recording aliases + // (policy about appropriateness of the alias is higher up) + for (int i = 0; i < size; i++) { + if (at == slots[set].end() || *at != slot + i) + at = slots[set].insert(at, slot + i); + ++at; + } + return slot; +} + +int TDefaultIoResolverBase::getFreeSlot(int set, int base, int size) { + TSlotSet::iterator at = findSlot(set, base); + if (at == slots[set].end()) + return reserveSlot(set, base, size); + // look for a big enough gap + for (; at != slots[set].end(); ++at) { + if (*at - base >= size) + break; + base = *at + 1; + } + return reserveSlot(set, base, size); +} + +int TDefaultIoResolverBase::resolveSet(EShLanguage stage, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + if (type.getQualifier().hasSet()) { + return ent.newSet = type.getQualifier().layoutSet; + } + // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN) + if (getResourceSetBinding(stage).size() == 1) { + return ent.newSet = atoi(getResourceSetBinding(stage)[0].c_str()); + } + return ent.newSet = 0; +} + +int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + const char* name = ent.symbol->getAccessName().c_str(); + // kick out of not doing this + if (! doAutoLocationMapping()) { + return ent.newLocation = -1; + } + // no locations added if already present, a built-in variable, a block, or an opaque + if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock || + type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) { + return ent.newLocation = -1; + } + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) { + return ent.newLocation = -1; + } + if ((*type.getStruct())[0].type->isBuiltIn()) { + return ent.newLocation = -1; + } + } + int location = intermediate.getUniformLocationOverride(name); + if (location != -1) { + return ent.newLocation = location; + } + location = nextUniformLocation; + nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type); + return ent.newLocation = location; +} + +int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + // kick out of not doing this + if (! doAutoLocationMapping()) { + return ent.newLocation = -1; + } + + // no locations added if already present, or a built-in variable + if (type.getQualifier().hasLocation() || type.isBuiltIn()) { + return ent.newLocation = -1; + } + + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) { + return ent.newLocation = -1; + } + if ((*type.getStruct())[0].type->isBuiltIn()) { + return ent.newLocation = -1; + } + } + // point to the right input or output location counter + int& nextLocation = type.getQualifier().isPipeInput() ? nextInputLocation : nextOutputLocation; + // Placeholder. This does not do proper cross-stage lining up, nor + // work with mixed location/no-location declarations. + int location = nextLocation; + int typeLocationSize; + // Don’t take into account the outer-most array if the stage’s + // interface is automatically an array. + typeLocationSize = computeTypeLocationSize(type, stage); + nextLocation += typeLocationSize; + return ent.newLocation = location; +} + +int TDefaultIoResolverBase::resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) { + return ent.newComponent = -1; +} + +int TDefaultIoResolverBase::resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) { return ent.newIndex = -1; } + +uint32_t TDefaultIoResolverBase::computeTypeLocationSize(const TType& type, EShLanguage stage) { + int typeLocationSize; + // Don’t take into account the outer-most array if the stage’s + // interface is automatically an array. + if (type.getQualifier().isArrayedIo(stage)) { + TType elementType(type, 0); + typeLocationSize = TIntermediate::computeTypeLocationSize(elementType, stage); + } else { + typeLocationSize = TIntermediate::computeTypeLocationSize(type, stage); + } + return typeLocationSize; +} + +//TDefaultGlslIoResolver +TResourceType TDefaultGlslIoResolver::getResourceType(const glslang::TType& type) { + if (isImageType(type)) { + return EResImage; + } + if (isTextureType(type)) { + return EResTexture; + } + if (isSsboType(type)) { + return EResSsbo; + } + if (isSamplerType(type)) { + return EResSampler; + } + if (isUboType(type)) { + return EResUbo; + } + return EResCount; +} + +TDefaultGlslIoResolver::TDefaultGlslIoResolver(const TIntermediate& intermediate) + : TDefaultIoResolverBase(intermediate) + , preStage(EShLangCount) + , currentStage(EShLangCount) +{ } + +int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getAccessName(); + if (currentStage != stage) { + preStage = currentStage; + currentStage = stage; + } + // kick out if not doing this + if (! doAutoLocationMapping()) { + return ent.newLocation = -1; + } + // expand the location to each element if the symbol is a struct or array + if (type.getQualifier().hasLocation()) { + return ent.newLocation = type.getQualifier().layoutLocation; + } + // no locations added if already present, or a built-in variable + if (type.isBuiltIn()) { + return ent.newLocation = -1; + } + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) { + return ent.newLocation = -1; + } + if ((*type.getStruct())[0].type->isBuiltIn()) { + return ent.newLocation = -1; + } + } + int typeLocationSize = computeTypeLocationSize(type, stage); + int location = type.getQualifier().layoutLocation; + bool hasLocation = false; + EShLanguage keyStage(EShLangCount); + TStorageQualifier storage; + storage = EvqInOut; + if (type.getQualifier().isPipeInput()) { + // If this symbol is a input, search pre stage's out + keyStage = preStage; + } + if (type.getQualifier().isPipeOutput()) { + // If this symbol is a output, search next stage's in + keyStage = currentStage; + } + // The in/out in current stage is not declared with location, but it is possible declared + // with explicit location in other stages, find the storageSlotMap firstly to check whether + // the in/out has location + int resourceKey = buildStorageKey(keyStage, storage); + if (! storageSlotMap[resourceKey].empty()) { + TVarSlotMap::iterator iter = storageSlotMap[resourceKey].find(name); + if (iter != storageSlotMap[resourceKey].end()) { + // If interface resource be found, set it has location and this symbol's new location + // equal the symbol's explicit location declaration in pre or next stage. + // + // vs: out vec4 a; + // fs: layout(..., location = 3,...) in vec4 a; + hasLocation = true; + location = iter->second; + // if we want deal like that: + // vs: layout(location=4) out vec4 a; + // out vec4 b; + // + // fs: in vec4 a; + // layout(location = 4) in vec4 b; + // we need retraverse the map. + } + if (! hasLocation) { + // If interface resource note found, It's mean the location in two stage are both implicit declarat. + // So we should find a new slot for this interface. + // + // vs: out vec4 a; + // fs: in vec4 a; + location = getFreeSlot(resourceKey, 0, typeLocationSize); + storageSlotMap[resourceKey][name] = location; + } + } else { + // the first interface declarated in a program. + TVarSlotMap varSlotMap; + location = getFreeSlot(resourceKey, 0, typeLocationSize); + varSlotMap[name] = location; + storageSlotMap[resourceKey] = varSlotMap; + } + //Update location + return ent.newLocation = location; +} + +int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getAccessName(); + // kick out of not doing this + if (! doAutoLocationMapping()) { + return ent.newLocation = -1; + } + // expand the location to each element if the symbol is a struct or array + if (type.getQualifier().hasLocation() && (type.isStruct() || type.isArray())) { + return ent.newLocation = type.getQualifier().layoutLocation; + } else { + // no locations added if already present, a built-in variable, a block, or an opaque + if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock || + type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) { + return ent.newLocation = -1; + } + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) { + return ent.newLocation = -1; + } + if ((*type.getStruct())[0].type->isBuiltIn()) { + return ent.newLocation = -1; + } + } + } + int location = intermediate.getUniformLocationOverride(name.c_str()); + if (location != -1) { + return ent.newLocation = location; + } + + int size = TIntermediate::computeTypeUniformLocationSize(type); + + // The uniform in current stage is not declared with location, but it is possible declared + // with explicit location in other stages, find the storageSlotMap firstly to check whether + // the uniform has location + bool hasLocation = false; + int resourceKey = buildStorageKey(EShLangCount, EvqUniform); + TVarSlotMap& slotMap = storageSlotMap[resourceKey]; + // Check dose shader program has uniform resource + if (! slotMap.empty()) { + // If uniform resource not empty, try find a same name uniform + TVarSlotMap::iterator iter = slotMap.find(name); + if (iter != slotMap.end()) { + // If uniform resource be found, set it has location and this symbol's new location + // equal the uniform's explicit location declaration in other stage. + // + // vs: uniform vec4 a; + // fs: layout(..., location = 3,...) uniform vec4 a; + hasLocation = true; + location = iter->second; + } + if (! hasLocation) { + // No explicit location declaration in other stage. + // So we should find a new slot for this uniform. + // + // vs: uniform vec4 a; + // fs: uniform vec4 a; + location = getFreeSlot(resourceKey, 0, computeTypeLocationSize(type, currentStage)); + storageSlotMap[resourceKey][name] = location; + } + } else { + // the first uniform declaration in a program. + TVarSlotMap varSlotMap; + location = getFreeSlot(resourceKey, 0, size); + varSlotMap[name] = location; + storageSlotMap[resourceKey] = varSlotMap; + } + return ent.newLocation = location; +} + +int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getAccessName(); + // On OpenGL arrays of opaque types take a separate binding for each element + int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1; + TResourceType resource = getResourceType(type); + // don't need to handle uniform symbol, it will be handled in resolveUniformLocation + if (resource == EResUbo && type.getBasicType() != EbtBlock) { + return ent.newBinding = -1; + } + // There is no 'set' qualifier in OpenGL shading language, each resource has its own + // binding name space, so remap the 'set' to resource type which make each resource + // binding is valid from 0 to MAX_XXRESOURCE_BINDINGS + int set = intermediate.getSpv().openGl != 0 ? resource : ent.newSet; + int resourceKey = set; + if (resource < EResCount) { + if (type.getQualifier().hasBinding()) { + int newBinding = reserveSlot(resourceKey, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings); + return ent.newBinding = newBinding; + + } else { + // The resource in current stage is not declared with binding, but it is possible declared + // with explicit binding in other stages, find the resourceSlotMap firstly to check whether + // the resource has binding, don't need to allocate if it already has a binding + bool hasBinding = false; + ent.newBinding = -1; // leave as -1 if it isn't set below + + if (! resourceSlotMap[resourceKey].empty()) { + TVarSlotMap::iterator iter = resourceSlotMap[resourceKey].find(name); + if (iter != resourceSlotMap[resourceKey].end()) { + hasBinding = true; + ent.newBinding = iter->second; + } + } + if (!hasBinding && (ent.live && doAutoBindingMapping())) { + // find free slot, the caller did make sure it passes all vars with binding + // first and now all are passed that do not have a binding and needs one + int binding = getFreeSlot(resourceKey, getBaseBinding(stage, resource, set), numBindings); + resourceSlotMap[resourceKey][name] = binding; + ent.newBinding = binding; + } + return ent.newBinding; + } + } + return ent.newBinding = -1; +} + +void TDefaultGlslIoResolver::beginResolve(EShLanguage stage) { + // reset stage state + if (stage == EShLangCount) + preStage = currentStage = stage; + // update stage state + else if (currentStage != stage) { + preStage = currentStage; + currentStage = stage; + } +} + +void TDefaultGlslIoResolver::endResolve(EShLanguage /*stage*/) { + // TODO nothing +} + +void TDefaultGlslIoResolver::beginCollect(EShLanguage stage) { + // reset stage state + if (stage == EShLangCount) + preStage = currentStage = stage; + // update stage state + else if (currentStage != stage) { + preStage = currentStage; + currentStage = stage; + } +} + +void TDefaultGlslIoResolver::endCollect(EShLanguage /*stage*/) { + // TODO nothing +} + +void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getAccessName(); + TStorageQualifier storage = type.getQualifier().storage; + EShLanguage stage(EShLangCount); + switch (storage) { + case EvqUniform: + if (type.getBasicType() != EbtBlock && type.getQualifier().hasLocation()) { + // + // Reserve the slots for the uniforms who has explicit location + int storageKey = buildStorageKey(EShLangCount, EvqUniform); + int location = type.getQualifier().layoutLocation; + TVarSlotMap& varSlotMap = storageSlotMap[storageKey]; + TVarSlotMap::iterator iter = varSlotMap.find(name); + if (iter == varSlotMap.end()) { + int numLocations = TIntermediate::computeTypeUniformLocationSize(type); + reserveSlot(storageKey, location, numLocations); + varSlotMap[name] = location; + } else { + // Allocate location by name for OpenGL driver, so the uniform in different + // stages should be declared with the same location + if (iter->second != location) { + TString errorMsg = "Invalid location: " + name; + infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + hasError = true; + } + } + } + break; + case EvqVaryingIn: + case EvqVaryingOut: + // + // Reserve the slots for the inout who has explicit location + if (type.getQualifier().hasLocation()) { + stage = storage == EvqVaryingIn ? preStage : stage; + stage = storage == EvqVaryingOut ? currentStage : stage; + int storageKey = buildStorageKey(stage, EvqInOut); + int location = type.getQualifier().layoutLocation; + TVarSlotMap& varSlotMap = storageSlotMap[storageKey]; + TVarSlotMap::iterator iter = varSlotMap.find(name); + if (iter == varSlotMap.end()) { + int numLocations = TIntermediate::computeTypeUniformLocationSize(type); + reserveSlot(storageKey, location, numLocations); + varSlotMap[name] = location; + } else { + // Allocate location by name for OpenGL driver, so the uniform in different + // stages should be declared with the same location + if (iter->second != location) { + TString errorMsg = "Invalid location: " + name; + infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + hasError = true; + } + } + } + break; + default: + break; + } +} + +void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getAccessName(); + TResourceType resource = getResourceType(type); + int set = intermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent); + int resourceKey = set; + + if (type.getQualifier().hasBinding()) { + TVarSlotMap& varSlotMap = resourceSlotMap[resourceKey]; + TVarSlotMap::iterator iter = varSlotMap.find(name); + int binding = type.getQualifier().layoutBinding + getBaseBinding(ent.stage, resource, set); + + if (iter == varSlotMap.end()) { + // Reserve the slots for the ubo, ssbo and opaques who has explicit binding + int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1; + varSlotMap[name] = binding; + reserveSlot(resourceKey, binding, numBindings); + } else { + // Allocate binding by name for OpenGL driver, so the resource in different + // stages should be declared with the same binding + if (iter->second != binding) { + TString errorMsg = "Invalid binding: " + name; + infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + hasError = true; + } + } + } +} + +//TDefaultGlslIoResolver end + /* * Basic implementation of glslang::TIoMapResolver that replaces the * previous offset behavior. @@ -567,69 +1260,51 @@ protected: /* * Default resolver */ -struct TDefaultIoResolver : public TDefaultIoResolverBase -{ - TDefaultIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { } +struct TDefaultIoResolver : public TDefaultIoResolverBase { + TDefaultIoResolver(const TIntermediate& intermediate) : TDefaultIoResolverBase(intermediate) { } - bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override - { - return true; + bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; } + + TResourceType getResourceType(const glslang::TType& type) override { + if (isImageType(type)) { + return EResImage; + } + if (isTextureType(type)) { + return EResTexture; + } + if (isSsboType(type)) { + return EResSsbo; + } + if (isSamplerType(type)) { + return EResSampler; + } + if (isUboType(type)) { + return EResUbo; + } + return EResCount; } - int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override - { + int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) override { + const TType& type = ent.symbol->getType(); const int set = getLayoutSet(type); // On OpenGL arrays of opaque types take a seperate binding for each element int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1; - - if (type.getQualifier().hasBinding()) { - if (isImageType(type)) - return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding, numBindings); - - if (isTextureType(type)) - return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding, numBindings); - - if (isSsboType(type)) - return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding, numBindings); - - if (isSamplerType(type)) - return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding, numBindings); - - if (isUboType(type)) - return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding, numBindings); - } else if (is_live && doAutoBindingMapping()) { - // find free slot, the caller did make sure it passes all vars with binding - // first and now all are passed that do not have a binding and needs one - - if (isImageType(type)) - return getFreeSlot(set, getBaseBinding(EResImage, set), numBindings); - - if (isTextureType(type)) - return getFreeSlot(set, getBaseBinding(EResTexture, set), numBindings); - - if (isSsboType(type)) - return getFreeSlot(set, getBaseBinding(EResSsbo, set), numBindings); - - if (isSamplerType(type)) - return getFreeSlot(set, getBaseBinding(EResSampler, set), numBindings); - - if (isUboType(type)) - return getFreeSlot(set, getBaseBinding(EResUbo, set), numBindings); + TResourceType resource = getResourceType(type); + if (resource < EResCount) { + if (type.getQualifier().hasBinding()) { + return ent.newBinding = reserveSlot( + set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings); + } else if (ent.live && doAutoBindingMapping()) { + // find free slot, the caller did make sure it passes all vars with binding + // first and now all are passed that do not have a binding and needs one + return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set), numBindings); + } } - - return -1; - } - -protected: - static bool isImageType(const glslang::TType& type) { - return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage(); - } - - static bool isSsboType(const glslang::TType& type) { - return type.getQualifier().storage == EvqBuffer; + return ent.newBinding = -1; } }; +#ifdef ENABLE_HLSL /******************************************************************************** The following IO resolver maps types in HLSL register space, as follows: @@ -647,7 +1322,7 @@ t - for shader resource views (SRV) BYTEADDRESSBUFFER BUFFER TBUFFER - + s - for samplers SAMPLER SAMPLER1D @@ -673,98 +1348,69 @@ b - for constant buffer views (CBV) CBUFFER CONSTANTBUFFER ********************************************************************************/ -struct TDefaultHlslIoResolver : public TDefaultIoResolverBase -{ - TDefaultHlslIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { } +struct TDefaultHlslIoResolver : public TDefaultIoResolverBase { + TDefaultHlslIoResolver(const TIntermediate& intermediate) : TDefaultIoResolverBase(intermediate) { } - bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override - { - return true; - } + bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; } - int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override - { - const int set = getLayoutSet(type); - - if (type.getQualifier().hasBinding()) { - if (isUavType(type)) - return reserveSlot(set, getBaseBinding(EResUav, set) + type.getQualifier().layoutBinding); - - if (isSrvType(type)) - return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding); - - if (isSamplerType(type)) - return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding); - - if (isUboType(type)) - return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding); - } else if (is_live && doAutoBindingMapping()) { - // find free slot, the caller did make sure it passes all vars with binding - // first and now all are passed that do not have a binding and needs one - - if (isUavType(type)) - return getFreeSlot(set, getBaseBinding(EResUav, set)); - - if (isSrvType(type)) - return getFreeSlot(set, getBaseBinding(EResTexture, set)); - - if (isSamplerType(type)) - return getFreeSlot(set, getBaseBinding(EResSampler, set)); - - if (isUboType(type)) - return getFreeSlot(set, getBaseBinding(EResUbo, set)); + TResourceType getResourceType(const glslang::TType& type) override { + if (isUavType(type)) { + return EResUav; } - - return -1; + if (isSrvType(type)) { + return EResTexture; + } + if (isSamplerType(type)) { + return EResSampler; + } + if (isUboType(type)) { + return EResUbo; + } + return EResCount; } -protected: - // Return true if this is a SRV (shader resource view) type: - static bool isSrvType(const glslang::TType& type) { - return isTextureType(type) || type.getQualifier().storage == EvqBuffer; - } - - // Return true if this is a UAV (unordered access view) type: - static bool isUavType(const glslang::TType& type) { - if (type.getQualifier().readonly) - return false; - - return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) || - (type.getQualifier().storage == EvqBuffer); + int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) override { + const TType& type = ent.symbol->getType(); + const int set = getLayoutSet(type); + TResourceType resource = getResourceType(type); + if (resource < EResCount) { + if (type.getQualifier().hasBinding()) { + return ent.newBinding = reserveSlot(set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding); + } else if (ent.live && doAutoBindingMapping()) { + // find free slot, the caller did make sure it passes all vars with binding + // first and now all are passed that do not have a binding and needs one + return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set)); + } + } + return ent.newBinding = -1; } }; - +#endif // Map I/O variables to provided offsets, and make bindings for // unbound but live variables. // // Returns false if the input is too malformed to do this. -bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver) -{ - bool somethingToDo = !intermediate.getResourceSetBinding().empty() || - intermediate.getAutoMapBindings() || - intermediate.getAutoMapLocations(); - - for (int res = 0; res < EResCount; ++res) { - somethingToDo = somethingToDo || - (intermediate.getShiftBinding(TResourceType(res)) != 0) || - intermediate.hasShiftBindingForSet(TResourceType(res)); +bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSink& infoSink, TIoMapResolver* resolver) { + bool somethingToDo = ! intermediate.getResourceSetBinding().empty() || intermediate.getAutoMapBindings() || + intermediate.getAutoMapLocations(); + // Restrict the stricter condition to further check 'somethingToDo' only if 'somethingToDo' has not been set, reduce + // unnecessary or insignificant for-loop operation after 'somethingToDo' have been true. + for (int res = 0; (res < EResCount && !somethingToDo); ++res) { + somethingToDo = somethingToDo || (intermediate.getShiftBinding(TResourceType(res)) != 0) || + intermediate.hasShiftBindingForSet(TResourceType(res)); } - - if (!somethingToDo && resolver == nullptr) + if (! somethingToDo && resolver == nullptr) return true; - if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive()) return false; - TIntermNode* root = intermediate.getTreeRoot(); if (root == nullptr) return false; - // if no resolver is provided, use the default resolver with the given shifts and auto map settings TDefaultIoResolver defaultResolver(intermediate); +#ifdef ENABLE_HLSL TDefaultHlslIoResolver defaultHlslResolver(intermediate); - if (resolver == nullptr) { // TODO: use a passed in IO mapper for this if (intermediate.usingHlslIoMapping()) @@ -772,47 +1418,246 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi else resolver = &defaultResolver; } +#else + resolver = &defaultResolver; +#endif + resolver->addStage(stage, intermediate); TVarLiveMap inVarMap, outVarMap, uniformVarMap; + TVarLiveVector inVector, outVector, uniformVector; TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap); TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap); - root->traverse(&iter_binding_all); iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str()); - - while (!iter_binding_live.functions.empty()) { - TIntermNode* function = iter_binding_live.functions.back(); - iter_binding_live.functions.pop_back(); - function->traverse(&iter_binding_live); + while (! iter_binding_live.destinations.empty()) { + TIntermNode* destination = iter_binding_live.destinations.back(); + iter_binding_live.destinations.pop_back(); + destination->traverse(&iter_binding_live); } // sort entries by priority. see TVarEntryInfo::TOrderByPriority for info. - std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderByPriority()); - + for (auto& var : inVarMap) { inVector.push_back(var); } + std::sort(inVector.begin(), inVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + for (auto& var : outVarMap) { outVector.push_back(var); } + std::sort(outVector.begin(), outVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + for (auto& var : uniformVarMap) { uniformVector.push_back(var); } + std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); bool hadError = false; + TVarLiveMap* dummyUniformVarMap[EShLangCount] = {}; TNotifyInOutAdaptor inOutNotify(stage, *resolver); TNotifyUniformAdaptor uniformNotify(stage, *resolver); - TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError, intermediate); - TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError, intermediate); + TResolverUniformAdaptor uniformResolve(stage, *resolver, dummyUniformVarMap, infoSink, hadError); + TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError); resolver->beginNotifications(stage); - std::for_each(inVarMap.begin(), inVarMap.end(), inOutNotify); - std::for_each(outVarMap.begin(), outVarMap.end(), inOutNotify); - std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformNotify); + std::for_each(inVector.begin(), inVector.end(), inOutNotify); + std::for_each(outVector.begin(), outVector.end(), inOutNotify); + std::for_each(uniformVector.begin(), uniformVector.end(), uniformNotify); resolver->endNotifications(stage); resolver->beginResolve(stage); - std::for_each(inVarMap.begin(), inVarMap.end(), inOutResolve); - std::for_each(outVarMap.begin(), outVarMap.end(), inOutResolve); - std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformResolve); + for (auto& var : inVector) { inOutResolve(var); } + std::for_each(inVector.begin(), inVector.end(), [&inVarMap](TVarLivePair p) { + auto at = inVarMap.find(p.second.symbol->getAccessName()); + if (at != inVarMap.end() && p.second.id == at->second.id) + at->second = p.second; + }); + for (auto& var : outVector) { inOutResolve(var); } + std::for_each(outVector.begin(), outVector.end(), [&outVarMap](TVarLivePair p) { + auto at = outVarMap.find(p.second.symbol->getAccessName()); + if (at != outVarMap.end() && p.second.id == at->second.id) + at->second = p.second; + }); + std::for_each(uniformVector.begin(), uniformVector.end(), uniformResolve); + std::for_each(uniformVector.begin(), uniformVector.end(), [&uniformVarMap](TVarLivePair p) { + auto at = uniformVarMap.find(p.second.symbol->getAccessName()); + if (at != uniformVarMap.end() && p.second.id == at->second.id) + at->second = p.second; + }); resolver->endResolve(stage); - if (!hadError) { - // sort by id again, so we can use lower bound to find entries - std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderById()); TVarSetTraverser iter_iomap(intermediate, inVarMap, outVarMap, uniformVarMap); root->traverse(&iter_iomap); } - return !hadError; } +// Map I/O variables to provided offsets, and make bindings for +// unbound but live variables. +// +// Returns false if the input is too malformed to do this. +bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSink& infoSink, TIoMapResolver* resolver) { + bool somethingToDo = !intermediate.getResourceSetBinding().empty() || + intermediate.getAutoMapBindings() || + intermediate.getAutoMapLocations(); + + // Profile and version are use for symbol validate. + profile = intermediate.getProfile(); + version = intermediate.getVersion(); + + // Restrict the stricter condition to further check 'somethingToDo' only if 'somethingToDo' has not been set, reduce + // unnecessary or insignificant for-loop operation after 'somethingToDo' have been true. + for (int res = 0; (res < EResCount && !somethingToDo); ++res) { + somethingToDo = somethingToDo || (intermediate.getShiftBinding(TResourceType(res)) != 0) || + intermediate.hasShiftBindingForSet(TResourceType(res)); + } + if (! somethingToDo && resolver == nullptr) { + return true; + } + if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive()) { + return false; + } + TIntermNode* root = intermediate.getTreeRoot(); + if (root == nullptr) { + return false; + } + // if no resolver is provided, use the default resolver with the given shifts and auto map settings + TDefaultGlslIoResolver defaultResolver(intermediate); +#ifdef ENABLE_HLSL + TDefaultHlslIoResolver defaultHlslResolver(intermediate); + if (resolver == nullptr) { + // TODO: use a passed in IO mapper for this + if (intermediate.usingHlslIoMapping()) + resolver = &defaultHlslResolver; + else + resolver = &defaultResolver; + } +#else + if (resolver == nullptr) { + resolver = &defaultResolver; + } +#endif + resolver->addStage(stage, intermediate); + inVarMaps[stage] = new TVarLiveMap(); outVarMaps[stage] = new TVarLiveMap(); uniformVarMap[stage] = new TVarLiveMap(); + TVarGatherTraverser iter_binding_all(intermediate, true, *inVarMaps[stage], *outVarMaps[stage], + *uniformVarMap[stage]); + TVarGatherTraverser iter_binding_live(intermediate, false, *inVarMaps[stage], *outVarMaps[stage], + *uniformVarMap[stage]); + root->traverse(&iter_binding_all); + iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str()); + while (! iter_binding_live.destinations.empty()) { + TIntermNode* destination = iter_binding_live.destinations.back(); + iter_binding_live.destinations.pop_back(); + destination->traverse(&iter_binding_live); + } + + TNotifyInOutAdaptor inOutNotify(stage, *resolver); + TNotifyUniformAdaptor uniformNotify(stage, *resolver); + // Resolve current stage input symbol location with previous stage output here, + // uniform symbol, ubo, ssbo and opaque symbols are per-program resource, + // will resolve uniform symbol location and ubo/ssbo/opaque binding in doMap() + resolver->beginNotifications(stage); + std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), inOutNotify); + std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), inOutNotify); + std::for_each(uniformVarMap[stage]->begin(), uniformVarMap[stage]->end(), uniformNotify); + resolver->endNotifications(stage); + TSlotCollector slotCollector(*resolver, infoSink); + resolver->beginCollect(stage); + std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), slotCollector); + std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), slotCollector); + std::for_each(uniformVarMap[stage]->begin(), uniformVarMap[stage]->end(), slotCollector); + resolver->endCollect(stage); + intermediates[stage] = &intermediate; + return !hadError; +} + +bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) { + resolver->endResolve(EShLangCount); + if (!hadError) { + //Resolve uniform location, ubo/ssbo/opaque bindings across stages + TResolverUniformAdaptor uniformResolve(EShLangCount, *resolver, uniformVarMap, infoSink, hadError); + TResolverInOutAdaptor inOutResolve(EShLangCount, *resolver, infoSink, hadError); + TSymbolValidater symbolValidater(*resolver, infoSink, inVarMaps, + outVarMaps, uniformVarMap, hadError, profile, version); + + TVarLiveVector inVectors[EShLangCount]; + TVarLiveVector outVectors[EShLangCount]; + TVarLiveVector uniformVector; + + resolver->beginResolve(EShLangCount); + for (int stage = EShLangVertex; stage < EShLangCount; stage++) { + if (inVarMaps[stage] != nullptr) { + inOutResolve.setStage(EShLanguage(stage)); + + // copy vars into a sorted list + std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), + [&inVectors, stage](TVarLivePair p) { inVectors[stage].push_back(p); }); + std::sort(inVectors[stage].begin(), inVectors[stage].end(), + [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + + std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), + [&outVectors, stage](TVarLivePair p) { outVectors[stage].push_back(p); }); + std::sort(outVectors[stage].begin(), outVectors[stage].end(), + [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + + for (auto& var : inVectors[stage]) { symbolValidater(var); } + for (auto& var : inVectors[stage]) { inOutResolve(var); } + for (auto& var : outVectors[stage]) { symbolValidater(var); } + for (auto& var : outVectors[stage]) { inOutResolve(var); } + + // copy results back into maps + std::for_each(inVectors[stage].begin(), inVectors[stage].end(), + [this, stage](TVarLivePair p) { + auto at = inVarMaps[stage]->find(p.first); + if (at != inVarMaps[stage]->end()) + at->second = p.second; + }); + + std::for_each(outVectors[stage].begin(), outVectors[stage].end(), + [this, stage](TVarLivePair p) { + auto at = outVarMaps[stage]->find(p.first); + if (at != outVarMaps[stage]->end()) + at->second = p.second; + }); + + } + if (uniformVarMap[stage] != nullptr) { + uniformResolve.setStage(EShLanguage(stage)); + for (auto& var : *(uniformVarMap[stage])) { uniformVector.push_back(var); } + } + } + std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriorityAndLive()(p1.second, p2.second); + }); + for (auto& var : uniformVector) { symbolValidater(var); } + for (auto& var : uniformVector) { uniformResolve(var); } + std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + resolver->endResolve(EShLangCount); + for (size_t stage = 0; stage < EShLangCount; stage++) { + if (intermediates[stage] != nullptr) { + // traverse each stage, set new location to each input/output and unifom symbol, set new binding to + // ubo, ssbo and opaque symbols + TVarLiveMap** pUniformVarMap = uniformResolve.uniformVarMap; + std::for_each(uniformVector.begin(), uniformVector.end(), [pUniformVarMap, stage](TVarLivePair p) { + auto at = pUniformVarMap[stage]->find(p.second.symbol->getAccessName()); + if (at != pUniformVarMap[stage]->end() && at->second.id == p.second.id){ + int resolvedBinding = at->second.newBinding; + at->second = p.second; + if (resolvedBinding > 0) + at->second.newBinding = resolvedBinding; + } + }); + TVarSetTraverser iter_iomap(*intermediates[stage], *inVarMaps[stage], *outVarMaps[stage], + *uniformResolve.uniformVarMap[stage]); + intermediates[stage]->getTreeRoot()->traverse(&iter_iomap); + } + } + return !hadError; + } else { + return false; + } +} + } // end namespace glslang + +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/iomapper.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/iomapper.h index 5e0d439..07357c2 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/iomapper.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/iomapper.h @@ -33,11 +33,15 @@ // POSSIBILITY OF SUCH DAMAGE. // +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + #ifndef _IOMAPPER_INCLUDED #define _IOMAPPER_INCLUDED -#include "../Public/ShaderLang.h" - +#include +#include "LiveTraverser.h" +#include +#include // // A reflection database and its interface, consistent with the OpenGL API reflection queries. // @@ -47,17 +51,288 @@ class TInfoSink; namespace glslang { class TIntermediate; +struct TVarEntryInfo { + long long id; + TIntermSymbol* symbol; + bool live; + int newBinding; + int newSet; + int newLocation; + int newComponent; + int newIndex; + EShLanguage stage; + struct TOrderById { + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; } + }; + + struct TOrderByPriority { + // ordering: + // 1) has both binding and set + // 2) has binding but no set + // 3) has no binding but set + // 4) has no binding and no set + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { + const TQualifier& lq = l.symbol->getQualifier(); + const TQualifier& rq = r.symbol->getQualifier(); + + // simple rules: + // has binding gives 2 points + // has set gives 1 point + // who has the most points is more important. + int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); + int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); + + if (lPoints == rPoints) + return l.id < r.id; + return lPoints > rPoints; + } + }; + + struct TOrderByPriorityAndLive { + // ordering: + // 1) do live variables first + // 2) has both binding and set + // 3) has binding but no set + // 4) has no binding but set + // 5) has no binding and no set + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { + + const TQualifier& lq = l.symbol->getQualifier(); + const TQualifier& rq = r.symbol->getQualifier(); + + // simple rules: + // has binding gives 2 points + // has set gives 1 point + // who has the most points is more important. + int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); + int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); + + if (l.live != r.live) + return l.live > r.live; + + if (lPoints != rPoints) + return lPoints > rPoints; + + return l.id < r.id; + } + }; +}; + +// Base class for shared TIoMapResolver services, used by several derivations. +struct TDefaultIoResolverBase : public glslang::TIoMapResolver { +public: + TDefaultIoResolverBase(const TIntermediate& intermediate); + typedef std::vector TSlotSet; + typedef std::unordered_map TSlotSetMap; + + // grow the reflection stage by stage + void notifyBinding(EShLanguage, TVarEntryInfo& /*ent*/) override {} + void notifyInOut(EShLanguage, TVarEntryInfo& /*ent*/) override {} + void beginNotifications(EShLanguage) override {} + void endNotifications(EShLanguage) override {} + void beginResolve(EShLanguage) override {} + void endResolve(EShLanguage) override {} + void beginCollect(EShLanguage) override {} + void endCollect(EShLanguage) override {} + void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} + void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} + int getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const; + const std::vector& getResourceSetBinding(EShLanguage stage) const; + virtual TResourceType getResourceType(const glslang::TType& type) = 0; + bool doAutoBindingMapping() const; + bool doAutoLocationMapping() const; + TSlotSet::iterator findSlot(int set, int slot); + bool checkEmpty(int set, int slot); + bool validateInOut(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; } + int reserveSlot(int set, int slot, int size = 1); + int getFreeSlot(int set, int base, int size = 1); + int resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override; + int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + void addStage(EShLanguage stage, TIntermediate& stageIntermediate) override { + if (stage < EShLangCount) { + stageMask[stage] = true; + stageIntermediates[stage] = &stageIntermediate; + } + } + uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage); + + TSlotSetMap slots; + bool hasError = false; + +protected: + TDefaultIoResolverBase(TDefaultIoResolverBase&); + TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&); + const TIntermediate& intermediate; + int nextUniformLocation; + int nextInputLocation; + int nextOutputLocation; + bool stageMask[EShLangCount + 1]; + const TIntermediate* stageIntermediates[EShLangCount]; + + // Return descriptor set specific base if there is one, and the generic base otherwise. + int selectBaseBinding(int base, int descriptorSetBase) const { + return descriptorSetBase != -1 ? descriptorSetBase : base; + } + + static int getLayoutSet(const glslang::TType& type) { + if (type.getQualifier().hasSet()) + return type.getQualifier().layoutSet; + else + return 0; + } + + static bool isSamplerType(const glslang::TType& type) { + return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler(); + } + + static bool isTextureType(const glslang::TType& type) { + return (type.getBasicType() == glslang::EbtSampler && + (type.getSampler().isTexture() || type.getSampler().isSubpass())); + } + + static bool isUboType(const glslang::TType& type) { + return type.getQualifier().storage == EvqUniform; + } + + static bool isImageType(const glslang::TType& type) { + return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage(); + } + + static bool isSsboType(const glslang::TType& type) { + return type.getQualifier().storage == EvqBuffer; + } + + // Return true if this is a SRV (shader resource view) type: + static bool isSrvType(const glslang::TType& type) { + return isTextureType(type) || type.getQualifier().storage == EvqBuffer; + } + + // Return true if this is a UAV (unordered access view) type: + static bool isUavType(const glslang::TType& type) { + if (type.getQualifier().isReadOnly()) + return false; + return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) || + (type.getQualifier().storage == EvqBuffer); + } +}; + +// Default I/O resolver for OpenGL +struct TDefaultGlslIoResolver : public TDefaultIoResolverBase { +public: + typedef std::map TVarSlotMap; // + typedef std::map TSlotMap; // + TDefaultGlslIoResolver(const TIntermediate& intermediate); + bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; } + TResourceType getResourceType(const glslang::TType& type) override; + int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override; + int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + void beginResolve(EShLanguage /*stage*/) override; + void endResolve(EShLanguage stage) override; + void beginCollect(EShLanguage) override; + void endCollect(EShLanguage) override; + void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override; + void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override; + // in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol. + // We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage. + // if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key. + // Note: both stage and type must less then 0xffff. + int buildStorageKey(EShLanguage stage, TStorageQualifier type) { + assert(static_cast(stage) <= 0x0000ffff && static_cast(type) <= 0x0000ffff); + return (stage << 16) | type; + } + +protected: + // Use for mark pre stage, to get more interface symbol information. + EShLanguage preStage; + // Use for mark current shader stage for resolver + EShLanguage currentStage; + // Slot map for storage resource(location of uniform and interface symbol) It's a program share slot + TSlotMap resourceSlotMap; + // Slot map for other resource(image, ubo, ssbo), It's a program share slot. + TSlotMap storageSlotMap; +}; + +typedef std::map TVarLiveMap; + +// override function "operator=", if a vector being sort, +// when use vc++, the sort function will call : +// pair& operator=(const pair<_Other1, _Other2>& _Right) +// { +// first = _Right.first; +// second = _Right.second; +// return (*this); +// } +// that will make a const type handing on left. +// override this function can avoid a compiler error. +// In the future, if the vc++ compiler can handle such a situation, +// this part of the code will be removed. +struct TVarLivePair : std::pair { + TVarLivePair(const std::pair& _Right) : pair(_Right.first, _Right.second) {} + TVarLivePair& operator=(const TVarLivePair& _Right) { + const_cast(first) = _Right.first; + second = _Right.second; + return (*this); + } + TVarLivePair(const TVarLivePair& src) : pair(src) { } +}; +typedef std::vector TVarLiveVector; // I/O mapper class TIoMapper { public: TIoMapper() {} virtual ~TIoMapper() {} - // grow the reflection stage by stage - bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*); + bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*); + bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; } +}; + +// I/O mapper for OpenGL +class TGlslIoMapper : public TIoMapper { +public: + TGlslIoMapper() { + memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); + memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); + memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); + memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1)); + profile = ENoProfile; + version = 0; + } + virtual ~TGlslIoMapper() { + for (size_t stage = 0; stage < EShLangCount; stage++) { + if (inVarMaps[stage] != nullptr) { + delete inVarMaps[stage]; + inVarMaps[stage] = nullptr; + } + if (outVarMaps[stage] != nullptr) { + delete outVarMaps[stage]; + outVarMaps[stage] = nullptr; + } + if (uniformVarMap[stage] != nullptr) { + delete uniformVarMap[stage]; + uniformVarMap[stage] = nullptr; + } + if (intermediates[stage] != nullptr) + intermediates[stage] = nullptr; + } + } + // grow the reflection stage by stage + bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override; + bool doMap(TIoMapResolver*, TInfoSink&) override; + TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], + *uniformVarMap[EShLangCount]; + TIntermediate* intermediates[EShLangCount]; + bool hadError = false; + EProfile profile; + int version; }; } // end namespace glslang #endif // _IOMAPPER_INCLUDED + +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/limits.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/limits.cpp index 64d191b..3915705 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/limits.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/limits.cpp @@ -63,14 +63,14 @@ namespace glslang { class TInductiveTraverser : public TIntermTraverser { public: - TInductiveTraverser(int id, TSymbolTable& st) + TInductiveTraverser(long long id, TSymbolTable& st) : loopId(id), symbolTable(st), bad(false) { } virtual bool visitBinary(TVisit, TIntermBinary* node); virtual bool visitUnary(TVisit, TIntermUnary* node); virtual bool visitAggregate(TVisit, TIntermAggregate* node); - int loopId; // unique ID of the symbol that's the loop inductive variable + long long loopId; // unique ID of the symbol that's the loop inductive variable TSymbolTable& symbolTable; bool bad; TSourceLoc badLoc; @@ -129,7 +129,7 @@ bool TInductiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* n // // External function to call for loop check. // -void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbolTable& symbolTable) +void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, long long loopId, TSymbolTable& symbolTable) { TInductiveTraverser it(loopId, symbolTable); @@ -187,12 +187,14 @@ bool TIndexTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) // void TParseContext::constantIndexExpressionCheck(TIntermNode* index) { +#ifndef GLSLANG_WEB TIndexTraverser it(inductiveLoopIds); index->traverse(&it); if (it.bad) error(it.badLoc, "Non-constant-index-expression", "limitations", ""); +#endif } } // end namespace glslang diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/linkValidate.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/linkValidate.cpp index 0cf2d36..9656e2e 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/linkValidate.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/linkValidate.cpp @@ -48,6 +48,7 @@ #include "localintermediate.h" #include "../Include/InfoSink.h" +#include "SymbolTable.h" namespace glslang { @@ -56,8 +57,10 @@ namespace glslang { // void TIntermediate::error(TInfoSink& infoSink, const char* message) { +#ifndef GLSLANG_WEB infoSink.info.prefix(EPrefixError); infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; +#endif ++numErrors; } @@ -65,8 +68,10 @@ void TIntermediate::error(TInfoSink& infoSink, const char* message) // Link-time warning. void TIntermediate::warn(TInfoSink& infoSink, const char* message) { +#ifndef GLSLANG_WEB infoSink.info.prefix(EPrefixWarning); infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; +#endif } // TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block @@ -78,9 +83,61 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message) // void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) { +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) mergeCallGraphs(infoSink, unit); mergeModes(infoSink, unit); mergeTrees(infoSink, unit); +#endif +} + +// +// check that link objects between stages +// +void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit) { + if (unit.treeRoot == nullptr || treeRoot == nullptr) + return; + + // Get the linker-object lists + TIntermSequence& linkerObjects = findLinkerObjects()->getSequence(); + TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence(); + + // filter unitLinkerObjects to only contain uniforms + auto end = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(), + [](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqUniform && + node->getAsSymbolNode()->getQualifier().storage != EvqBuffer; }); + unitLinkerObjects.resize(end - unitLinkerObjects.begin()); + + // merge uniforms and do error checking + bool mergeExistingOnly = false; + mergeGlobalUniformBlocks(infoSink, unit, mergeExistingOnly); + mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage()); +} + +// +// do error checking on the shader boundary in / out vars +// +void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) { + if (unit.treeRoot == nullptr || treeRoot == nullptr) + return; + + // Get copies of the linker-object lists + TIntermSequence linkerObjects = findLinkerObjects()->getSequence(); + TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence(); + + // filter linkerObjects to only contain out variables + auto end = std::remove_if(linkerObjects.begin(), linkerObjects.end(), + [](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqVaryingOut; }); + linkerObjects.resize(end - linkerObjects.begin()); + + // filter unitLinkerObjects to only contain in variables + auto unitEnd = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(), + [](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqVaryingIn; }); + unitLinkerObjects.resize(unitEnd - unitLinkerObjects.begin()); + + // do matching and error checking + mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage()); + + // TODO: final check; make sure that any statically used `in` have matching `out` written to } void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) @@ -98,6 +155,8 @@ void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end()); } +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + #define MERGE_MAX(member) member = std::max(member, unit.member) #define MERGE_TRUE(member) if (unit.member) member = unit.member; @@ -106,9 +165,9 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) if (language != unit.language) error(infoSink, "stages must match when linking into a single stage"); - if (source == EShSourceNone) - source = unit.source; - if (source != unit.source) + if (getSource() == EShSourceNone) + setSource(unit.getSource()); + if (getSource() != unit.getSource()) error(infoSink, "can't link compilation units from different source languages"); if (treeRoot == nullptr) { @@ -116,7 +175,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) version = unit.version; requestedExtensions = unit.requestedExtensions; } else { - if ((profile == EEsProfile) != (unit.profile == EEsProfile)) + if ((isEsProfile()) != (unit.isEsProfile())) error(infoSink, "Cannot cross link ES and desktop profiles"); else if (unit.profile == ECompatibilityProfile) profile = ECompatibilityProfile; @@ -128,9 +187,14 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) MERGE_MAX(spvVersion.vulkanGlsl); MERGE_MAX(spvVersion.vulkan); MERGE_MAX(spvVersion.openGl); + MERGE_TRUE(spvVersion.vulkanRelaxed); numErrors += unit.getNumErrors(); - numPushConstants += unit.numPushConstants; + // Only one push_constant is allowed, mergeLinkerObjects() will ensure the push_constant + // is the same for all units. + if (numPushConstants > 1 || unit.numPushConstants > 1) + error(infoSink, "Only one push_constant block is allowed per stage"); + numPushConstants = std::min(numPushConstants + unit.numPushConstants, 1); if (unit.invocations != TQualifier::layoutNotSet) { if (invocations == TQualifier::layoutNotSet) @@ -141,19 +205,14 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) if (vertices == TQualifier::layoutNotSet) vertices = unit.vertices; - else if (vertices != unit.vertices) { - if (language == EShLangGeometry -#ifdef NV_EXTENSIONS - || language == EShLangMeshNV -#endif - ) + else if (unit.vertices != TQualifier::layoutNotSet && vertices != unit.vertices) { + if (language == EShLangGeometry || language == EShLangMeshNV) error(infoSink, "Contradictory layout max_vertices values"); else if (language == EShLangTessControl) error(infoSink, "Contradictory layout vertices values"); else assert(0); } -#ifdef NV_EXTENSIONS if (primitives == TQualifier::layoutNotSet) primitives = unit.primitives; else if (primitives != unit.primitives) { @@ -162,16 +221,15 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) else assert(0); } -#endif if (inputPrimitive == ElgNone) inputPrimitive = unit.inputPrimitive; - else if (inputPrimitive != unit.inputPrimitive) + else if (unit.inputPrimitive != ElgNone && inputPrimitive != unit.inputPrimitive) error(infoSink, "Contradictory input layout primitives"); if (outputPrimitive == ElgNone) outputPrimitive = unit.outputPrimitive; - else if (outputPrimitive != unit.outputPrimitive) + else if (unit.outputPrimitive != ElgNone && outputPrimitive != unit.outputPrimitive) error(infoSink, "Contradictory output layout primitives"); if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) @@ -190,12 +248,16 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) MERGE_TRUE(pointMode); for (int i = 0; i < 3; ++i) { - if (localSize[i] > 1) - localSize[i] = unit.localSize[i]; - else if (localSize[i] != unit.localSize[i]) - error(infoSink, "Contradictory local size"); + if (unit.localSizeNotDefault[i]) { + if (!localSizeNotDefault[i]) { + localSize[i] = unit.localSize[i]; + localSizeNotDefault[i] = true; + } + else if (localSize[i] != unit.localSize[i]) + error(infoSink, "Contradictory local size"); + } - if (localSizeSpecId[i] != TQualifier::layoutNotSet) + if (localSizeSpecId[i] == TQualifier::layoutNotSet) localSizeSpecId[i] = unit.localSizeSpecId[i]; else if (localSizeSpecId[i] != unit.localSizeSpecId[i]) error(infoSink, "Contradictory local size specialization ids"); @@ -224,21 +286,16 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride); if (unit.xfbBuffers[b].contains64BitType) xfbBuffers[b].contains64BitType = true; -#ifdef AMD_EXTENSIONS if (unit.xfbBuffers[b].contains32BitType) xfbBuffers[b].contains32BitType = true; if (unit.xfbBuffers[b].contains16BitType) xfbBuffers[b].contains16BitType = true; -#endif // TODO: 4.4 link: enhanced layouts: compare ranges } MERGE_TRUE(multiStream); - -#ifdef NV_EXTENSIONS MERGE_TRUE(layoutOverrideCoverage); MERGE_TRUE(geoPassthroughEXT); -#endif for (unsigned int i = 0; i < unit.shiftBinding.size(); ++i) { if (unit.shiftBinding[i] > 0) @@ -259,6 +316,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) MERGE_TRUE(useUnknownFormat); MERGE_TRUE(hlslOffsets); MERGE_TRUE(useStorageBuffer); + MERGE_TRUE(invariantAll); MERGE_TRUE(hlslIoMapping); // TODO: sourceFile @@ -287,13 +345,8 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) } // Getting this far means we have two existing trees to merge... -#ifdef NV_EXTENSIONS - numShaderRecordNVBlocks += unit.numShaderRecordNVBlocks; -#endif - -#ifdef NV_EXTENSIONS + numShaderRecordBlocks += unit.numShaderRecordBlocks; numTaskNVBlocks += unit.numTaskNVBlocks; -#endif // Get the top-level globals of each unit TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence(); @@ -305,38 +358,57 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) // Map by global name to unique ID to rationalize the same object having // differing IDs in different trees. - TMap idMap; - int maxId; - seedIdMap(idMap, maxId); - remapIds(idMap, maxId + 1, unit); + TIdMaps idMaps; + long long idShift; + seedIdMap(idMaps, idShift); + remapIds(idMaps, idShift + 1, unit); mergeBodies(infoSink, globals, unitGlobals); - mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); + bool mergeExistingOnly = false; + mergeGlobalUniformBlocks(infoSink, unit, mergeExistingOnly); + mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage()); ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end()); } +#endif + +static const TString& getNameForIdMap(TIntermSymbol* symbol) +{ + TShaderInterface si = symbol->getType().getShaderInterface(); + if (si == EsiNone) + return symbol->getName(); + else + return symbol->getType().getTypeName(); +} + + + // Traverser that seeds an ID map with all built-ins, and tracks the -// maximum ID used. +// maximum ID used, currently using (maximum ID + 1) as new symbol id shift seed. +// Level id will keep same after shifting. // (It would be nice to put this in a function, but that causes warnings // on having no bodies for the copy-constructor/operator=.) class TBuiltInIdTraverser : public TIntermTraverser { public: - TBuiltInIdTraverser(TMap& idMap) : idMap(idMap), maxId(0) { } + TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), idShift(0) { } // If it's a built in, add it to the map. - // Track the max ID. virtual void visitSymbol(TIntermSymbol* symbol) { const TQualifier& qualifier = symbol->getType().getQualifier(); - if (qualifier.builtIn != EbvNone) - idMap[symbol->getName()] = symbol->getId(); - maxId = std::max(maxId, symbol->getId()); + if (qualifier.builtIn != EbvNone) { + TShaderInterface si = symbol->getType().getShaderInterface(); + idMaps[si][getNameForIdMap(symbol)] = symbol->getId(); + } + idShift = (symbol->getId() & ~TSymbolTable::uniqueIdMask) | + std::max(idShift & TSymbolTable::uniqueIdMask, + symbol->getId() & TSymbolTable::uniqueIdMask); } - int getMaxId() const { return maxId; } + long long getIdShift() const { return idShift; } protected: TBuiltInIdTraverser(TBuiltInIdTraverser&); TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&); - TMap& idMap; - int maxId; + TIdMaps& idMaps; + long long idShift; }; // Traverser that seeds an ID map with non-builtins. @@ -344,31 +416,33 @@ protected: // on having no bodies for the copy-constructor/operator=.) class TUserIdTraverser : public TIntermTraverser { public: - TUserIdTraverser(TMap& idMap) : idMap(idMap) { } + TUserIdTraverser(TIdMaps& idMaps) : idMaps(idMaps) { } // If its a non-built-in global, add it to the map. virtual void visitSymbol(TIntermSymbol* symbol) { const TQualifier& qualifier = symbol->getType().getQualifier(); - if (qualifier.builtIn == EbvNone) - idMap[symbol->getName()] = symbol->getId(); + if (qualifier.builtIn == EbvNone) { + TShaderInterface si = symbol->getType().getShaderInterface(); + idMaps[si][getNameForIdMap(symbol)] = symbol->getId(); + } } protected: TUserIdTraverser(TUserIdTraverser&); TUserIdTraverser& operator=(TUserIdTraverser&); - TMap& idMap; // over biggest id + TIdMaps& idMaps; // over biggest id }; // Initialize the the ID map with what we know of 'this' AST. -void TIntermediate::seedIdMap(TMap& idMap, int& maxId) +void TIntermediate::seedIdMap(TIdMaps& idMaps, long long& idShift) { // all built-ins everywhere need to align on IDs and contribute to the max ID - TBuiltInIdTraverser builtInIdTraverser(idMap); + TBuiltInIdTraverser builtInIdTraverser(idMaps); treeRoot->traverse(&builtInIdTraverser); - maxId = builtInIdTraverser.getMaxId(); + idShift = builtInIdTraverser.getIdShift() & TSymbolTable::uniqueIdMask; // user variables in the linker object list need to align on ids - TUserIdTraverser userIdTraverser(idMap); + TUserIdTraverser userIdTraverser(idMaps); findLinkerObjects()->traverse(&userIdTraverser); } @@ -377,7 +451,7 @@ void TIntermediate::seedIdMap(TMap& idMap, int& maxId) // on having no bodies for the copy-constructor/operator=.) class TRemapIdTraverser : public TIntermTraverser { public: - TRemapIdTraverser(const TMap& idMap, int idShift) : idMap(idMap), idShift(idShift) { } + TRemapIdTraverser(const TIdMaps& idMaps, long long idShift) : idMaps(idMaps), idShift(idShift) { } // Do the mapping: // - if the same symbol, adopt the 'this' ID // - otherwise, ensure a unique ID by shifting to a new space @@ -386,9 +460,12 @@ public: const TQualifier& qualifier = symbol->getType().getQualifier(); bool remapped = false; if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) { - auto it = idMap.find(symbol->getName()); - if (it != idMap.end()) { - symbol->changeId(it->second); + TShaderInterface si = symbol->getType().getShaderInterface(); + auto it = idMaps[si].find(getNameForIdMap(symbol)); + if (it != idMaps[si].end()) { + uint64_t id = (symbol->getId() & ~TSymbolTable::uniqueIdMask) | + (it->second & TSymbolTable::uniqueIdMask); + symbol->changeId(id); remapped = true; } } @@ -398,14 +475,14 @@ public: protected: TRemapIdTraverser(TRemapIdTraverser&); TRemapIdTraverser& operator=(TRemapIdTraverser&); - const TMap& idMap; - int idShift; + const TIdMaps& idMaps; + long long idShift; }; -void TIntermediate::remapIds(const TMap& idMap, int idShift, TIntermediate& unit) +void TIntermediate::remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate& unit) { // Remap all IDs to either share or be unique, as dictated by the idMap and idShift. - TRemapIdTraverser idTraverser(idMap, idShift); + TRemapIdTraverser idTraverser(idMaps, idShift); unit.getTreeRoot()->traverse(&idTraverser); } @@ -433,11 +510,193 @@ void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, c globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1); } +static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) { + return // 1) same stage and same shader interface + (stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) || + // 2) accross stages and both are uniform or buffer + (symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) || + (symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) || + // 3) in/out matched across stage boundary + (stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) || + (unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut); +} + +// +// Global Unfiform block stores any default uniforms (i.e. uniforms without a block) +// If two linked stages declare the same member, they are meant to be the same uniform +// and need to be in the same block +// merge the members of different stages to allow them to be linked properly +// as a single block +// +void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly) +{ + TIntermSequence& linkerObjects = findLinkerObjects()->getSequence(); + TIntermSequence& unitLinkerObjects = unit.findLinkerObjects()->getSequence(); + + // build lists of default blocks from the intermediates + TIntermSequence defaultBlocks; + TIntermSequence unitDefaultBlocks; + + auto filter = [](TIntermSequence& list, TIntermNode* node) { + if (node->getAsSymbolNode()->getQualifier().defaultBlock) { + list.push_back(node); + } + }; + + std::for_each(linkerObjects.begin(), linkerObjects.end(), + [&defaultBlocks, &filter](TIntermNode* node) { + filter(defaultBlocks, node); + }); + std::for_each(unitLinkerObjects.begin(), unitLinkerObjects.end(), + [&unitDefaultBlocks, &filter](TIntermNode* node) { + filter(unitDefaultBlocks, node); + }); + + auto itUnitBlock = unitDefaultBlocks.begin(); + for (; itUnitBlock != unitDefaultBlocks.end(); itUnitBlock++) { + + bool add = !mergeExistingOnly; + auto itBlock = defaultBlocks.begin(); + + for (; itBlock != defaultBlocks.end(); itBlock++) { + TIntermSymbol* block = (*itBlock)->getAsSymbolNode(); + TIntermSymbol* unitBlock = (*itUnitBlock)->getAsSymbolNode(); + + assert(block && unitBlock); + + // if the two default blocks match, then merge their definitions + if (block->getType().getTypeName() == unitBlock->getType().getTypeName() && + block->getQualifier().storage == unitBlock->getQualifier().storage) { + add = false; + mergeBlockDefinitions(infoSink, block, unitBlock, &unit); + } + } + if (add) { + // push back on original list; won't change the size of the list we're iterating over + linkerObjects.push_back(*itUnitBlock); + } + } +} + +void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unit) { + if (block->getType() == unitBlock->getType()) { + return; + } + + if (block->getType().getTypeName() != unitBlock->getType().getTypeName() || + block->getType().getBasicType() != unitBlock->getType().getBasicType() || + block->getQualifier().storage != unitBlock->getQualifier().storage || + block->getQualifier().layoutSet != unitBlock->getQualifier().layoutSet) { + // different block names likely means different blocks + return; + } + + // merge the struct + // order of declarations doesn't matter and they matched based on member name + TTypeList* memberList = block->getType().getWritableStruct(); + TTypeList* unitMemberList = unitBlock->getType().getWritableStruct(); + + // keep track of which members have changed position + // so we don't have to search the array again + std::map memberIndexUpdates; + + size_t memberListStartSize = memberList->size(); + for (unsigned int i = 0; i < unitMemberList->size(); ++i) { + bool merge = true; + for (unsigned int j = 0; j < memberListStartSize; ++j) { + if ((*memberList)[j].type->getFieldName() == (*unitMemberList)[i].type->getFieldName()) { + merge = false; + const TType* memberType = (*memberList)[j].type; + const TType* unitMemberType = (*unitMemberList)[i].type; + + // compare types + // don't need as many checks as when merging symbols, since + // initializers and most qualifiers are stripped when the member is moved into the block + if ((*memberType) != (*unitMemberType)) { + error(infoSink, "Types must match:"); + infoSink.info << " " << memberType->getFieldName() << ": "; + infoSink.info << "\"" << memberType->getCompleteString() << "\" versus "; + infoSink.info << "\"" << unitMemberType->getCompleteString() << "\"\n"; + } + + memberIndexUpdates[i] = j; + } + } + if (merge) { + memberList->push_back((*unitMemberList)[i]); + memberIndexUpdates[i] = (unsigned int)memberList->size() - 1; + } + } + + TType unitType; + unitType.shallowCopy(unitBlock->getType()); + + // update symbol node in unit tree, + // and other nodes that may reference it + class TMergeBlockTraverser : public TIntermTraverser { + public: + TMergeBlockTraverser(const glslang::TType &type, const glslang::TType& unitType, + glslang::TIntermediate& unit, + const std::map& memberIdxUpdates) : + newType(type), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates) + { } + virtual ~TMergeBlockTraverser() { } + + const glslang::TType& newType; // type with modifications + const glslang::TType& unitType; // copy of original type + glslang::TIntermediate& unit; // intermediate that is being updated + const std::map& memberIndexUpdates; + + virtual void visitSymbol(TIntermSymbol* symbol) + { + glslang::TType& symType = symbol->getWritableType(); + + if (symType == unitType) { + // each symbol node has a local copy of the unitType + // if merging involves changing properties that aren't shared objects + // they should be updated in all instances + + // e.g. the struct list is a ptr to an object, so it can be updated + // once, outside the traverser + //*symType.getWritableStruct() = *newType.getStruct(); + } + + } + + virtual bool visitBinary(TVisit, glslang::TIntermBinary* node) + { + if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == unitType) { + // this is a dereference to a member of the block since the + // member list changed, need to update this to point to the + // right index + assert(node->getRight()->getAsConstantUnion()); + + glslang::TIntermConstantUnion* constNode = node->getRight()->getAsConstantUnion(); + unsigned int memberIdx = constNode->getConstArray()[0].getUConst(); + unsigned int newIdx = memberIndexUpdates.at(memberIdx); + TIntermTyped* newConstNode = unit.addConstantUnion(newIdx, node->getRight()->getLoc()); + + node->setRight(newConstNode); + delete constNode; + + return true; + } + return true; + } + } finalLinkTraverser(block->getType(), unitType, *unit, memberIndexUpdates); + + // update the tree to use the new type + unit->getTreeRoot()->traverse(&finalLinkTraverser); + + // update the member list + (*unitMemberList) = (*memberList); +} + // // Merge the linker objects from unitLinkerObjects into linkerObjects. // Duplication is expected and filtered out, but contradictions are an error. // -void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects) +void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects, EShLanguage unitStage) { // Error check and merge the linker objects (duplicates should not be created) std::size_t initialNumLinkerObjects = linkerObjects.size(); @@ -447,7 +706,19 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode(); TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode(); assert(symbol && unitSymbol); - if (symbol->getName() == unitSymbol->getName()) { + + bool isSameSymbol = false; + // If they are both blocks in the same shader interface, + // match by the block-name, not the identifier name. + if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) { + if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) { + isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName(); + } + } + else if (symbol->getName() == unitSymbol->getName()) + isSameSymbol = true; + + if (isSameSymbol) { // filter out copy merge = false; @@ -460,15 +731,54 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin if (! symbol->getQualifier().hasBinding() && unitSymbol->getQualifier().hasBinding()) symbol->getQualifier().layoutBinding = unitSymbol->getQualifier().layoutBinding; + // Similarly for location + if (!symbol->getQualifier().hasLocation() && unitSymbol->getQualifier().hasLocation()) { + symbol->getQualifier().layoutLocation = unitSymbol->getQualifier().layoutLocation; + } + // Update implicit array sizes mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType()); // Check for consistent types/qualification/initializers etc. - mergeErrorCheck(infoSink, *symbol, *unitSymbol, false); + mergeErrorCheck(infoSink, *symbol, *unitSymbol, unitStage); + } + // If different symbols, verify they arn't push_constant since there can only be one per stage + else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant() && getStage() == unitStage) + error(infoSink, "Only one push_constant block is allowed per stage"); + } + if (merge) { + linkerObjects.push_back(unitLinkerObjects[unitLinkObj]); + + // for anonymous blocks, check that their members don't conflict with other names + if (unitLinkerObjects[unitLinkObj]->getAsSymbolNode()->getBasicType() == EbtBlock && + IsAnonymous(unitLinkerObjects[unitLinkObj]->getAsSymbolNode()->getName())) { + for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) { + TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode(); + TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode(); + assert(symbol && unitSymbol); + + auto checkName = [this, unitSymbol, &infoSink](const TString& name) { + for (unsigned int i = 0; i < unitSymbol->getType().getStruct()->size(); ++i) { + if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()) { + error(infoSink, "Anonymous member name used for global variable or other anonymous member: "); + infoSink.info << (*unitSymbol->getType().getStruct())[i].type->getCompleteString() << "\n"; + } + } + }; + + if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) { + checkName(symbol->getName()); + + // check members of other anonymous blocks + if (symbol->getBasicType() == EbtBlock && IsAnonymous(symbol->getName())) { + for (unsigned int i = 0; i < symbol->getType().getStruct()->size(); ++i) { + checkName((*symbol->getType().getStruct())[i].type->getFieldName()); + } + } + } + } } } - if (merge) - linkerObjects.push_back(unitLinkerObjects[unitLinkObj]); } } @@ -500,31 +810,97 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) // // This function only does one of intra- or cross-stage matching per call. // -void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage) +void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, EShLanguage unitStage) { +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + bool crossStage = getStage() != unitStage; bool writeTypeComparison = false; // Types have to match - if (symbol.getType() != unitSymbol.getType()) { + { // but, we make an exception if one is an implicit array and the other is sized - if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() && - symbol.getType().sameElementType(unitSymbol.getType()) && - (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) { - error(infoSink, "Types must match:"); + // or if the array sizes differ because of the extra array dimension on some in/out boundaries + bool arraysMatch = false; + if (isIoResizeArray(symbol.getType(), getStage()) || isIoResizeArray(unitSymbol.getType(), unitStage)) { + // if the arrays have an extra dimension because of the stage. + // compare dimensions while ignoring the outer dimension + unsigned int firstDim = isIoResizeArray(symbol.getType(), getStage()) ? 1 : 0; + unsigned int numDim = symbol.getArraySizes() + ? symbol.getArraySizes()->getNumDims() : 0; + unsigned int unitFirstDim = isIoResizeArray(unitSymbol.getType(), unitStage) ? 1 : 0; + unsigned int unitNumDim = unitSymbol.getArraySizes() + ? unitSymbol.getArraySizes()->getNumDims() : 0; + arraysMatch = (numDim - firstDim) == (unitNumDim - unitFirstDim); + // check that array sizes match as well + for (unsigned int i = 0; i < (numDim - firstDim) && arraysMatch; i++) { + if (symbol.getArraySizes()->getDimSize(firstDim + i) != + unitSymbol.getArraySizes()->getDimSize(unitFirstDim + i)) { + arraysMatch = false; + break; + } + } + } + else { + arraysMatch = symbol.getType().sameArrayness(unitSymbol.getType()) || + (symbol.getType().isArray() && unitSymbol.getType().isArray() && + (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray())); + } + + if (!symbol.getType().sameElementType(unitSymbol.getType()) || + !symbol.getType().sameTypeParameters(unitSymbol.getType()) || + !arraysMatch ) { writeTypeComparison = true; + error(infoSink, "Types must match:"); } } - // Qualifiers have to (almost) match + // Interface block member-wise layout qualifiers have to match + if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock && + symbol.getType().getStruct() && unitSymbol.getType().getStruct() && + symbol.getType().sameStructType(unitSymbol.getType())) { + for (unsigned int i = 0; i < symbol.getType().getStruct()->size(); ++i) { + const TQualifier& qualifier = (*symbol.getType().getStruct())[i].type->getQualifier(); + const TQualifier& unitQualifier = (*unitSymbol.getType().getStruct())[i].type->getQualifier(); + if (qualifier.layoutMatrix != unitQualifier.layoutMatrix || + qualifier.layoutOffset != unitQualifier.layoutOffset || + qualifier.layoutAlign != unitQualifier.layoutAlign || + qualifier.layoutLocation != unitQualifier.layoutLocation || + qualifier.layoutComponent != unitQualifier.layoutComponent) { + error(infoSink, "Interface block member layout qualifiers must match:"); + writeTypeComparison = true; + } + } + } + bool isInOut = crossStage && + ((symbol.getQualifier().storage == EvqVaryingIn && unitSymbol.getQualifier().storage == EvqVaryingOut) || + (symbol.getQualifier().storage == EvqVaryingOut && unitSymbol.getQualifier().storage == EvqVaryingIn)); + + // Qualifiers have to (almost) match // Storage... - if (symbol.getQualifier().storage != unitSymbol.getQualifier().storage) { + if (!isInOut && symbol.getQualifier().storage != unitSymbol.getQualifier().storage) { error(infoSink, "Storage qualifiers must match:"); writeTypeComparison = true; } + // Uniform and buffer blocks must either both have an instance name, or + // must both be anonymous. The names don't need to match though. + if (symbol.getQualifier().isUniformOrBuffer() && + (IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()))) { + error(infoSink, "Matched Uniform or Storage blocks must all be anonymous," + " or all be named:"); + writeTypeComparison = true; + } + + if (symbol.getQualifier().storage == unitSymbol.getQualifier().storage && + (IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()) || + (!IsAnonymous(symbol.getName()) && symbol.getName() != unitSymbol.getName()))) { + warn(infoSink, "Matched shader interfaces are using different instance names."); + writeTypeComparison = true; + } + // Precision... - if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) { + if (!isInOut && symbol.getQualifier().precision != unitSymbol.getQualifier().precision) { error(infoSink, "Precision qualifiers must match:"); writeTypeComparison = true; } @@ -536,18 +912,22 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy } // Precise... - if (! crossStage && symbol.getQualifier().noContraction != unitSymbol.getQualifier().noContraction) { + if (! crossStage && symbol.getQualifier().isNoContraction() != unitSymbol.getQualifier().isNoContraction()) { error(infoSink, "Presence of precise qualifier must match:"); writeTypeComparison = true; } // Auxiliary and interpolation... - if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid || + // "interpolation qualification (e.g., flat) and auxiliary qualification (e.g. centroid) may differ. + // These mismatches are allowed between any pair of stages ... + // those provided in the fragment shader supersede those provided in previous stages." + if (!crossStage && + (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid || symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth || symbol.getQualifier().flat != unitSymbol.getQualifier().flat || - symbol.getQualifier().sample != unitSymbol.getQualifier().sample || - symbol.getQualifier().patch != unitSymbol.getQualifier().patch || - symbol.getQualifier().nopersp != unitSymbol.getQualifier().nopersp) { + symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() || + symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() || + symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective())) { error(infoSink, "Interpolation and auxiliary storage qualifiers must match:"); writeTypeComparison = true; } @@ -558,6 +938,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent || symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent || symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent || + symbol.getQualifier().shadercallcoherent!= unitSymbol.getQualifier().shadercallcoherent || symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate || symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil || symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict || @@ -592,9 +973,33 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy } } - if (writeTypeComparison) - infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" << - unitSymbol.getType().getCompleteString() << "\"\n"; + if (writeTypeComparison) { + infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus "; + if (symbol.getName() != unitSymbol.getName()) + infoSink.info << unitSymbol.getName() << ": "; + + infoSink.info << "\"" << unitSymbol.getType().getCompleteString() << "\"\n"; + } +#endif +} + +void TIntermediate::sharedBlockCheck(TInfoSink& infoSink) +{ + bool has_shared_block = false; + bool has_shared_non_block = false; + TIntermSequence& linkObjects = findLinkerObjects()->getSequence(); + for (size_t i = 0; i < linkObjects.size(); ++i) { + const TType& type = linkObjects[i]->getAsTyped()->getType(); + const TQualifier& qualifier = type.getQualifier(); + if (qualifier.storage == glslang::EvqShared) { + if (type.getBasicType() == glslang::EbtBlock) + has_shared_block = true; + else + has_shared_non_block = true; + } + } + if (has_shared_block && has_shared_non_block) + error(infoSink, "cannot mix use of shared variables inside and outside blocks"); } // @@ -609,15 +1014,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) return; if (numEntryPoints < 1) { - if (source == EShSourceGlsl) + if (getSource() == EShSourceGlsl) error(infoSink, "Missing entry point: Each stage requires one entry point"); else warn(infoSink, "Entry point not found"); } - if (numPushConstants > 1) - error(infoSink, "Only one push_constant block is allowed per stage"); - // recursion and missing body checking checkCallGraphCycles(infoSink); checkCallGraphBodies(infoSink, keepUncalled); @@ -625,6 +1027,10 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) // overlap/alias/missing I/O, etc. inOutLocationCheck(infoSink); +#ifndef GLSLANG_WEB + if (getNumPushConstants() > 1) + error(infoSink, "Only one push_constant block is allowed per stage"); + // invocations if (invocations == TQualifier::layoutNotSet) invocations = 1; @@ -642,12 +1048,10 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) for (size_t b = 0; b < xfbBuffers.size(); ++b) { if (xfbBuffers[b].contains64BitType) RoundToPow2(xfbBuffers[b].implicitStride, 8); -#ifdef AMD_EXTENSIONS else if (xfbBuffers[b].contains32BitType) RoundToPow2(xfbBuffers[b].implicitStride, 4); else if (xfbBuffers[b].contains16BitType) RoundToPow2(xfbBuffers[b].implicitStride, 2); -#endif // "It is a compile-time or link-time error to have // any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or @@ -668,16 +1072,11 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double or 64-bit integer:"); infoSink.info.prefix(EPrefixError); infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n"; -#ifdef AMD_EXTENSIONS } else if (xfbBuffers[b].contains32BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) { -#else - } else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) { -#endif error(infoSink, "xfb_stride must be multiple of 4:"); infoSink.info.prefix(EPrefixError); infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n"; } -#ifdef AMD_EXTENSIONS // "If the buffer is capturing any // outputs with half-precision or 16-bit integer components, the stride must be a multiple of 2" else if (xfbBuffers[b].contains16BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 2)) { @@ -686,13 +1085,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n"; } -#endif // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents." - if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) { + if (xfbBuffers[b].stride > (unsigned int)(4 * resources->maxTransformFeedbackInterleavedComponents)) { error(infoSink, "xfb_stride is too large:"); infoSink.info.prefix(EPrefixError); - infoSink.info << " xfb_buffer " << (unsigned int)b << ", components (1/4 stride) needed are " << xfbBuffers[b].stride/4 << ", gl_MaxTransformFeedbackInterleavedComponents is " << resources.maxTransformFeedbackInterleavedComponents << "\n"; + infoSink.info << " xfb_buffer " << (unsigned int)b << ", components (1/4 stride) needed are " << xfbBuffers[b].stride/4 << ", gl_MaxTransformFeedbackInterleavedComponents is " << resources->maxTransformFeedbackInterleavedComponents << "\n"; } } @@ -704,7 +1102,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) error(infoSink, "At least one shader must specify an output layout(vertices=...)"); break; case EShLangTessEvaluation: - if (source == EShSourceGlsl) { + if (getSource() == EShSourceGlsl) { if (inputPrimitive == ElgNone) error(infoSink, "At least one shader must specify an input layout primitive"); if (vertexSpacing == EvsNone) @@ -729,16 +1127,15 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) error(infoSink, "post_depth_coverage requires early_fragment_tests"); break; case EShLangCompute: + sharedBlockCheck(infoSink); break; - -#ifdef NV_EXTENSIONS - case EShLangRayGenNV: - case EShLangIntersectNV: - case EShLangAnyHitNV: - case EShLangClosestHitNV: - case EShLangMissNV: - case EShLangCallableNV: - if (numShaderRecordNVBlocks > 1) + case EShLangRayGen: + case EShLangIntersect: + case EShLangAnyHit: + case EShLangClosestHit: + case EShLangMiss: + case EShLangCallable: + if (numShaderRecordBlocks > 1) error(infoSink, "Only one shaderRecordNV buffer block is allowed per stage"); break; case EShLangMeshNV: @@ -763,9 +1160,8 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) case EShLangTaskNV: if (numTaskNVBlocks > 1) error(infoSink, "Only one taskNV interface block is allowed per shader"); + sharedBlockCheck(infoSink); break; -#endif - default: error(infoSink, "Unknown Stage."); break; @@ -787,6 +1183,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) } finalLinkTraverser; treeRoot->traverse(&finalLinkTraverser); +#endif } // @@ -973,7 +1370,7 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink) } } - if (profile == EEsProfile) { + if (isEsProfile()) { if (numFragOut > 1 && fragOutWithNoLocation) error(infoSink, "when more than one fragment shader output, all must have location qualifiers"); } @@ -1011,8 +1408,8 @@ bool TIntermediate::userOutputUsed() const return found; } -// Accumulate locations used for inputs, outputs, and uniforms, and check for collisions -// as the accumulation is done. +// Accumulate locations used for inputs, outputs, and uniforms, payload and callable data +// and check for collisions as the accumulation is done. // // Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. // @@ -1024,6 +1421,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ typeCollision = false; int set; + int setRT; if (qualifier.isPipeInput()) set = 0; else if (qualifier.isPipeOutput()) @@ -1032,11 +1430,17 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ set = 2; else if (qualifier.storage == EvqBuffer) set = 3; + else if (qualifier.isAnyPayload()) + setRT = 0; + else if (qualifier.isAnyCallable()) + setRT = 1; else return -1; int size; - if (qualifier.isUniformOrBuffer() || qualifier.isTaskMemory()) { + if (qualifier.isAnyPayload() || qualifier.isAnyCallable()) { + size = 1; + } else if (qualifier.isUniformOrBuffer() || qualifier.isTaskMemory()) { if (type.isSizedArray()) size = type.getCumulativeArraySize(); else @@ -1064,9 +1468,17 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ // (A vertex shader input will show using only one location, even for a dvec3/4.) // // So, for the case of dvec3, we need two independent ioRanges. - + // + // For raytracing IO (payloads and callabledata) each declaration occupies a single + // slot irrespective of type. int collision = -1; // no collision - if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 && +#ifndef GLSLANG_WEB + if (qualifier.isAnyPayload() || qualifier.isAnyCallable()) { + TRange range(qualifier.layoutLocation, qualifier.layoutLocation); + collision = checkLocationRT(setRT, qualifier.layoutLocation); + if (collision < 0) + usedIoRT[setRT].push_back(range); + } else if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 && (qualifier.isPipeInput() || qualifier.isPipeOutput())) { // Dealing with dvec3 in/out split across two locations. // Need two io-ranges. @@ -1092,7 +1504,9 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ if (collision < 0) usedIo[set].push_back(range2); } - } else { + } else +#endif + { // Not a dvec3 in/out split across two locations, generic path. // Need a single IO-range block. @@ -1106,10 +1520,10 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ } // combine location and component ranges - TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0); + TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.getIndex() : 0); // check for collisions, except for vertex inputs on desktop targeting OpenGL - if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0) + if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0) collision = checkLocationRange(set, range, type, typeCollision); if (collision < 0) @@ -1140,6 +1554,16 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp return -1; // no collision } +int TIntermediate::checkLocationRT(int set, int location) { + TRange range(location, location); + for (size_t r = 0; r < usedIoRT[set].size(); ++r) { + if (range.overlap(usedIoRT[set][r])) { + return range.start; + } + } + return -1; // no collision +} + // Accumulate bindings and offsets, and check for collisions // as the accumulation is done. // @@ -1187,14 +1611,10 @@ int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage) // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness // TODO: are there valid cases of having an unsized array with a location? If so, running this code too early. TType elementType(type, 0); - if (type.isSizedArray() -#ifdef NV_EXTENSIONS - && !type.getQualifier().isPerView() -#endif - ) + if (type.isSizedArray() && !type.getQualifier().isPerView()) return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage); else { -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB // unset perViewNV attributes for arrayed per-view outputs: "perviewNV vec4 v[MAX_VIEWS][3];" elementType.getQualifier().perViewNV = false; #endif @@ -1273,6 +1693,8 @@ int TIntermediate::computeTypeUniformLocationSize(const TType& type) return 1; } +#ifndef GLSLANG_WEB + // Accumulate xfb buffer ranges and check for collisions as the accumulation is done. // // Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. @@ -1285,11 +1707,7 @@ int TIntermediate::addXfbBufferOffset(const TType& type) TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer]; // compute the range -#ifdef AMD_EXTENSIONS unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType, buffer.contains32BitType, buffer.contains16BitType); -#else - unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType); -#endif buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size); TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1); @@ -1309,15 +1727,10 @@ int TIntermediate::addXfbBufferOffset(const TType& type) // Recursively figure out how many bytes of xfb buffer are used by the given type. // Return the size of type, in bytes. // Sets contains64BitType to true if the type contains a 64-bit data type. -#ifdef AMD_EXTENSIONS // Sets contains32BitType to true if the type contains a 32-bit data type. // Sets contains16BitType to true if the type contains a 16-bit data type. // N.B. Caller must set contains64BitType, contains32BitType, and contains16BitType to false before calling. unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const -#else -// N.B. Caller must set contains64BitType to false before calling. -unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType) const -#endif { // "...if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8, // and the space taken in the buffer will be a multiple of 8. @@ -1326,48 +1739,36 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains // that component's size. Aggregate types are flattened down to the component // level to get this sequence of components." - if (type.isArray()) { + if (type.isSizedArray()) { // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness - assert(type.isSizedArray()); + // Unsized array use to xfb should be a compile error. TType elementType(type, 0); -#ifdef AMD_EXTENSIONS return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType); -#else - return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType); -#endif } if (type.isStruct()) { unsigned int size = 0; bool structContains64BitType = false; -#ifdef AMD_EXTENSIONS bool structContains32BitType = false; bool structContains16BitType = false; -#endif for (int member = 0; member < (int)type.getStruct()->size(); ++member) { TType memberType(type, member); // "... if applied to // an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8, // and the space taken in the buffer will be a multiple of 8." bool memberContains64BitType = false; -#ifdef AMD_EXTENSIONS bool memberContains32BitType = false; bool memberContains16BitType = false; int memberSize = computeTypeXfbSize(memberType, memberContains64BitType, memberContains32BitType, memberContains16BitType); -#else - int memberSize = computeTypeXfbSize(memberType, memberContains64BitType); -#endif if (memberContains64BitType) { structContains64BitType = true; RoundToPow2(size, 8); -#ifdef AMD_EXTENSIONS } else if (memberContains32BitType) { structContains32BitType = true; RoundToPow2(size, 4); } else if (memberContains16BitType) { structContains16BitType = true; RoundToPow2(size, 2); -#endif } size += memberSize; } @@ -1375,14 +1776,12 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains if (structContains64BitType) { contains64BitType = true; RoundToPow2(size, 8); -#ifdef AMD_EXTENSIONS } else if (structContains32BitType) { contains32BitType = true; RoundToPow2(size, 4); } else if (structContains16BitType) { contains16BitType = true; RoundToPow2(size, 2); -#endif } return size; } @@ -1402,7 +1801,6 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains if (type.getBasicType() == EbtDouble || type.getBasicType() == EbtInt64 || type.getBasicType() == EbtUint64) { contains64BitType = true; return 8 * numComponents; -#ifdef AMD_EXTENSIONS } else if (type.getBasicType() == EbtFloat16 || type.getBasicType() == EbtInt16 || type.getBasicType() == EbtUint16) { contains16BitType = true; return 2 * numComponents; @@ -1412,12 +1810,10 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains contains32BitType = true; return 4 * numComponents; } -#else - } else - return 4 * numComponents; -#endif } +#endif + const int baseAlignmentVec4Std140 = 16; // Return the size and alignment of a component of the given type. @@ -1425,6 +1821,10 @@ const int baseAlignmentVec4Std140 = 16; // Return value is the alignment.. int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) { +#ifdef GLSLANG_WEB + size = 4; return 4; +#endif + switch (type.getBasicType()) { case EbtInt64: case EbtUint64: @@ -1527,7 +1927,9 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T RoundToPow2(size, alignment); stride = size; // uses full matrix size for stride of an array of matrices (not quite what rule 6/8, but what's expected) // uses the assumption for rule 10 in the comment above - size = stride * type.getOuterArraySize(); + // use one element to represent the last member of SSBO which is unsized array + int arraySize = (type.isUnsizedArray() && (type.getOuterArraySize() == 0)) ? 1 : type.getOuterArraySize(); + size = stride * arraySize; return alignment; } @@ -1683,4 +2085,87 @@ int TIntermediate::getMemberAlignment(const TType& type, int& size, int& stride, } } +// shared calculation by getOffset and getOffsets +void TIntermediate::updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize) +{ + int dummyStride; + + // modify just the children's view of matrix layout, if there is one for this member + TLayoutMatrix subMatrixLayout = memberType.getQualifier().layoutMatrix; + int memberAlignment = getMemberAlignment(memberType, memberSize, dummyStride, + parentType.getQualifier().layoutPacking, + subMatrixLayout != ElmNone + ? subMatrixLayout == ElmRowMajor + : parentType.getQualifier().layoutMatrix == ElmRowMajor); + RoundToPow2(offset, memberAlignment); +} + +// Lookup or calculate the offset of a block member, using the recursively +// defined block offset rules. +int TIntermediate::getOffset(const TType& type, int index) +{ + const TTypeList& memberList = *type.getStruct(); + + // Don't calculate offset if one is present, it could be user supplied + // and different than what would be calculated. That is, this is faster, + // but not just an optimization. + if (memberList[index].type->getQualifier().hasOffset()) + return memberList[index].type->getQualifier().layoutOffset; + + int memberSize = 0; + int offset = 0; + for (int m = 0; m <= index; ++m) { + updateOffset(type, *memberList[m].type, offset, memberSize); + + if (m < index) + offset += memberSize; + } + + return offset; +} + +// Calculate the block data size. +// Block arrayness is not taken into account, each element is backed by a separate buffer. +int TIntermediate::getBlockSize(const TType& blockType) +{ + const TTypeList& memberList = *blockType.getStruct(); + int lastIndex = (int)memberList.size() - 1; + int lastOffset = getOffset(blockType, lastIndex); + + int lastMemberSize; + int dummyStride; + getMemberAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride, + blockType.getQualifier().layoutPacking, + blockType.getQualifier().layoutMatrix == ElmRowMajor); + + return lastOffset + lastMemberSize; +} + +int TIntermediate::computeBufferReferenceTypeSize(const TType& type) +{ + assert(type.isReference()); + int size = getBlockSize(*type.getReferentType()); + + int align = type.getBufferReferenceAlignment(); + + if (align) { + size = (size + align - 1) & ~(align-1); + } + + return size; +} + +#ifndef GLSLANG_WEB +bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) { + return type.isArray() && + ((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) || + (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && + ! type.getQualifier().patch) || + (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn && + type.getQualifier().pervertexNV) || + (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut && + !type.getQualifier().perTaskNV)); +} +#endif // not GLSLANG_WEB + } // end namespace glslang diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/localintermediate.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/localintermediate.h index aecbc6b..6aa9399 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/localintermediate.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/localintermediate.h @@ -147,26 +147,25 @@ struct TOffsetRange { TRange offset; }; +#ifndef GLSLANG_WEB // Things that need to be tracked per xfb buffer. struct TXfbBuffer { -#ifdef AMD_EXTENSIONS TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false), contains32BitType(false), contains16BitType(false) { } -#else - TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false) { } -#endif std::vector ranges; // byte offsets that have already been assigned unsigned int stride; unsigned int implicitStride; bool contains64BitType; -#ifdef AMD_EXTENSIONS bool contains32BitType; bool contains16BitType; -#endif }; +#endif // Track a set of strings describing how the module was processed. -// Using the form: +// This includes command line options, transforms, etc., ideally inclusive enough +// to reproduce the steps used to transform the input source to the output. +// E.g., see SPIR-V OpModuleProcessed. +// Each "process" or "transform" uses is expressed in the form: // process arg0 arg1 arg2 ... // process arg0 arg1 arg2 ... // where everything is textual, and there can be zero or more arguments @@ -217,7 +216,6 @@ class TSymbolTable; class TSymbol; class TVariable; -#ifdef NV_EXTENSIONS // // Texture and Sampler transformation mode. // @@ -226,7 +224,57 @@ enum ComputeDerivativeMode { LayoutDerivativeGroupQuads, // derivative_group_quadsNV LayoutDerivativeGroupLinear, // derivative_group_linearNV }; -#endif + +class TIdMaps { +public: + TMap& operator[](long long i) { return maps[i]; } + const TMap& operator[](long long i) const { return maps[i]; } +private: + TMap maps[EsiCount]; +}; + +class TNumericFeatures { +public: + TNumericFeatures() : features(0) { } + TNumericFeatures(const TNumericFeatures&) = delete; + TNumericFeatures& operator=(const TNumericFeatures&) = delete; + typedef enum : unsigned int { + shader_explicit_arithmetic_types = 1 << 0, + shader_explicit_arithmetic_types_int8 = 1 << 1, + shader_explicit_arithmetic_types_int16 = 1 << 2, + shader_explicit_arithmetic_types_int32 = 1 << 3, + shader_explicit_arithmetic_types_int64 = 1 << 4, + shader_explicit_arithmetic_types_float16 = 1 << 5, + shader_explicit_arithmetic_types_float32 = 1 << 6, + shader_explicit_arithmetic_types_float64 = 1 << 7, + shader_implicit_conversions = 1 << 8, + gpu_shader_fp64 = 1 << 9, + gpu_shader_int16 = 1 << 10, + gpu_shader_half_float = 1 << 11, + } feature; + void insert(feature f) { features |= f; } + void erase(feature f) { features &= ~f; } + bool contains(feature f) const { return (features & f) != 0; } +private: + unsigned int features; +}; + +// MustBeAssigned wraps a T, asserting that it has been assigned with +// operator =() before attempting to read with operator T() or operator ->(). +// Used to catch cases where fields are read before they have been assigned. +template +class MustBeAssigned +{ +public: + MustBeAssigned() = default; + MustBeAssigned(const T& v) : value(v) {} + operator const T&() const { assert(isSet); return value; } + const T* operator ->() const { assert(isSet); return &value; } + MustBeAssigned& operator = (const T& v) { value = v; isSet = true; return *this; } +private: + T value; + bool isSet = false; +}; // // Set of helper functions to help parse and build the tree. @@ -234,57 +282,166 @@ enum ComputeDerivativeMode { class TIntermediate { public: explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : - implicitThisName("@this"), implicitCounterName("@count"), - language(l), source(EShSourceNone), profile(p), version(v), treeRoot(0), + language(l), +#ifndef GLSLANG_ANGLE + profile(p), version(v), +#endif + treeRoot(0), + resources(TBuiltInResource{}), numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), + invertY(false), + useStorageBuffer(false), + invariantAll(false), + nanMinMaxClamp(false), + depthReplacing(false), + uniqueId(0), + globalUniformBlockName(""), + atomicCounterBlockName(""), + globalUniformBlockSet(TQualifier::layoutSetEnd), + globalUniformBlockBinding(TQualifier::layoutBindingEnd), + atomicCounterBlockSet(TQualifier::layoutSetEnd) +#ifndef GLSLANG_WEB + , + implicitThisName("@this"), implicitCounterName("@count"), + source(EShSourceNone), + useVulkanMemoryModel(false), invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), - vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), - postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false), + vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false), + postDepthCoverage(false), depthLayout(EldNone), hlslFunctionality1(false), blendEquations(0), xfbMode(false), multiStream(false), -#ifdef NV_EXTENSIONS layoutOverrideCoverage(false), geoPassthroughEXT(false), - numShaderRecordNVBlocks(0), + numShaderRecordBlocks(0), computeDerivativeMode(LayoutDerivativeNone), primitives(TQualifier::layoutNotSet), numTaskNVBlocks(0), -#endif + layoutPrimitiveCulling(false), autoMapBindings(false), autoMapLocations(false), - invertY(false), flattenUniformArrays(false), useUnknownFormat(false), hlslOffsets(false), - useStorageBuffer(false), - useVulkanMemoryModel(false), hlslIoMapping(false), + useVariablePointers(false), textureSamplerTransformMode(EShTexSampTransKeep), needToLegalize(false), binaryDoubleOutput(false), + subgroupUniformControlFlow(false), usePhysicalStorageBuffer(false), + spirvRequirement(nullptr), + spirvExecutionMode(nullptr), uniformLocationBase(0) +#endif { localSize[0] = 1; localSize[1] = 1; localSize[2] = 1; + localSizeNotDefault[0] = false; + localSizeNotDefault[1] = false; + localSizeNotDefault[2] = false; localSizeSpecId[0] = TQualifier::layoutNotSet; localSizeSpecId[1] = TQualifier::layoutNotSet; localSizeSpecId[2] = TQualifier::layoutNotSet; +#ifndef GLSLANG_WEB xfbBuffers.resize(TQualifier::layoutXfbBufferEnd); - shiftBinding.fill(0); +#endif } + + void setVersion(int v) + { +#ifndef GLSLANG_ANGLE + version = v; +#endif + } + void setProfile(EProfile p) + { +#ifndef GLSLANG_ANGLE + profile = p; +#endif + } + + int getVersion() const { return version; } + EProfile getProfile() const { return profile; } + void setSpv(const SpvVersion& s) + { + spvVersion = s; + + // client processes + if (spvVersion.vulkan > 0) + processes.addProcess("client vulkan100"); + if (spvVersion.openGl > 0) + processes.addProcess("client opengl100"); + + // target SPV + switch (spvVersion.spv) { + case 0: + break; + case EShTargetSpv_1_0: + break; + case EShTargetSpv_1_1: + processes.addProcess("target-env spirv1.1"); + break; + case EShTargetSpv_1_2: + processes.addProcess("target-env spirv1.2"); + break; + case EShTargetSpv_1_3: + processes.addProcess("target-env spirv1.3"); + break; + case EShTargetSpv_1_4: + processes.addProcess("target-env spirv1.4"); + break; + case EShTargetSpv_1_5: + processes.addProcess("target-env spirv1.5"); + break; + default: + processes.addProcess("target-env spirvUnknown"); + break; + } + + // target-environment processes + switch (spvVersion.vulkan) { + case 0: + break; + case EShTargetVulkan_1_0: + processes.addProcess("target-env vulkan1.0"); + break; + case EShTargetVulkan_1_1: + processes.addProcess("target-env vulkan1.1"); + break; + case EShTargetVulkan_1_2: + processes.addProcess("target-env vulkan1.2"); + break; + default: + processes.addProcess("target-env vulkanUnknown"); + break; + } + if (spvVersion.openGl > 0) + processes.addProcess("target-env opengl"); + } + const SpvVersion& getSpv() const { return spvVersion; } + EShLanguage getStage() const { return language; } + void addRequestedExtension(const char* extension) { requestedExtensions.insert(extension); } + const std::set& getRequestedExtensions() const { return requestedExtensions; } + bool isRayTracingStage() const { + return language >= EShLangRayGen && language <= EShLangCallableNV; + } + + void setTreeRoot(TIntermNode* r) { treeRoot = r; } + TIntermNode* getTreeRoot() const { return treeRoot; } + void incrementEntryPointCount() { ++numEntryPoints; } + int getNumEntryPoints() const { return numEntryPoints; } + int getNumErrors() const { return numErrors; } + void addPushConstantCount() { ++numPushConstants; } void setLimits(const TBuiltInResource& r) { resources = r; } + const TBuiltInResource& getLimits() const { return resources; } bool postProcess(TIntermNode*, EShLanguage); - void output(TInfoSink&, bool tree); void removeTree(); - void setSource(EShSource s) { source = s; } - EShSource getSource() const { return source; } void setEntryPointName(const char* ep) { entryPointName = ep; @@ -295,6 +452,180 @@ public: const std::string& getEntryPointName() const { return entryPointName; } const std::string& getEntryPointMangledName() const { return entryPointMangledName; } + void setInvertY(bool invert) + { + invertY = invert; + if (invertY) + processes.addProcess("invert-y"); + } + bool getInvertY() const { return invertY; } + +#ifdef ENABLE_HLSL + void setSource(EShSource s) { source = s; } + EShSource getSource() const { return source; } +#else + void setSource(EShSource s) { assert(s == EShSourceGlsl); (void)s; } + EShSource getSource() const { return EShSourceGlsl; } +#endif + + bool isRecursive() const { return recursive; } + + TIntermSymbol* addSymbol(const TVariable&); + TIntermSymbol* addSymbol(const TVariable&, const TSourceLoc&); + TIntermSymbol* addSymbol(const TType&, const TSourceLoc&); + TIntermSymbol* addSymbol(const TIntermSymbol&); + TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); + std::tuple addPairConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1); + TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*); + TIntermTyped* addConversion(TBasicType convertTo, TIntermTyped* node) const; + void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode); + TIntermTyped* addShapeConversion(const TType&, TIntermTyped*); + TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); + TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); + TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&); + TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, const TSourceLoc&); + TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType); + bool canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op = EOpNull) const; + bool isIntegralPromotion(TBasicType from, TBasicType to) const; + bool isFPPromotion(TBasicType from, TBasicType to) const; + bool isIntegralConversion(TBasicType from, TBasicType to) const; + bool isFPConversion(TBasicType from, TBasicType to) const; + bool isFPIntegralConversion(TBasicType from, TBasicType to) const; + TOperator mapTypeToConstructorOp(const TType&) const; + TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right); + TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&); + TIntermAggregate* makeAggregate(TIntermNode* node); + TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&); + TIntermAggregate* makeAggregate(const TSourceLoc&); + TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, const TSourceLoc&); + bool areAllChildConst(TIntermAggregate* aggrNode); + TIntermSelection* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&); + TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&); + TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); + TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&); + TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(signed char, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(unsigned char, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(signed short, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(unsigned short, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const; + TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const; + bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false); + TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&); + TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, + const TSourceLoc&, TIntermLoop*&); + TIntermBranch* addBranch(TOperator, const TSourceLoc&); + TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&); + template TIntermTyped* addSwizzle(TSwizzleSelectors&, const TSourceLoc&); + + // Low level functions to add nodes (no conversions or other higher level transformations) + // If a type is provided, the node's type will be set to it. + TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&) const; + TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&, + const TType&) const; + TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc&) const; + TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc&, const TType&) const; + + // Constant folding (in Constant.cpp) + TIntermTyped* fold(TIntermAggregate* aggrNode); + TIntermTyped* foldConstructor(TIntermAggregate* aggrNode); + TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&); + TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors& fields, const TSourceLoc&); + + // Tree ops + static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false); + + // Linkage related + void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); + void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&); + TIntermAggregate* findLinkerObjects() const; + + void setGlobalUniformBlockName(const char* name) { globalUniformBlockName = std::string(name); } + const char* getGlobalUniformBlockName() const { return globalUniformBlockName.c_str(); } + void setGlobalUniformSet(unsigned int set) { globalUniformBlockSet = set; } + unsigned int getGlobalUniformSet() const { return globalUniformBlockSet; } + void setGlobalUniformBinding(unsigned int binding) { globalUniformBlockBinding = binding; } + unsigned int getGlobalUniformBinding() const { return globalUniformBlockBinding; } + + void setAtomicCounterBlockName(const char* name) { atomicCounterBlockName = std::string(name); } + const char* getAtomicCounterBlockName() const { return atomicCounterBlockName.c_str(); } + void setAtomicCounterBlockSet(unsigned int set) { atomicCounterBlockSet = set; } + unsigned int getAtomicCounterBlockSet() const { return atomicCounterBlockSet; } + + + void setUseStorageBuffer() { useStorageBuffer = true; } + bool usingStorageBuffer() const { return useStorageBuffer; } + void setInvariantAll() { invariantAll = true; } + bool isInvariantAll() const { return invariantAll; } + void setDepthReplacing() { depthReplacing = true; } + bool isDepthReplacing() const { return depthReplacing; } + bool setLocalSize(int dim, int size) + { + if (localSizeNotDefault[dim]) + return size == localSize[dim]; + localSizeNotDefault[dim] = true; + localSize[dim] = size; + return true; + } + unsigned int getLocalSize(int dim) const { return localSize[dim]; } + bool isLocalSizeSet() const + { + // Return true if any component has been set (i.e. any component is not default). + return localSizeNotDefault[0] || localSizeNotDefault[1] || localSizeNotDefault[2]; + } + bool setLocalSizeSpecId(int dim, int id) + { + if (localSizeSpecId[dim] != TQualifier::layoutNotSet) + return id == localSizeSpecId[dim]; + localSizeSpecId[dim] = id; + return true; + } + int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; } + bool isLocalSizeSpecialized() const + { + // Return true if any component has been specialized. + return localSizeSpecId[0] != TQualifier::layoutNotSet || + localSizeSpecId[1] != TQualifier::layoutNotSet || + localSizeSpecId[2] != TQualifier::layoutNotSet; + } +#ifdef GLSLANG_WEB + void output(TInfoSink&, bool tree) { } + + bool isEsProfile() const { return false; } + bool getXfbMode() const { return false; } + bool isMultiStream() const { return false; } + TLayoutGeometry getOutputPrimitive() const { return ElgNone; } + bool getPostDepthCoverage() const { return false; } + bool getEarlyFragmentTests() const { return false; } + TLayoutDepth getDepth() const { return EldNone; } + bool getPixelCenterInteger() const { return false; } + void setOriginUpperLeft() { } + bool getOriginUpperLeft() const { return true; } + TInterlockOrdering getInterlockOrdering() const { return EioNone; } + + bool getAutoMapBindings() const { return false; } + bool getAutoMapLocations() const { return false; } + int getNumPushConstants() const { return 0; } + void addShaderRecordCount() { } + void addTaskNVCount() { } + void setUseVulkanMemoryModel() { } + bool usingVulkanMemoryModel() const { return false; } + bool usingPhysicalStorageBuffer() const { return false; } + bool usingVariablePointers() const { return false; } + unsigned getXfbStride(int buffer) const { return 0; } + bool hasLayoutDerivativeModeNone() const { return false; } + ComputeDerivativeMode getLayoutDerivativeModeNone() const { return LayoutDerivativeNone; } +#else + void output(TInfoSink&, bool tree); + + bool isEsProfile() const { return profile == EEsProfile; } + void setShiftBinding(TResourceType res, unsigned int shift) { shiftBinding[res] = shift; @@ -352,14 +683,8 @@ public: processes.addProcess("auto-map-locations"); } bool getAutoMapLocations() const { return autoMapLocations; } - void setInvertY(bool invert) - { - invertY = invert; - if (invertY) - processes.addProcess("invert-y"); - } - bool getInvertY() const { return invertY; } +#ifdef ENABLE_HLSL void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; @@ -367,6 +692,7 @@ public: processes.addProcess("flatten-uniform-arrays"); } bool getFlattenUniformArrays() const { return flattenUniformArrays; } +#endif void setNoStorageFormat(bool b) { useUnknownFormat = b; @@ -374,26 +700,6 @@ public: processes.addProcess("no-storage-format"); } bool getNoStorageFormat() const { return useUnknownFormat; } - void setHlslOffsets() - { - hlslOffsets = true; - if (hlslOffsets) - processes.addProcess("hlsl-offsets"); - } - bool usingHlslOffsets() const { return hlslOffsets; } - void setUseStorageBuffer() - { - useStorageBuffer = true; - processes.addProcess("use-storage-buffer"); - } - bool usingStorageBuffer() const { return useStorageBuffer; } - void setHlslIoMapping(bool b) - { - hlslIoMapping = b; - if (hlslIoMapping) - processes.addProcess("hlsl-iomap"); - } - bool usingHlslIoMapping() { return hlslIoMapping; } void setUseVulkanMemoryModel() { useVulkanMemoryModel = true; @@ -405,157 +711,26 @@ public: usePhysicalStorageBuffer = true; } bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; } + void setUseVariablePointers() + { + useVariablePointers = true; + processes.addProcess("use-variable-pointers"); + } + bool usingVariablePointers() const { return useVariablePointers; } +#ifdef ENABLE_HLSL template T addCounterBufferName(const T& name) const { return name + implicitCounterName; } bool hasCounterBufferName(const TString& name) const { size_t len = strlen(implicitCounterName); return name.size() > len && name.compare(name.size() - len, len, implicitCounterName) == 0; } - - void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; } - - void setVersion(int v) { version = v; } - int getVersion() const { return version; } - void setProfile(EProfile p) { profile = p; } - EProfile getProfile() const { return profile; } - void setSpv(const SpvVersion& s) - { - spvVersion = s; - - // client processes - if (spvVersion.vulkan > 0) - processes.addProcess("client vulkan100"); - if (spvVersion.openGl > 0) - processes.addProcess("client opengl100"); - - // target SPV - switch (spvVersion.spv) { - case 0: - break; - case EShTargetSpv_1_0: - break; - case EShTargetSpv_1_1: - processes.addProcess("target-env spirv1.1"); - break; - case EShTargetSpv_1_2: - processes.addProcess("target-env spirv1.2"); - break; - case EShTargetSpv_1_3: - processes.addProcess("target-env spirv1.3"); - break; - default: - processes.addProcess("target-env spirvUnknown"); - break; - } - - // target-environment processes - switch (spvVersion.vulkan) { - case 0: - break; - case EShTargetVulkan_1_0: - processes.addProcess("target-env vulkan1.0"); - break; - case EShTargetVulkan_1_1: - processes.addProcess("target-env vulkan1.1"); - break; - default: - processes.addProcess("target-env vulkanUnknown"); - break; - } - if (spvVersion.openGl > 0) - processes.addProcess("target-env opengl"); - } - const SpvVersion& getSpv() const { return spvVersion; } - EShLanguage getStage() const { return language; } - void addRequestedExtension(const char* extension) { requestedExtensions.insert(extension); } - const std::set& getRequestedExtensions() const { return requestedExtensions; } - - void setTreeRoot(TIntermNode* r) { treeRoot = r; } - TIntermNode* getTreeRoot() const { return treeRoot; } - void incrementEntryPointCount() { ++numEntryPoints; } - int getNumEntryPoints() const { return numEntryPoints; } - int getNumErrors() const { return numErrors; } - void addPushConstantCount() { ++numPushConstants; } -#ifdef NV_EXTENSIONS - void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; } - void addTaskNVCount() { ++numTaskNVBlocks; } #endif - bool isRecursive() const { return recursive; } - - TIntermSymbol* addSymbol(const TVariable&); - TIntermSymbol* addSymbol(const TVariable&, const TSourceLoc&); - TIntermSymbol* addSymbol(const TType&, const TSourceLoc&); - TIntermSymbol* addSymbol(const TIntermSymbol&); - TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const; - std::tuple addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) const; - TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*); - void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode); - TIntermTyped* addShapeConversion(const TType&, TIntermTyped*); - TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); - TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc); - TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc); - TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc); - TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType); - bool canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op = EOpNull) const; - bool isIntegralPromotion(TBasicType from, TBasicType to) const; - bool isFPPromotion(TBasicType from, TBasicType to) const; - bool isIntegralConversion(TBasicType from, TBasicType to) const; - bool isFPConversion(TBasicType from, TBasicType to) const; - bool isFPIntegralConversion(TBasicType from, TBasicType to) const; - TOperator mapTypeToConstructorOp(const TType&) const; - TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right); - TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&); - TIntermAggregate* makeAggregate(TIntermNode* node); - TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&); - TIntermAggregate* makeAggregate(const TSourceLoc&); - TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc); - bool areAllChildConst(TIntermAggregate* aggrNode); - TIntermSelection* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&); - TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&); - TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); - TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&); - TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(signed char, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(unsigned char, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(signed short, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(unsigned short, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const; - TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const; - bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false); - TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&); - TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, - const TSourceLoc&, TIntermLoop*&); - TIntermBranch* addBranch(TOperator, const TSourceLoc&); - TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&); - template TIntermTyped* addSwizzle(TSwizzleSelectors&, const TSourceLoc&); - - // Low level functions to add nodes (no conversions or other higher level transformations) - // If a type is provided, the node's type will be set to it. - TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc) const; - TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, const TType&) const; - TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc) const; - TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc, const TType&) const; - - // Constant folding (in Constant.cpp) - TIntermTyped* fold(TIntermAggregate* aggrNode); - TIntermTyped* foldConstructor(TIntermAggregate* aggrNode); - TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&); - TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors& fields, const TSourceLoc&); - - // Tree ops - static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay); - - // Linkage related - void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); - void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&); + void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; } + int getNumPushConstants() const { return numPushConstants; } + void addShaderRecordCount() { ++numShaderRecordBlocks; } + void addTaskNVCount() { ++numTaskNVBlocks; } bool setInvocations(int i) { @@ -600,23 +775,14 @@ public: void setPointMode() { pointMode = true; } bool getPointMode() const { return pointMode; } - bool setLocalSize(int dim, int size) + bool setInterlockOrdering(TInterlockOrdering o) { - if (localSize[dim] > 1) - return size == localSize[dim]; - localSize[dim] = size; + if (interlockOrdering != EioNone) + return interlockOrdering == o; + interlockOrdering = o; return true; } - unsigned int getLocalSize(int dim) const { return localSize[dim]; } - - bool setLocalSizeSpecId(int dim, int id) - { - if (localSizeSpecId[dim] != TQualifier::layoutNotSet) - return id == localSizeSpecId[dim]; - localSizeSpecId[dim] = id; - return true; - } - int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; } + TInterlockOrdering getInterlockOrdering() const { return interlockOrdering; } void setXfbMode() { xfbMode = true; } bool getXfbMode() const { return xfbMode; } @@ -630,14 +796,10 @@ public: return true; } TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; } - void setOriginUpperLeft() { originUpperLeft = true; } - bool getOriginUpperLeft() const { return originUpperLeft; } - void setPixelCenterInteger() { pixelCenterInteger = true; } - bool getPixelCenterInteger() const { return pixelCenterInteger; } - void setEarlyFragmentTests() { earlyFragmentTests = true; } - bool getEarlyFragmentTests() const { return earlyFragmentTests; } void setPostDepthCoverage() { postDepthCoverage = true; } bool getPostDepthCoverage() const { return postDepthCoverage; } + void setEarlyFragmentTests() { earlyFragmentTests = true; } + bool getEarlyFragmentTests() const { return earlyFragmentTests; } bool setDepth(TLayoutDepth d) { if (depthLayout != EldNone) @@ -646,29 +808,12 @@ public: return true; } TLayoutDepth getDepth() const { return depthLayout; } - void setDepthReplacing() { depthReplacing = true; } - bool isDepthReplacing() const { return depthReplacing; } - - void setHlslFunctionality1() { hlslFunctionality1 = true; } - bool getHlslFunctionality1() const { return hlslFunctionality1; } - + void setOriginUpperLeft() { originUpperLeft = true; } + bool getOriginUpperLeft() const { return originUpperLeft; } + void setPixelCenterInteger() { pixelCenterInteger = true; } + bool getPixelCenterInteger() const { return pixelCenterInteger; } void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); } unsigned int getBlendEquations() const { return blendEquations; } - - void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); - void merge(TInfoSink&, TIntermediate&); - void finalCheck(TInfoSink&, bool keepUncalled); - - void addIoAccessed(const TString& name) { ioAccessed.insert(name); } - bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); } - - int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision); - int checkLocationRange(int set, const TIoRange& range, const TType&, bool& typeCollision); - int addUsedOffsets(int binding, int offset, int numOffsets); - bool addUsedConstantId(int id); - static int computeTypeLocationSize(const TType&, EShLanguage); - static int computeTypeUniformLocationSize(const TType&); - bool setXfbBufferStride(int buffer, unsigned stride) { if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd) @@ -678,25 +823,17 @@ public: } unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; } int addXfbBufferOffset(const TType&); -#ifdef AMD_EXTENSIONS unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const; -#else unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const; -#endif - static int getBaseAlignmentScalar(const TType&, int& size); - static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor); - static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor); - static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor); - static bool improperStraddle(const TType& type, int size, int offset); - bool promote(TIntermOperator*); - -#ifdef NV_EXTENSIONS void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; } bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; } void setGeoPassthroughEXT() { geoPassthroughEXT = true; } bool getGeoPassthroughEXT() const { return geoPassthroughEXT; } void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; } + bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; } ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; } + void setLayoutPrimitiveCulling() { layoutPrimitiveCulling = true; } + bool getLayoutPrimitiveCulling() const { return layoutPrimitiveCulling; } bool setPrimitives(int m) { if (primitives != TQualifier::layoutNotSet) @@ -705,28 +842,10 @@ public: return true; } int getPrimitives() const { return primitives; } -#endif - const char* addSemanticName(const TString& name) { return semanticNameSet.insert(name).first->c_str(); } - - void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; } - const std::string& getSourceFile() const { return sourceFile; } - void addSourceText(const char* text, size_t len) { sourceText.append(text, len); } - const std::string& getSourceText() const { return sourceText; } - const std::map& getIncludeText() const { return includeText; } - void addIncludeText(const char* name, const char* text, size_t len) { includeText[name].assign(text,len); } - void addProcesses(const std::vector& p) - { - for (int i = 0; i < (int)p.size(); ++i) - processes.addProcess(p[i]); - } - void addProcess(const std::string& process) { processes.addProcess(process); } - void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } - const std::vector& getProcesses() const { return processes.getProcesses(); } - void addUniformLocationOverride(const char* nameStr, int location) { std::string name = nameStr; @@ -752,26 +871,167 @@ public: void setBinaryDoubleOutput() { binaryDoubleOutput = true; } bool getBinaryDoubleOutput() { return binaryDoubleOutput; } - const char* const implicitThisName; - const char* const implicitCounterName; + void setSubgroupUniformControlFlow() { subgroupUniformControlFlow = true; } + bool getSubgroupUniformControlFlow() const { return subgroupUniformControlFlow; } + + // GL_EXT_spirv_intrinsics + void insertSpirvRequirement(const TSpirvRequirement* spirvReq); + bool hasSpirvRequirement() const { return spirvRequirement != nullptr; } + const TSpirvRequirement& getSpirvRequirement() const { return *spirvRequirement; } + void insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args = nullptr); + void insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args); + bool hasSpirvExecutionMode() const { return spirvExecutionMode != nullptr; } + const TSpirvExecutionMode& getSpirvExecutionMode() const { return *spirvExecutionMode; } +#endif // GLSLANG_WEB + + void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) + { + std::string name(nameStr); + blockBackingOverrides[name] = backing; + } + TBlockStorageClass getBlockStorageOverride(const char* nameStr) const + { + std::string name = nameStr; + auto pos = blockBackingOverrides.find(name); + if (pos == blockBackingOverrides.end()) + return EbsNone; + else + return pos->second; + } +#ifdef ENABLE_HLSL + void setHlslFunctionality1() { hlslFunctionality1 = true; } + bool getHlslFunctionality1() const { return hlslFunctionality1; } + void setHlslOffsets() + { + hlslOffsets = true; + if (hlslOffsets) + processes.addProcess("hlsl-offsets"); + } + bool usingHlslOffsets() const { return hlslOffsets; } + void setHlslIoMapping(bool b) + { + hlslIoMapping = b; + if (hlslIoMapping) + processes.addProcess("hlsl-iomap"); + } + bool usingHlslIoMapping() { return hlslIoMapping; } +#else + bool getHlslFunctionality1() const { return false; } + bool usingHlslOffsets() const { return false; } + bool usingHlslIoMapping() { return false; } +#endif + + bool usingScalarBlockLayout() const { + for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) { + if (*extIt == E_GL_EXT_scalar_block_layout) + return true; + } + return false; + } + + bool IsRequestedExtension(const char* extension) const + { + return (requestedExtensions.find(extension) != requestedExtensions.end()); + } + + void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); + void merge(TInfoSink&, TIntermediate&); + void finalCheck(TInfoSink&, bool keepUncalled); + + void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly); + void mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit); + void checkStageIO(TInfoSink&, TIntermediate&); + + bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const; + TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const; + + void addIoAccessed(const TString& name) { ioAccessed.insert(name); } + bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); } + + int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision); + int checkLocationRange(int set, const TIoRange& range, const TType&, bool& typeCollision); + int checkLocationRT(int set, int location); + int addUsedOffsets(int binding, int offset, int numOffsets); + bool addUsedConstantId(int id); + static int computeTypeLocationSize(const TType&, EShLanguage); + static int computeTypeUniformLocationSize(const TType&); + + static int getBaseAlignmentScalar(const TType&, int& size); + static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor); + static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor); + static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor); + static bool improperStraddle(const TType& type, int size, int offset); + static void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize); + static int getOffset(const TType& type, int index); + static int getBlockSize(const TType& blockType); + static int computeBufferReferenceTypeSize(const TType&); + static bool isIoResizeArray(const TType& type, EShLanguage language); + + bool promote(TIntermOperator*); + void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; } + bool getNanMinMaxClamp() const { return nanMinMaxClamp; } + + void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; } + const std::string& getSourceFile() const { return sourceFile; } + void addSourceText(const char* text, size_t len) { sourceText.append(text, len); } + const std::string& getSourceText() const { return sourceText; } + const std::map& getIncludeText() const { return includeText; } + void addIncludeText(const char* name, const char* text, size_t len) { includeText[name].assign(text,len); } + void addProcesses(const std::vector& p) + { + for (int i = 0; i < (int)p.size(); ++i) + processes.addProcess(p[i]); + } + void addProcess(const std::string& process) { processes.addProcess(process); } + void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } + const std::vector& getProcesses() const { return processes.getProcesses(); } + unsigned long long getUniqueId() const { return uniqueId; } + void setUniqueId(unsigned long long id) { uniqueId = id; } + + // Certain explicit conversions are allowed conditionally +#ifdef GLSLANG_WEB + bool getArithemeticInt8Enabled() const { return false; } + bool getArithemeticInt16Enabled() const { return false; } + bool getArithemeticFloat16Enabled() const { return false; } + void updateNumericFeature(TNumericFeatures::feature f, bool on) { } +#else + bool getArithemeticInt8Enabled() const { + return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8); + } + bool getArithemeticInt16Enabled() const { + return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::gpu_shader_int16) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16); + } + + bool getArithemeticFloat16Enabled() const { + return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16); + } + void updateNumericFeature(TNumericFeatures::feature f, bool on) + { on ? numericFeatures.insert(f) : numericFeatures.erase(f); } +#endif protected: - TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); + TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); void error(TInfoSink& infoSink, const char*); void warn(TInfoSink& infoSink, const char*); void mergeCallGraphs(TInfoSink&, TIntermediate&); void mergeModes(TInfoSink&, TIntermediate&); void mergeTrees(TInfoSink&, TIntermediate&); - void seedIdMap(TMap& idMap, int& maxId); - void remapIds(const TMap& idMap, int idShift, TIntermediate&); + void seedIdMap(TIdMaps& idMaps, long long& IdShift); + void remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate&); void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals); - void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects); + void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects, EShLanguage); + void mergeBlockDefinitions(TInfoSink&, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unitRoot); void mergeImplicitArraySizes(TType&, const TType&); - void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, bool crossStage); + void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, EShLanguage); void checkCallGraphCycles(TInfoSink&); void checkCallGraphBodies(TInfoSink&, bool keepUncalled); void inOutLocationCheck(TInfoSink&); - TIntermAggregate* findLinkerObjects() const; + void sharedBlockCheck(TInfoSink&); bool userOutputUsed() const; bool isSpecializationOperation(const TIntermOperator&) const; bool isNonuniformPropagating(TOperator) const; @@ -784,28 +1044,54 @@ protected: bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&); void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root); bool isConversionAllowed(TOperator op, TIntermTyped* node) const; - TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const; - std::tuple getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const; - bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();} + std::tuple getConversionDestinationType(TBasicType type0, TBasicType type1, TOperator op) const; + static const char* getResourceName(TResourceType); const EShLanguage language; // stage, known at construction time - EShSource source; // source language, known a bit later std::string entryPointName; std::string entryPointMangledName; typedef std::list TGraph; TGraph callGraph; +#ifdef GLSLANG_ANGLE + const EProfile profile = ECoreProfile; + const int version = 450; +#else EProfile profile; // source profile int version; // source version +#endif SpvVersion spvVersion; TIntermNode* treeRoot; std::set requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them - TBuiltInResource resources; + MustBeAssigned resources; int numEntryPoints; int numErrors; int numPushConstants; bool recursive; + bool invertY; + bool useStorageBuffer; + bool invariantAll; + bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN + bool depthReplacing; + int localSize[3]; + bool localSizeNotDefault[3]; + int localSizeSpecId[3]; + unsigned long long uniqueId; + + std::string globalUniformBlockName; + std::string atomicCounterBlockName; + unsigned int globalUniformBlockSet; + unsigned int globalUniformBlockBinding; + unsigned int atomicCounterBlockSet; + +#ifndef GLSLANG_WEB +public: + const char* const implicitThisName; + const char* const implicitCounterName; +protected: + EShSource source; // source language, known a bit later + bool useVulkanMemoryModel; int invocations; int vertices; TLayoutGeometry inputPrimitive; @@ -814,27 +1100,23 @@ protected: bool originUpperLeft; TVertexSpacing vertexSpacing; TVertexOrder vertexOrder; + TInterlockOrdering interlockOrdering; bool pointMode; - int localSize[3]; - int localSizeSpecId[3]; bool earlyFragmentTests; bool postDepthCoverage; TLayoutDepth depthLayout; - bool depthReplacing; bool hlslFunctionality1; int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift bool xfbMode; std::vector xfbBuffers; // all the data we need to track per xfb buffer bool multiStream; - -#ifdef NV_EXTENSIONS bool layoutOverrideCoverage; bool geoPassthroughEXT; - int numShaderRecordNVBlocks; + int numShaderRecordBlocks; ComputeDerivativeMode computeDerivativeMode; int primitives; int numTaskNVBlocks; -#endif + bool layoutPrimitiveCulling; // Base shift values std::array shiftBinding; @@ -845,22 +1127,37 @@ protected: std::vector resourceSetBinding; bool autoMapBindings; bool autoMapLocations; - bool invertY; bool flattenUniformArrays; bool useUnknownFormat; bool hlslOffsets; - bool useStorageBuffer; - bool useVulkanMemoryModel; bool hlslIoMapping; + bool useVariablePointers; - std::set ioAccessed; // set of names of statically read/written I/O that might need extra checking - std::vector usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers - std::vector usedAtomics; // sets of bindings used by atomic counters - std::unordered_set usedConstantId; // specialization constant ids used std::set semanticNameSet; EShTextureSamplerTransformMode textureSamplerTransformMode; + bool needToLegalize; + bool binaryDoubleOutput; + bool subgroupUniformControlFlow; + bool usePhysicalStorageBuffer; + + TSpirvRequirement* spirvRequirement; + TSpirvExecutionMode* spirvExecutionMode; + + std::unordered_map uniformLocationOverrides; + int uniformLocationBase; + TNumericFeatures numericFeatures; +#endif + std::unordered_map blockBackingOverrides; + + std::unordered_set usedConstantId; // specialization constant ids used + std::vector usedAtomics; // sets of bindings used by atomic counters + std::vector usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers + std::vector usedIoRT[2]; // sets of used location, one for rayPayload/rayPayloadIN and other + // for callableData/callableDataIn + // set of names of statically read/written I/O that might need extra checking + std::set ioAccessed; // source code of shader, useful as part of debug information std::string sourceFile; std::string sourceText; @@ -871,13 +1168,6 @@ protected: // for OpModuleProcessed, or equivalent TProcesses processes; - bool needToLegalize; - bool binaryDoubleOutput; - bool usePhysicalStorageBuffer; - - std::unordered_map uniformLocationOverrides; - int uniformLocationBase; - private: void operator=(TIntermediate&); // prevent assignments }; diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/parseConst.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/parseConst.cpp index 1a8e6d9..6c18299 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/parseConst.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/parseConst.cpp @@ -165,22 +165,31 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) } } } else { - // matrix from vector - int count = 0; - const int startIndex = index; + // matrix from vector or scalar int nodeComps = node->getType().computeNumComponents(); - for (int i = startIndex; i < endIndex; i++) { - if (i >= instanceSize) - return; - if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 ) + if (nodeComps == 1) { + for (int c = 0; c < matrixCols; ++c) { + for (int r = 0; r < matrixRows; ++r) { + if (r == c) + leftUnionArray[index] = rightUnionArray[0]; + else + leftUnionArray[index].setDConst(0.0); + index++; + } + } + } else { + int count = 0; + for (int i = index; i < endIndex; i++) { + if (i >= instanceSize) + return; + + // construct the matrix in column-major order, from + // the components provided, in order leftUnionArray[i] = rightUnionArray[count]; - else - leftUnionArray[i].setDConst(0.0); - index++; - - if (nodeComps > 1) + index++; count++; + } } } } diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/parseVersions.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/parseVersions.h index b5e229a..7248354 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/parseVersions.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/parseVersions.h @@ -57,26 +57,98 @@ public: TParseVersions(TIntermediate& interm, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) - : infoSink(infoSink), version(version), profile(profile), language(language), - spvVersion(spvVersion), forwardCompatible(forwardCompatible), - intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { } + : +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + forwardCompatible(forwardCompatible), + profile(profile), +#endif + infoSink(infoSink), version(version), + language(language), + spvVersion(spvVersion), + intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { } virtual ~TParseVersions() { } + void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc); + void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); +#ifdef GLSLANG_WEB + const EProfile profile = EEsProfile; + bool isEsProfile() const { return true; } + void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) + { + if (! (EEsProfile & profileMask)) + error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); + } + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, + const char* const extensions[], const char* featureDesc) + { + if ((EEsProfile & profileMask) && (minVersion == 0 || version < minVersion)) + error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); + } + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, + const char* featureDesc) + { + profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); + } + void initializeExtensionBehavior() { } + void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { } + void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { } + void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc) { } + void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc) { } + TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; } + bool extensionTurnedOn(const char* const extension) { return false; } + bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; } + void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { } + void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { } + void checkExtensionStage(const TSourceLoc&, const char* const extension) { } + void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior) { } + void fullIntegerCheck(const TSourceLoc&, const char* op) { } + void doubleCheck(const TSourceLoc&, const char* op) { } + bool float16Arithmetic() { return false; } + void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } + bool int16Arithmetic() { return false; } + void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } + bool int8Arithmetic() { return false; } + void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } + void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } + void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { } + void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } + bool relaxedErrors() const { return false; } + bool suppressWarnings() const { return true; } + bool isForwardCompatible() const { return false; } +#else +#ifdef GLSLANG_ANGLE + const bool forwardCompatible = true; + const EProfile profile = ECoreProfile; +#else + bool forwardCompatible; // true if errors are to be given for use of deprecated features + EProfile profile; // the declared profile in the shader (core by default) +#endif + bool isEsProfile() const { return profile == EEsProfile; } + void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc); + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, + const char* const extensions[], const char* featureDesc); + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, + const char* featureDesc); virtual void initializeExtensionBehavior(); - virtual void requireProfile(const TSourceLoc&, int queryProfiles, const char* featureDesc); - virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc); - virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, const char* const extension, const char* featureDesc); - virtual void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc); - virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc); virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc); - virtual void unimplemented(const TSourceLoc&, const char* featureDesc); - virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); - virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); + virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc); + virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc); virtual TExtensionBehavior getExtensionBehavior(const char*); virtual bool extensionTurnedOn(const char* const extension); virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]); virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior); + virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior); + virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc); + virtual void checkExtensionStage(const TSourceLoc&, const char* const extension); + virtual void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior); virtual void fullIntegerCheck(const TSourceLoc&, const char* op); + + virtual void unimplemented(const TSourceLoc&, const char* featureDesc); virtual void doubleCheck(const TSourceLoc&, const char* op); virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false); virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); @@ -88,23 +160,36 @@ public: virtual void int8ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); virtual bool int8Arithmetic(); virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); -#ifdef AMD_EXTENSIONS virtual void float16OpaqueCheck(const TSourceLoc&, const char* op, bool builtIn = false); -#endif virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false); virtual void explicitInt8Check(const TSourceLoc&, const char* op, bool builtIn = false); virtual void explicitInt16Check(const TSourceLoc&, const char* op, bool builtIn = false); virtual void explicitInt32Check(const TSourceLoc&, const char* op, bool builtIn = false); virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false); virtual void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void intcoopmatCheck(const TSourceLoc&, const char *op, bool builtIn = false); + bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } + bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } + bool isForwardCompatible() const { return forwardCompatible; } +#endif // GLSLANG_WEB virtual void spvRemoved(const TSourceLoc&, const char* op); virtual void vulkanRemoved(const TSourceLoc&, const char* op); virtual void requireVulkan(const TSourceLoc&, const char* op); virtual void requireSpv(const TSourceLoc&, const char* op); - virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); - virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior); - virtual void checkExtensionStage(const TSourceLoc&, const char* const extension); + virtual void requireSpv(const TSourceLoc&, const char *op, unsigned int version); + +#if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL) + void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) { addError(); } + void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) { } + void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) { addError(); } + void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) { } +#else virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...) = 0; virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, @@ -113,6 +198,7 @@ public: const char* szExtraInfoFormat, ...) = 0; virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...) = 0; +#endif void addError() { ++numErrors; } int getNumErrors() const { return numErrors; } @@ -126,24 +212,25 @@ public: void setCurrentString(int string) { currentScanner->setString(string); } void getPreamble(std::string&); - bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } - bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } +#ifdef ENABLE_HLSL bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; } bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; } +#else + bool isReadingHLSL() const { return false; } +#endif TInfoSink& infoSink; // compilation mode int version; // version, updated by #version in the shader - EProfile profile; // the declared profile in the shader (core by default) EShLanguage language; // really the stage SpvVersion spvVersion; - bool forwardCompatible; // true if errors are to be given for use of deprecated features TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree protected: - TMap extensionBehavior; // for each extension string, what its current behavior is set to + TMap extensionBehavior; // for each extension string, what its current behavior is + TMap extensionMinSpv; // for each extension string, store minimum spirv required EShMessages messages; // errors/warnings/rule-sets int numErrors; // number of compile-time errors encountered TInputScanner* currentScanner; diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/pch.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/pch.h new file mode 100644 index 0000000..6ea3761 --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/pch.h @@ -0,0 +1,49 @@ +#ifndef _PCH_H +#define _PCH_H +// +// Copyright (C) 2018 The Khronos Group Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#include +#include +#include +#include +#include +#include +#include +#include +#include "SymbolTable.h" +#include "ParseHelper.h" +#include "Scan.h" +#include "ScanContext.h" + +#endif /* _PCH_H */ diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/Pp.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/Pp.cpp index 3441948..aa1e0d7 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -147,6 +147,10 @@ int TPpContext::CPPdefine(TPpToken* ppToken) } token = scanToken(ppToken); + } else if (token != '\n' && token != EndOfInput && !ppToken->space) { + parseContext.ppWarn(ppToken->loc, "missing space after macro name", "#define", ""); + + return token; } // record the definition of the macro @@ -162,29 +166,43 @@ int TPpContext::CPPdefine(TPpToken* ppToken) if (existing != nullptr) { if (! existing->undef) { // Already defined -- need to make sure they are identical: - // "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, - // ordering, spelling, and white-space separation, where all white-space separations are considered identical." - if (existing->functionLike != mac.functionLike) - parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define", atomStrings.getString(defAtom)); - else if (existing->args.size() != mac.args.size()) - parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom)); - else { - if (existing->args != mac.args) - parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom)); + // "Two replacement lists are identical if and only if the + // preprocessing tokens in both have the same number, + // ordering, spelling, and white-space separation, where all + // white-space separations are considered identical." + if (existing->functionLike != mac.functionLike) { + parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define", + atomStrings.getString(defAtom)); + } else if (existing->args.size() != mac.args.size()) { + parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", + atomStrings.getString(defAtom)); + } else { + if (existing->args != mac.args) { + parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", + atomStrings.getString(defAtom)); + } + // set up to compare the two existing->body.reset(); mac.body.reset(); int newToken; + bool firstToken = true; do { int oldToken; TPpToken oldPpToken; TPpToken newPpToken; oldToken = existing->body.getToken(parseContext, &oldPpToken); newToken = mac.body.getToken(parseContext, &newPpToken); + // for the first token, preceding spaces don't matter + if (firstToken) { + newPpToken.space = oldPpToken.space; + firstToken = false; + } if (oldToken != newToken || oldPpToken != newPpToken) { - parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom)); + parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", + atomStrings.getString(defAtom)); break; } - } while (newToken > 0); + } while (newToken != EndOfInput); } } *existing = mac; @@ -404,10 +422,10 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo if (! parseContext.isReadingHLSL() && isMacroInput()) { if (parseContext.relaxedErrors()) parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression", - "defined", ""); + "defined", ""); else parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros", - "defined", ""); + "defined", ""); } bool needclose = 0; token = scanToken(ppToken); @@ -437,6 +455,7 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo token = scanToken(ppToken); } } else { + token = tokenPaste(token, *ppToken); token = evalToToken(token, shortCircuit, res, err, ppToken); return eval(token, precedence, shortCircuit, res, err, ppToken); } @@ -527,7 +546,7 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, T case MacroExpandStarted: break; case MacroExpandUndef: - if (! shortCircuit && parseContext.profile == EEsProfile) { + if (! shortCircuit && parseContext.isEsProfile()) { const char* message = "undefined macro in expression not allowed in es profile"; if (parseContext.relaxedErrors()) parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", ppToken->name); @@ -603,14 +622,25 @@ int TPpContext::CPPinclude(TPpToken* ppToken) { const TSourceLoc directiveLoc = ppToken->loc; bool startWithLocalSearch = true; // to additionally include the extra "" paths - int token = scanToken(ppToken); + int token; - // handle -style #include - if (token == '<') { + // Find the first non-whitespace char after #include + int ch = getChar(); + while (ch == ' ' || ch == '\t') { + ch = getChar(); + } + if (ch == '<') { + // style startWithLocalSearch = false; token = scanHeaderName(ppToken, '>'); + } else if (ch == '"') { + // "header-name" style + token = scanHeaderName(ppToken, '"'); + } else { + // unexpected, get the full token to generate the error + ungetChar(); + token = scanToken(ppToken); } - // otherwise ppToken already has the header name and it was "header-name" style if (token != PpAtomConstString) { parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", ""); @@ -693,7 +723,9 @@ int TPpContext::CPPline(TPpToken* ppToken) const char* sourceName = nullptr; // Optional source file name. bool lineErr = false; bool fileErr = false; + disableEscapeSequences = true; token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken); + disableEscapeSequences = false; if (! lineErr) { lineToken = lineRes; if (token == '\n') @@ -704,6 +736,7 @@ int TPpContext::CPPline(TPpToken* ppToken) parseContext.setCurrentLine(lineRes); if (token != '\n') { +#ifndef GLSLANG_WEB if (token == PpAtomConstString) { parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line"); // We need to save a copy of the string instead of pointing @@ -713,7 +746,9 @@ int TPpContext::CPPline(TPpToken* ppToken) parseContext.setCurrentSourceName(sourceName); hasFile = true; token = scanToken(ppToken); - } else { + } else +#endif + { token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken); if (! fileErr) { parseContext.setCurrentString(fileRes); @@ -733,7 +768,9 @@ int TPpContext::CPPline(TPpToken* ppToken) // Handle #error int TPpContext::CPPerror(TPpToken* ppToken) { + disableEscapeSequences = true; int token = scanToken(ppToken); + disableEscapeSequences = false; std::string message; TSourceLoc loc = ppToken->loc; @@ -774,10 +811,8 @@ int TPpContext::CPPpragma(TPpToken* ppToken) case PpAtomConstUint: case PpAtomConstInt64: case PpAtomConstUint64: -#ifdef AMD_EXTENSIONS case PpAtomConstInt16: case PpAtomConstUint16: -#endif case PpAtomConstFloat: case PpAtomConstDouble: case PpAtomConstFloat16: @@ -862,8 +897,7 @@ int TPpContext::CPPextension(TPpToken* ppToken) if (token != PpAtomIdentifier) parseContext.ppError(ppToken->loc, "extension name expected", "#extension", ""); - assert(strlen(ppToken->name) <= MaxTokenLength); - strcpy(extensionName, ppToken->name); + snprintf(extensionName, sizeof(extensionName), "%s", ppToken->name); token = scanToken(ppToken); if (token != ':') { @@ -937,18 +971,20 @@ int TPpContext::readCPPline(TPpToken* ppToken) case PpAtomIfndef: token = CPPifdef(0, ppToken); break; + case PpAtomLine: + token = CPPline(ppToken); + break; +#ifndef GLSLANG_WEB case PpAtomInclude: if(!parseContext.isReadingHLSL()) { parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include"); } token = CPPinclude(ppToken); break; - case PpAtomLine: - token = CPPline(ppToken); - break; case PpAtomPragma: token = CPPpragma(ppToken); break; +#endif case PpAtomUndef: token = CPPundef(ppToken); break; @@ -1023,7 +1059,9 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* case MacroExpandNotStarted: break; case MacroExpandError: - token = EndOfInput; + // toss the rest of the pushed-input argument by scanning until tMarkerInput + while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) + ; break; case MacroExpandStarted: case MacroExpandUndef: @@ -1035,13 +1073,10 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* expandedArg->putToken(token, ppToken); } - if (token == EndOfInput) { + if (token != tMarkerInput::marker) { // Error, or MacroExpand ate the marker, so had bad input, recover delete expandedArg; expandedArg = nullptr; - } else { - // remove the marker - popInput(); } return expandedArg; @@ -1150,7 +1185,9 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b int macroAtom = atomStrings.getAtom(ppToken->name); switch (macroAtom) { case PpAtomLineMacro: - ppToken->ival = parseContext.getCurrentLoc().line; + // Arguments which are macro have been replaced in the first stage. + if (ppToken->ival == 0) + ppToken->ival = parseContext.getCurrentLoc().line; snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival); UngetToken(PpAtomConstInt, ppToken); return MacroExpandStarted; @@ -1251,6 +1288,11 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b nestStack.push_back('}'); else if (nestStack.size() > 0 && token == nestStack.back()) nestStack.pop_back(); + + //Macro replacement list is expanded in the last stage. + if (atomStrings.getAtom(ppToken->name) == PpAtomLineMacro) + ppToken->ival = parseContext.getCurrentLoc().line; + in->args[arg]->putToken(token, ppToken); tokenRecorded = true; } @@ -1258,7 +1300,7 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b if (token == ')') { // closing paren of call - if (in->mac->args.size() == 1 && tokenRecorded == 0) + if (in->mac->args.size() == 1 && !tokenRecorded) break; arg++; break; diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpContext.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpContext.cpp index cc003a8..1363ce2 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpContext.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpContext.cpp @@ -87,7 +87,8 @@ namespace glslang { TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) : preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false), rootFileName(rootFileName), - currentSourceFile(rootFileName) + currentSourceFile(rootFileName), + disableEscapeSequences(false) { ifdepth = 0; for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++) diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpContext.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpContext.h index 73fe5e3..714b5ea 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpContext.h @@ -84,6 +84,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "../ParseHelper.h" +#include "PpTokens.h" /* windows only pragma */ #ifdef _MSC_VER @@ -104,13 +105,13 @@ public: } // Used for comparing macro definitions, so checks what is relevant for that. - bool operator==(const TPpToken& right) + bool operator==(const TPpToken& right) const { return space == right.space && ival == right.ival && dval == right.dval && i64val == right.i64val && strncmp(name, right.name, MaxTokenLength) == 0; } - bool operator!=(const TPpToken& right) { return ! operator==(right); } + bool operator!=(const TPpToken& right) const { return ! operator==(right); } TSourceLoc loc; // True if a space (for white space or a removed comment) should also be @@ -212,7 +213,8 @@ public: virtual int scan(TPpToken*) = 0; virtual int getch() = 0; virtual void ungetch() = 0; - virtual bool peekPasting() { return false; } // true when about to see ## + virtual bool peekPasting() { return false; } // true when about to see ## + virtual bool peekContinuedPasting(int) { return false; } // true when non-spaced tokens can paste virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define) virtual bool isMacroInput() { return false; } @@ -243,24 +245,79 @@ public: // From PpTokens.cpp // + // Capture the needed parts of a token stream for macro recording/playback. class TokenStream { public: - TokenStream() : current(0) { } + // Manage a stream of these 'Token', which capture the relevant parts + // of a TPpToken, plus its atom. + class Token { + public: + Token(int atom, const TPpToken& ppToken) : + atom(atom), + space(ppToken.space), + i64val(ppToken.i64val), + name(ppToken.name) { } + int get(TPpToken& ppToken) + { + ppToken.clear(); + ppToken.space = space; + ppToken.i64val = i64val; + snprintf(ppToken.name, sizeof(ppToken.name), "%s", name.c_str()); + return atom; + } + bool isAtom(int a) const { return atom == a; } + int getAtom() const { return atom; } + bool nonSpaced() const { return !space; } + protected: + Token() {} + int atom; + bool space; // did a space precede the token? + long long i64val; + TString name; + }; + + TokenStream() : currentPos(0) { } void putToken(int token, TPpToken* ppToken); + bool peekToken(int atom) { return !atEnd() && stream[currentPos].isAtom(atom); } + bool peekContinuedPasting(int atom) + { + // This is basically necessary because, for example, the PP + // tokenizer only accepts valid numeric-literals plus suffixes, so + // separates numeric-literals plus bad suffix into two tokens, which + // should get both pasted together as one token when token pasting. + // + // The following code is a bit more generalized than the above example. + if (!atEnd() && atom == PpAtomIdentifier && stream[currentPos].nonSpaced()) { + switch(stream[currentPos].getAtom()) { + case PpAtomConstInt: + case PpAtomConstUint: + case PpAtomConstInt64: + case PpAtomConstUint64: + case PpAtomConstInt16: + case PpAtomConstUint16: + case PpAtomConstFloat: + case PpAtomConstDouble: + case PpAtomConstFloat16: + case PpAtomConstString: + case PpAtomIdentifier: + return true; + default: + break; + } + } + + return false; + } int getToken(TParseContextBase&, TPpToken*); - bool atEnd() { return current >= data.size(); } + bool atEnd() { return currentPos >= stream.size(); } bool peekTokenizedPasting(bool lastTokenPastes); bool peekUntokenizedPasting(); - void reset() { current = 0; } + void reset() { currentPos = 0; } protected: - void putSubtoken(char); - int getSubtoken(); - void ungetSubtoken(); - - TVector data; - size_t current; + TVector stream; + size_t currentPos; }; // @@ -320,6 +377,10 @@ protected: int getChar() { return inputStack.back()->getch(); } void ungetChar() { inputStack.back()->ungetch(); } bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); } + bool peekContinuedPasting(int a) + { + return !inputStack.empty() && inputStack.back()->peekContinuedPasting(a); + } bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); } bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); } @@ -344,6 +405,7 @@ protected: virtual int getch() override { assert(0); return EndOfInput; } virtual void ungetch() override { assert(0); } bool peekPasting() override { return prepaste; } + bool peekContinuedPasting(int a) override { return mac->body.peekContinuedPasting(a); } bool endOfReplacementList() override { return mac->body.atEnd(); } bool isMacroInput() override { return true; } @@ -418,14 +480,18 @@ protected: class tTokenInput : public tInput { public: - tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : tInput(pp), tokens(t), lastTokenPastes(prepasting) { } + tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : + tInput(pp), + tokens(t), + lastTokenPastes(prepasting) { } virtual int scan(TPpToken *ppToken) override { return tokens->getToken(pp->parseContext, ppToken); } virtual int getch() override { assert(0); return EndOfInput; } virtual void ungetch() override { assert(0); } virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); } + bool peekContinuedPasting(int a) override { return tokens->peekContinuedPasting(a); } protected: TokenStream* tokens; - bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token + bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token }; class tUngotTokenInput : public tInput { @@ -629,6 +695,7 @@ protected: std::string currentSourceFile; std::istringstream strtodStream; + bool disableEscapeSequences; }; } // end namespace glslang diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpScanner.cpp index 8dd1036..ad11792 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -96,12 +96,19 @@ namespace glslang { /////////////////////////////////// Floating point constants: ///////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// -/* -* lFloatConst() - Scan a single- or double-precision floating point constant. Assumes that the scanner -* has seen at least one digit, followed by either a decimal '.' or the -* letter 'e', or a precision ending (e.g., F or LF). -*/ - +// +// Scan a single- or double-precision floating point constant. +// Assumes that the scanner has seen at least one digit, +// followed by either a decimal '.' or the letter 'e', or a +// precision ending (e.g., F or LF). +// +// This is technically not correct, as the preprocessor should just +// accept the numeric literal along with whatever suffix it has, but +// currently, it stops on seeing a bad suffix, treating that as the +// next token. This effects things like token pasting, where it is +// relevant how many tokens something was broken into. +// +// See peekContinuedPasting(). int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) { const auto saveName = [&](int ch) { @@ -135,6 +142,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) ch = getChar(); int firstDecimal = len; +#ifdef ENABLE_HLSL // 1.#INF or -1.#INF if (ch == '#' && (ifdepth > 0 || parseContext.intermediate.getSource() == EShSourceHlsl)) { if ((len < 2) || @@ -162,6 +170,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) } } } +#endif // Consume leading-zero digits after the decimal point while (ch == '0') { @@ -250,6 +259,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) // Suffix: bool isDouble = false; bool isFloat16 = false; +#ifndef GLSLANG_WEB if (ch == 'l' || ch == 'L') { if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl) parseContext.doubleCheck(ppToken->loc, "double floating-point suffix"); @@ -288,11 +298,15 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) saveName(ch); isFloat16 = true; } - } else if (ch == 'f' || ch == 'F') { + } else +#endif + if (ch == 'f' || ch == 'F') { +#ifndef GLSLANG_WEB if (ifdepth == 0) parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix"); if (ifdepth == 0 && !parseContext.relaxedErrors()) parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix"); +#endif if (ifdepth == 0 && !hasDecimalOrExponent) parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); saveName(ch); @@ -435,6 +449,14 @@ int TPpContext::characterLiteral(TPpToken* ppToken) // // Scanner used to tokenize source stream. // +// N.B. Invalid numeric suffixes are not consumed.// +// This is technically not correct, as the preprocessor should just +// accept the numeric literal along with whatever suffix it has, but +// currently, it stops on seeing a bad suffix, treating that as the +// next token. This effects things like token pasting, where it is +// relevant how many tokens something was broken into. +// See peekContinuedPasting(). +// int TPpContext::tStringInput::scan(TPpToken* ppToken) { int AlreadyComplained = 0; @@ -453,9 +475,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) static const int Num_Int64_Extensions = sizeof(Int64_Extensions) / sizeof(Int64_Extensions[0]); static const char* const Int16_Extensions[] = { -#ifdef AMD_EXTENSIONS E_GL_AMD_gpu_shader_int16, -#endif E_GL_EXT_shader_explicit_arithmetic_types, E_GL_EXT_shader_explicit_arithmetic_types_int16 }; static const int Num_Int16_Extensions = sizeof(Int16_Extensions) / sizeof(Int16_Extensions[0]); @@ -564,6 +584,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; +#ifndef GLSLANG_WEB int nextCh = getch(); if (nextCh == 'l' || nextCh == 'L') { if (len < MaxTokenLength) @@ -572,7 +593,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) } else ungetch(); -#ifdef AMD_EXTENSIONS nextCh = getch(); if ((nextCh == 's' || nextCh == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { @@ -581,12 +601,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) isInt16 = true; } else ungetch(); -#endif } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; -#ifdef AMD_EXTENSIONS } else if ((ch == 's' || ch == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { if (len < MaxTokenLength) @@ -674,6 +692,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; +#ifndef GLSLANG_WEB int nextCh = getch(); if (nextCh == 'l' || nextCh == 'L') { if (len < MaxTokenLength) @@ -682,7 +701,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) } else ungetch(); -#ifdef AMD_EXTENSIONS nextCh = getch(); if ((nextCh == 's' || nextCh == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { @@ -691,12 +709,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) isInt16 = true; } else ungetch(); -#endif } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; -#ifdef AMD_EXTENSIONS } else if ((ch == 's' || ch == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { if (len < MaxTokenLength) @@ -765,6 +781,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; +#ifndef GLSLANG_WEB int nextCh = getch(); if (nextCh == 'l' || nextCh == 'L') { if (len < MaxTokenLength) @@ -773,7 +790,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) } else ungetch(); -#ifdef AMD_EXTENSIONS nextCh = getch(); if ((nextCh == 's' || nextCh == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { @@ -782,12 +798,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) isInt16 = true; } else ungetch(); -#endif } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; -#ifdef AMD_EXTENSIONS } else if ((ch == 's' || ch == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { if (len < MaxTokenLength) @@ -1012,12 +1026,80 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) case '\'': return pp->characterLiteral(ppToken); case '"': - // TODO: If this gets enhanced to handle escape sequences, or - // anything that is different than what #include needs, then - // #include needs to use scanHeaderName() for this. + // #include uses scanHeaderName() to ignore these escape sequences. ch = getch(); while (ch != '"' && ch != '\n' && ch != EndOfInput) { if (len < MaxTokenLength) { + if (ch == '\\' && !pp->disableEscapeSequences) { + int nextCh = getch(); + switch (nextCh) { + case '\'': ch = 0x27; break; + case '"': ch = 0x22; break; + case '?': ch = 0x3f; break; + case '\\': ch = 0x5c; break; + case 'a': ch = 0x07; break; + case 'b': ch = 0x08; break; + case 'f': ch = 0x0c; break; + case 'n': ch = 0x0a; break; + case 'r': ch = 0x0d; break; + case 't': ch = 0x09; break; + case 'v': ch = 0x0b; break; + case 'x': + // Hex value, arbitrary number of characters. Terminated by the first + // non-hex digit + { + int numDigits = 0; + ch = 0; + while (true) { + nextCh = getch(); + if (nextCh >= '0' && nextCh <= '9') + nextCh -= '0'; + else if (nextCh >= 'A' && nextCh <= 'F') + nextCh -= 'A' - 10; + else if (nextCh >= 'a' && nextCh <= 'f') + nextCh -= 'a' - 10; + else { + ungetch(); + break; + } + numDigits++; + ch = ch * 0x10 + nextCh; + } + if (numDigits == 0) { + pp->parseContext.ppError(ppToken->loc, "Expected hex value in escape sequence", "string", ""); + } + break; + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + // Octal value, up to three octal digits + { + int numDigits = 1; + ch = nextCh - '0'; + while (numDigits < 3) { + nextCh = getch(); + if (nextCh >= '0' && nextCh <= '7') + nextCh -= '0'; + else { + ungetch(); + break; + } + numDigits++; + ch = ch * 8 + nextCh; + } + break; + } + default: + pp->parseContext.ppError(ppToken->loc, "Invalid escape sequence", "string", ""); + break; + } + } ppToken->name[len] = (char)ch; len++; ch = getch(); @@ -1106,17 +1188,21 @@ int TPpContext::tokenize(TPpToken& ppToken) continue; break; case PpAtomConstString: + // HLSL allows string literals. + // GLSL allows string literals with GL_EXT_debug_printf. if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) { - // HLSL allows string literals. - parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", ""); - continue; + const char* const string_literal_EXTs[] = { E_GL_EXT_debug_printf, E_GL_EXT_spirv_intrinsics }; + parseContext.requireExtensions(ppToken.loc, 2, string_literal_EXTs, "string literal"); + if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf) && + !parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) + continue; } break; case '\'': parseContext.ppError(ppToken.loc, "character literals not supported", "\'", ""); continue; default: - strcpy(ppToken.name, atomStrings.getString(token)); + snprintf(ppToken.name, sizeof(ppToken.name), "%s", atomStrings.getString(token)); break; } @@ -1153,61 +1239,69 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken) break; } - // get the token after the ## - token = scanToken(&pastedPpToken); + // Get the token(s) after the ##. + // Because of "space" semantics, and prior tokenization, what + // appeared a single token, e.g. "3A", might have been tokenized + // into two tokens "3" and "A", but the "A" will have 'space' set to + // false. Accumulate all of these to recreate the original lexical + // appearing token. + do { + token = scanToken(&pastedPpToken); - // This covers end of argument expansion - if (token == tMarkerInput::marker) { - parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", ""); - break; - } + // This covers end of argument expansion + if (token == tMarkerInput::marker) { + parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", ""); + return resultToken; + } - // get the token text - switch (resultToken) { - case PpAtomIdentifier: - // already have the correct text in token.names - break; - case '=': - case '!': - case '-': - case '~': - case '+': - case '*': - case '/': - case '%': - case '<': - case '>': - case '|': - case '^': - case '&': - case PpAtomRight: - case PpAtomLeft: - case PpAtomAnd: - case PpAtomOr: - case PpAtomXor: - strcpy(ppToken.name, atomStrings.getString(resultToken)); - strcpy(pastedPpToken.name, atomStrings.getString(token)); - break; - default: - parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", ""); - return resultToken; - } + // get the token text + switch (resultToken) { + case PpAtomIdentifier: + // already have the correct text in token.names + break; + case '=': + case '!': + case '-': + case '~': + case '+': + case '*': + case '/': + case '%': + case '<': + case '>': + case '|': + case '^': + case '&': + case PpAtomRight: + case PpAtomLeft: + case PpAtomAnd: + case PpAtomOr: + case PpAtomXor: + snprintf(ppToken.name, sizeof(ppToken.name), "%s", atomStrings.getString(resultToken)); + snprintf(pastedPpToken.name, sizeof(pastedPpToken.name), "%s", atomStrings.getString(token)); + break; + default: + parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", ""); + return resultToken; + } - // combine the tokens - if (strlen(ppToken.name) + strlen(pastedPpToken.name) > MaxTokenLength) { - parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", ""); - return resultToken; - } - strncat(ppToken.name, pastedPpToken.name, MaxTokenLength - strlen(ppToken.name)); + // combine the tokens + if (strlen(ppToken.name) + strlen(pastedPpToken.name) > MaxTokenLength) { + parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", ""); + return resultToken; + } + snprintf(&ppToken.name[0] + strlen(ppToken.name), sizeof(ppToken.name) - strlen(ppToken.name), + "%s", pastedPpToken.name); - // correct the kind of token we are making, if needed (identifiers stay identifiers) - if (resultToken != PpAtomIdentifier) { - int newToken = atomStrings.getAtom(ppToken.name); - if (newToken > 0) - resultToken = newToken; - else - parseContext.ppError(ppToken.loc, "combined token is invalid", "##", ""); - } + // correct the kind of token we are making, if needed (identifiers stay identifiers) + if (resultToken != PpAtomIdentifier) { + int newToken = atomStrings.getAtom(ppToken.name); + if (newToken > 0) + resultToken = newToken; + else + parseContext.ppError(ppToken.loc, "combined token is invalid", "##", ""); + } + } while (peekContinuedPasting(resultToken)); } return resultToken; diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpTokens.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpTokens.cpp index f8029f5..7ed5870 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpTokens.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/preprocessor/PpTokens.cpp @@ -99,150 +99,34 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace glslang { - -namespace { - - // When recording (and playing back) should the backing name string - // be saved (restored)? - bool SaveName(int atom) - { - switch (atom) { - case PpAtomIdentifier: - case PpAtomConstString: - case PpAtomConstInt: - case PpAtomConstUint: - case PpAtomConstInt64: - case PpAtomConstUint64: - #ifdef AMD_EXTENSIONS - case PpAtomConstInt16: - case PpAtomConstUint16: - #endif - case PpAtomConstFloat: - case PpAtomConstDouble: - case PpAtomConstFloat16: - return true; - default: - return false; - } - } - - // When recording (and playing back) should the numeric value - // be saved (restored)? - bool SaveValue(int atom) - { - switch (atom) { - case PpAtomConstInt: - case PpAtomConstUint: - case PpAtomConstInt64: - case PpAtomConstUint64: - #ifdef AMD_EXTENSIONS - case PpAtomConstInt16: - case PpAtomConstUint16: - #endif - case PpAtomConstFloat: - case PpAtomConstDouble: - case PpAtomConstFloat16: - return true; - default: - return false; - } - } -} - -// push onto back of stream -void TPpContext::TokenStream::putSubtoken(char subtoken) -{ - data.push_back(static_cast(subtoken)); -} - -// get the next token in stream -int TPpContext::TokenStream::getSubtoken() -{ - if (current < data.size()) - return data[current++]; - else - return EndOfInput; -} - -// back up one position in the stream -void TPpContext::TokenStream::ungetSubtoken() -{ - if (current > 0) - --current; -} - -// Add a complete token (including backing string) to the end of a list -// for later playback. +// Add a token (including backing string) to the end of a macro +// token stream, for later playback. void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken) { - // save the atom - assert((atom & ~0xff) == 0); - putSubtoken(static_cast(atom)); - - // save the backing name string - if (SaveName(atom)) { - const char* s = ppToken->name; - while (*s) - putSubtoken(*s++); - putSubtoken(0); - } - - // save the numeric value - if (SaveValue(atom)) { - const char* n = reinterpret_cast(&ppToken->i64val); - for (size_t i = 0; i < sizeof(ppToken->i64val); ++i) - putSubtoken(*n++); - } + TokenStream::Token streamToken(atom, *ppToken); + stream.push_back(streamToken); } -// Read the next token from a token stream. -// (Not the source stream, but a stream used to hold a tokenized macro). +// Read the next token from a macro token stream. int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken) { - // get the atom - int atom = getSubtoken(); - if (atom == EndOfInput) - return atom; + if (atEnd()) + return EndOfInput; - // init the token - ppToken->clear(); + int atom = stream[currentPos++].get(*ppToken); ppToken->loc = parseContext.getCurrentLoc(); - // get the backing name string - if (SaveName(atom)) { - int ch = getSubtoken(); - int len = 0; - while (ch != 0 && ch != EndOfInput) { - if (len < MaxTokenLength) { - ppToken->name[len] = (char)ch; - len++; - ch = getSubtoken(); - } else { - parseContext.error(ppToken->loc, "token too long", "", ""); - break; - } - } - ppToken->name[len] = 0; - } - +#ifndef GLSLANG_WEB // Check for ##, unless the current # is the last character if (atom == '#') { - if (current < data.size()) { - if (getSubtoken() == '#') { - parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); - parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); - atom = PpAtomPaste; - } else - ungetSubtoken(); + if (peekToken('#')) { + parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); + parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); + currentPos++; + atom = PpAtomPaste; } } - - // get the numeric value - if (SaveValue(atom)) { - char* n = reinterpret_cast(&ppToken->i64val); - for (size_t i = 0; i < sizeof(ppToken->i64val); ++i) - *n++ = (char)getSubtoken(); - } +#endif return atom; } @@ -256,15 +140,14 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes) { // 1. preceding ##? - size_t savePos = current; - int subtoken; + size_t savePos = currentPos; // skip white space - do { - subtoken = getSubtoken(); - } while (subtoken == ' '); - current = savePos; - if (subtoken == PpAtomPaste) + while (peekToken(' ')) + ++currentPos; + if (peekToken(PpAtomPaste)) { + currentPos = savePos; return true; + } // 2. last token and we've been told after this there will be a ## @@ -273,18 +156,18 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes) // Getting here means the last token will be pasted, after this // Are we at the last non-whitespace token? - savePos = current; + savePos = currentPos; bool moreTokens = false; do { - subtoken = getSubtoken(); - if (subtoken == EndOfInput) + if (atEnd()) break; - if (subtoken != ' ') { + if (!peekToken(' ')) { moreTokens = true; break; } + ++currentPos; } while (true); - current = savePos; + currentPos = savePos; return !moreTokens; } @@ -293,23 +176,21 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes) bool TPpContext::TokenStream::peekUntokenizedPasting() { // don't return early, have to restore this - size_t savePos = current; + size_t savePos = currentPos; // skip white-space - int subtoken; - do { - subtoken = getSubtoken(); - } while (subtoken == ' '); + while (peekToken(' ')) + ++currentPos; // check for ## bool pasting = false; - if (subtoken == '#') { - subtoken = getSubtoken(); - if (subtoken == '#') + if (peekToken('#')) { + ++currentPos; + if (peekToken('#')) pasting = true; } - current = savePos; + currentPos = savePos; return pasting; } diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/propagateNoContraction.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/propagateNoContraction.cpp index ae95688..9def592 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/propagateNoContraction.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/propagateNoContraction.cpp @@ -37,6 +37,8 @@ // propagate the 'noContraction' qualifier. // +#ifndef GLSLANG_WEB + #include "propagateNoContraction.h" #include @@ -79,7 +81,7 @@ typedef std::unordered_set ReturnBranchNodeSet; // the node has 'noContraction' qualifier, otherwise false. bool isPreciseObjectNode(glslang::TIntermTyped* node) { - return node->getType().getQualifier().noContraction; + return node->getType().getQualifier().isNoContraction(); } // Returns true if the opcode is a dereferencing one. @@ -864,3 +866,5 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate) } } }; + +#endif // GLSLANG_WEB diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.cpp b/thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.cpp index b696686..9ea48c4 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.cpp +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.cpp @@ -33,6 +33,8 @@ // POSSIBILITY OF SUCH DAMAGE. // +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + #include "../Include/Common.h" #include "reflection.h" #include "LiveTraverser.h" @@ -75,10 +77,10 @@ namespace glslang { // This is in the glslang namespace directly so it can be a friend of TReflection. // -class TReflectionTraverser : public TLiveTraverser { +class TReflectionTraverser : public TIntermTraverser { public: TReflectionTraverser(const TIntermediate& i, TReflection& r) : - TLiveTraverser(i), reflection(r) { } + TIntermTraverser(), intermediate(i), reflection(r), updateStageMasks(true) { } virtual bool visitBinary(TVisit, TIntermBinary* node); virtual void visitSymbol(TIntermSymbol* base); @@ -90,83 +92,96 @@ public: if (processedDerefs.find(&base) == processedDerefs.end()) { processedDerefs.insert(&base); + int blockIndex = -1; + int offset = -1; + TList derefs; + TString baseName = base.getName(); + + if (base.getType().getBasicType() == EbtBlock) { + offset = 0; + bool anonymous = IsAnonymous(baseName); + const TString& blockName = base.getType().getTypeName(); + + if (!anonymous) + baseName = blockName; + else + baseName = ""; + + blockIndex = addBlockName(blockName, base.getType(), intermediate.getBlockSize(base.getType())); + } + // Use a degenerate (empty) set of dereferences to immediately put as at the end of // the dereference change expected by blowUpActiveAggregate. - TList derefs; - blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0); + blowUpActiveAggregate(base.getType(), baseName, derefs, derefs.end(), offset, blockIndex, 0, -1, 0, + base.getQualifier().storage, updateStageMasks); } } - void addAttribute(const TIntermSymbol& base) + void addPipeIOVariable(const TIntermSymbol& base) { if (processedDerefs.find(&base) == processedDerefs.end()) { processedDerefs.insert(&base); const TString &name = base.getName(); const TType &type = base.getType(); + const bool input = base.getQualifier().isPipeInput(); - TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); - if (it == reflection.nameToIndex.end()) { - reflection.nameToIndex[name.c_str()] = (int)reflection.indexToAttribute.size(); - reflection.indexToAttribute.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0)); + TReflection::TMapIndexToReflection &ioItems = + input ? reflection.indexToPipeInput : reflection.indexToPipeOutput; + + + TReflection::TNameToIndex &ioMapper = + input ? reflection.pipeInNameToIndex : reflection.pipeOutNameToIndex; + + if (reflection.options & EShReflectionUnwrapIOBlocks) { + bool anonymous = IsAnonymous(name); + + TString baseName; + if (type.getBasicType() == EbtBlock) { + baseName = anonymous ? TString() : type.getTypeName(); + } else { + baseName = anonymous ? TString() : name; + } + + // by convention if this is an arrayed block we ignore the array in the reflection + if (type.isArray() && type.getBasicType() == EbtBlock) { + blowUpIOAggregate(input, baseName, TType(type, 0)); + } else { + blowUpIOAggregate(input, baseName, type); + } + } else { + TReflection::TNameToIndex::const_iterator it = ioMapper.find(name.c_str()); + if (it == ioMapper.end()) { + // seperate pipe i/o params from uniforms and blocks + // in is only for input in first stage as out is only for last stage. check traverse in call stack. + ioMapper[name.c_str()] = static_cast(ioItems.size()); + ioItems.push_back( + TObjectReflection(name.c_str(), type, 0, mapToGlType(type), mapToGlArraySize(type), 0)); + EShLanguageMask& stages = ioItems.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } else { + EShLanguageMask& stages = ioItems[it->second].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } } } } - // shared calculation by getOffset and getOffsets - void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize) - { - int dummyStride; - - // modify just the children's view of matrix layout, if there is one for this member - TLayoutMatrix subMatrixLayout = memberType.getQualifier().layoutMatrix; - int memberAlignment = intermediate.getMemberAlignment(memberType, memberSize, dummyStride, - parentType.getQualifier().layoutPacking, - subMatrixLayout != ElmNone - ? subMatrixLayout == ElmRowMajor - : parentType.getQualifier().layoutMatrix == ElmRowMajor); - RoundToPow2(offset, memberAlignment); - } - - // Lookup or calculate the offset of a block member, using the recursively - // defined block offset rules. - int getOffset(const TType& type, int index) - { - const TTypeList& memberList = *type.getStruct(); - - // Don't calculate offset if one is present, it could be user supplied - // and different than what would be calculated. That is, this is faster, - // but not just an optimization. - if (memberList[index].type->getQualifier().hasOffset()) - return memberList[index].type->getQualifier().layoutOffset; - - int memberSize = 0; - int offset = 0; - for (int m = 0; m <= index; ++m) { - updateOffset(type, *memberList[m].type, offset, memberSize); - - if (m < index) - offset += memberSize; - } - - return offset; - } - // Lookup or calculate the offset of all block members at once, using the recursively // defined block offset rules. void getOffsets(const TType& type, TVector& offsets) { const TTypeList& memberList = *type.getStruct(); - int memberSize = 0; int offset = 0; + for (size_t m = 0; m < offsets.size(); ++m) { // if the user supplied an offset, snap to it now if (memberList[m].type->getQualifier().hasOffset()) offset = memberList[m].type->getQualifier().layoutOffset; // calculate the offset of the next member and align the current offset to this member - updateOffset(type, *memberList[m].type, offset, memberSize); + intermediate.updateOffset(type, *memberList[m].type, offset, memberSize); // save the offset of this member offsets[m] = offset; @@ -196,21 +211,34 @@ public: return stride; } - // Calculate the block data size. - // Block arrayness is not taken into account, each element is backed by a separate buffer. - int getBlockSize(const TType& blockType) + // count the total number of leaf members from iterating out of a block type + int countAggregateMembers(const TType& parentType) { - const TTypeList& memberList = *blockType.getStruct(); - int lastIndex = (int)memberList.size() - 1; - int lastOffset = getOffset(blockType, lastIndex); + if (! parentType.isStruct()) + return 1; - int lastMemberSize; - int dummyStride; - intermediate.getMemberAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride, - blockType.getQualifier().layoutPacking, - blockType.getQualifier().layoutMatrix == ElmRowMajor); + const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix); - return lastOffset + lastMemberSize; + bool blockParent = (parentType.getBasicType() == EbtBlock && parentType.getQualifier().storage == EvqBuffer); + + const TTypeList &memberList = *parentType.getStruct(); + + int ret = 0; + + for (size_t i = 0; i < memberList.size(); i++) + { + const TType &memberType = *memberList[i].type; + int numMembers = countAggregateMembers(memberType); + // for sized arrays of structs, apply logic to expand out the same as we would below in + // blowUpActiveAggregate + if (memberType.isArray() && ! memberType.getArraySizes()->hasUnsized() && memberType.isStruct()) { + if (! strictArraySuffix || ! blockParent) + numMembers *= memberType.getArraySizes()->getCumulativeSize(); + } + ret += numMembers; + } + + return ret; } // Traverse the provided deref chain, including the base, and @@ -221,8 +249,19 @@ public: // arraySize tracks, just for the final dereference in the chain, if there was a specific known size. // A value of 0 for arraySize will mean to use the full array's size. void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList& derefs, - TList::const_iterator deref, int offset, int blockIndex, int arraySize) + TList::const_iterator deref, int offset, int blockIndex, int arraySize, + int topLevelArraySize, int topLevelArrayStride, TStorageQualifier baseStorage, bool active) { + // when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query. + // Broadly: + // * arrays-of-structs always have a [x] suffix. + // * with array-of-struct variables in the root of a buffer block, only ever return [0]. + // * otherwise, array suffixes are added whenever we iterate, even if that means expanding out an array. + const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix); + + // is this variable inside a buffer block. This flag is set back to false after we iterate inside the first array element. + bool blockParent = (baseType.getBasicType() == EbtBlock && baseType.getQualifier().storage == EvqBuffer); + // process the part of the dereference chain that was explicit in the shader TString name = baseName; const TType* terminalType = &baseType; @@ -234,39 +273,65 @@ public: case EOpIndexIndirect: { int stride = getArrayStride(baseType, visitNode->getLeft()->getType()); + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; + // Visit all the indices of this array, and for each one add on the remaining dereferencing for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) { TString newBaseName = name; - if (baseType.getBasicType() != EbtBlock) + if (terminalType->getBasicType() == EbtBlock) {} + else if (strictArraySuffix && blockParent) + newBaseName.append(TString("[0]")); + else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) newBaseName.append(TString("[") + String(i) + "]"); TList::const_iterator nextDeref = deref; ++nextDeref; - TType derefType(*terminalType, 0); - blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize); + blowUpActiveAggregate(*terminalType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize, + topLevelArraySize, topLevelArrayStride, baseStorage, active); if (offset >= 0) - offset += stride; + offset += stride; } // it was all completed in the recursive calls above return; } - case EOpIndexDirect: + case EOpIndexDirect: { + int stride = getArrayStride(baseType, visitNode->getLeft()->getType()); + index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); - if (baseType.getBasicType() != EbtBlock) { + if (terminalType->getBasicType() == EbtBlock) {} + else if (strictArraySuffix && blockParent) + name.append(TString("[0]")); + else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) { name.append(TString("[") + String(index) + "]"); if (offset >= 0) - offset += getArrayStride(baseType, visitNode->getLeft()->getType()) * index; + offset += stride * index; + } + + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; + + // expand top-level arrays in blocks with [0] suffix + if (topLevelArrayStride != 0 && visitNode->getLeft()->getType().isArray()) { + blockParent = false; } break; + } case EOpIndexDirectStruct: index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); if (offset >= 0) - offset += getOffset(visitNode->getLeft()->getType(), index); + offset += intermediate.getOffset(visitNode->getLeft()->getType(), index); if (name.size() > 0) name.append("."); name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName()); + + // expand non top-level arrays with [x] suffix + if (visitNode->getLeft()->getType().getBasicType() != EbtBlock && terminalType->isArray()) + { + blockParent = false; + } break; default: break; @@ -286,13 +351,27 @@ public: if (offset >= 0) stride = getArrayStride(baseType, *terminalType); - for (int i = 0; i < std::max(terminalType->getOuterArraySize(), 1); ++i) { + int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1); + + // for top-level arrays in blocks, only expand [0] to avoid explosion of items + if ((strictArraySuffix && blockParent) || + ((topLevelArraySize == arrayIterateSize) && (topLevelArrayStride == 0))) { + arrayIterateSize = 1; + } + + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; + + for (int i = 0; i < arrayIterateSize; ++i) { TString newBaseName = name; - newBaseName.append(TString("[") + String(i) + "]"); + if (terminalType->getBasicType() != EbtBlock) + newBaseName.append(TString("[") + String(i) + "]"); TType derefType(*terminalType, 0); if (offset >= 0) offset = baseOffset + stride * i; - blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0); + + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, + topLevelArraySize, topLevelArrayStride, baseStorage, active); } } else { // Visit all members of this aggregate, and for each one, @@ -308,11 +387,44 @@ public: for (int i = 0; i < (int)typeList.size(); ++i) { TString newBaseName = name; - newBaseName.append(TString(".") + typeList[i].type->getFieldName()); + if (newBaseName.size() > 0) + newBaseName.append("."); + newBaseName.append(typeList[i].type->getFieldName()); TType derefType(*terminalType, i); if (offset >= 0) offset = baseOffset + memberOffsets[i]; - blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0); + + int arrayStride = topLevelArrayStride; + if (terminalType->getBasicType() == EbtBlock && terminalType->getQualifier().storage == EvqBuffer && + derefType.isArray()) { + arrayStride = getArrayStride(baseType, derefType); + } + + if (topLevelArraySize == -1 && arrayStride == 0 && blockParent) + topLevelArraySize = 1; + + if (strictArraySuffix && blockParent) { + // if this member is an array, store the top-level array stride but start the explosion from + // the inner struct type. + if (derefType.isArray() && derefType.isStruct()) { + newBaseName.append("[0]"); + auto dimSize = derefType.isUnsizedArray() ? 0 : derefType.getArraySizes()->getDimSize(0); + blowUpActiveAggregate(TType(derefType, 0), newBaseName, derefs, derefs.end(), memberOffsets[i], + blockIndex, 0, dimSize, arrayStride, terminalType->getQualifier().storage, false); + } + else if (derefType.isArray()) { + auto dimSize = derefType.isUnsizedArray() ? 0 : derefType.getArraySizes()->getDimSize(0); + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), memberOffsets[i], blockIndex, + 0, dimSize, 0, terminalType->getQualifier().storage, false); + } + else { + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), memberOffsets[i], blockIndex, + 0, 1, 0, terminalType->getQualifier().storage, false); + } + } else { + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, + topLevelArraySize, arrayStride, baseStorage, active); + } } } @@ -320,6 +432,10 @@ public: return; } + if ((reflection.options & EShReflectionBasicArraySuffix) && terminalType->isArray()) { + name.append(TString("[0]")); + } + // Finally, add a full string to the reflection database, and update the array size if necessary. // If the dereferenced entity to record is an array, compute the size and update the maximum size. @@ -327,15 +443,101 @@ public: if (arraySize == 0) arraySize = mapToGlArraySize(*terminalType); + TReflection::TMapIndexToReflection& variables = reflection.GetVariableMapForStorage(baseStorage); + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); if (it == reflection.nameToIndex.end()) { - reflection.nameToIndex[name.c_str()] = (int)reflection.indexToUniform.size(); - reflection.indexToUniform.push_back(TObjectReflection(name.c_str(), *terminalType, offset, - mapToGlType(*terminalType), - arraySize, blockIndex)); - } else if (arraySize > 1) { - int& reflectedArraySize = reflection.indexToUniform[it->second].size; - reflectedArraySize = std::max(arraySize, reflectedArraySize); + int uniformIndex = (int)variables.size(); + reflection.nameToIndex[name.c_str()] = uniformIndex; + variables.push_back(TObjectReflection(name.c_str(), *terminalType, offset, mapToGlType(*terminalType), + arraySize, blockIndex)); + if (terminalType->isArray()) { + variables.back().arrayStride = getArrayStride(baseType, *terminalType); + if (topLevelArrayStride == 0) + topLevelArrayStride = variables.back().arrayStride; + } + + if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->isAtomic()) + reflection.atomicCounterUniformIndices.push_back(uniformIndex); + + variables.back().topLevelArraySize = topLevelArraySize; + variables.back().topLevelArrayStride = topLevelArrayStride; + + if ((reflection.options & EShReflectionAllBlockVariables) && active) { + EShLanguageMask& stages = variables.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + } else { + if (arraySize > 1) { + int& reflectedArraySize = variables[it->second].size; + reflectedArraySize = std::max(arraySize, reflectedArraySize); + } + + if ((reflection.options & EShReflectionAllBlockVariables) && active) { + EShLanguageMask& stages = variables[it->second].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + } + } + + // similar to blowUpActiveAggregate, but with simpler rules and no dereferences to follow. + void blowUpIOAggregate(bool input, const TString &baseName, const TType &type) + { + TString name = baseName; + + // if the type is still too coarse a granularity, this is still an aggregate to expand, expand it... + if (! isReflectionGranularity(type)) { + if (type.isArray()) { + // Visit all the indices of this array, and for each one, + // fully explode the remaining aggregate to dereference + for (int i = 0; i < std::max(type.getOuterArraySize(), 1); ++i) { + TString newBaseName = name; + newBaseName.append(TString("[") + String(i) + "]"); + TType derefType(type, 0); + + blowUpIOAggregate(input, newBaseName, derefType); + } + } else { + // Visit all members of this aggregate, and for each one, + // fully explode the remaining aggregate to dereference + const TTypeList& typeList = *type.getStruct(); + + for (int i = 0; i < (int)typeList.size(); ++i) { + TString newBaseName = name; + if (newBaseName.size() > 0) + newBaseName.append("."); + newBaseName.append(typeList[i].type->getFieldName()); + TType derefType(type, i); + + blowUpIOAggregate(input, newBaseName, derefType); + } + } + + // it was all completed in the recursive calls above + return; + } + + if ((reflection.options & EShReflectionBasicArraySuffix) && type.isArray()) { + name.append(TString("[0]")); + } + + TReflection::TMapIndexToReflection &ioItems = + input ? reflection.indexToPipeInput : reflection.indexToPipeOutput; + + std::string namespacedName = input ? "in " : "out "; + namespacedName += name.c_str(); + + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(namespacedName); + if (it == reflection.nameToIndex.end()) { + reflection.nameToIndex[namespacedName] = (int)ioItems.size(); + ioItems.push_back( + TObjectReflection(name.c_str(), type, 0, mapToGlType(type), mapToGlArraySize(type), 0)); + + EShLanguageMask& stages = ioItems.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } else { + EShLanguageMask& stages = ioItems[it->second].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); } } @@ -385,16 +587,23 @@ public: anonymous = IsAnonymous(base->getName()); const TString& blockName = base->getType().getTypeName(); + TString baseName; + + if (! anonymous) + baseName = blockName; - if (base->getType().isArray()) { - TType derefType(base->getType(), 0); + blockIndex = addBlockName(blockName, base->getType(), intermediate.getBlockSize(base->getType())); - assert(! anonymous); - for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e) - blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType, - getBlockSize(base->getType())); - } else - blockIndex = addBlockName(blockName, base->getType(), getBlockSize(base->getType())); + if (reflection.options & EShReflectionAllBlockVariables) { + // Use a degenerate (empty) set of dereferences to immediately put as at the end of + // the dereference change expected by blowUpActiveAggregate. + TList derefs; + + // otherwise - if we're not using strict array suffix rules, or this isn't a block so we are + // expanding root arrays anyway, just start the iteration from the base block type. + blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, -1, 0, + base->getQualifier().storage, false); + } } // Process the dereference chain, backward, accumulating the pieces for later forward traversal. @@ -424,19 +633,44 @@ public: else baseName = base->getName(); } - blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize); + blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, -1, 0, + base->getQualifier().storage, true); } int addBlockName(const TString& name, const TType& type, int size) { - int blockIndex; - TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); - if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) { - blockIndex = (int)reflection.indexToUniformBlock.size(); - reflection.nameToIndex[name.c_str()] = blockIndex; - reflection.indexToUniformBlock.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1)); - } else - blockIndex = it->second; + int blockIndex = 0; + if (type.isArray()) { + TType derefType(type, 0); + for (int e = 0; e < type.getOuterArraySize(); ++e) { + int memberBlockIndex = addBlockName(name + "[" + String(e) + "]", derefType, size); + if (e == 0) + blockIndex = memberBlockIndex; + } + } else { + TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage); + + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); + if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) { + blockIndex = (int)blocks.size(); + reflection.nameToIndex[name.c_str()] = blockIndex; + blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, blockIndex)); + + blocks.back().numMembers = countAggregateMembers(type); + + if (updateStageMasks) { + EShLanguageMask& stages = blocks.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + } + else { + blockIndex = it->second; + if (updateStageMasks) { + EShLanguageMask& stages = blocks[blockIndex].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + } + } return blockIndex; } @@ -444,7 +678,7 @@ public: // Are we at a level in a dereference chain at which individual active uniform queries are made? bool isReflectionGranularity(const TType& type) { - return type.getBasicType() != EbtBlock && type.getBasicType() != EbtStruct; + return type.getBasicType() != EbtBlock && type.getBasicType() != EbtStruct && !type.isArrayOfArrays(); } // For a binary operation indexing into an aggregate, chase down the base of the aggregate. @@ -497,7 +731,6 @@ public: case EsdBuffer: return GL_SAMPLER_BUFFER; } -#ifdef AMD_EXTENSIONS case EbtFloat16: switch ((int)sampler.dim) { case Esd1D: @@ -526,7 +759,6 @@ public: case EsdBuffer: return GL_FLOAT16_SAMPLER_BUFFER_AMD; } -#endif case EbtInt: switch ((int)sampler.dim) { case Esd1D: @@ -589,7 +821,6 @@ public: case EsdBuffer: return GL_IMAGE_BUFFER; } -#ifdef AMD_EXTENSIONS case EbtFloat16: switch ((int)sampler.dim) { case Esd1D: @@ -608,7 +839,6 @@ public: case EsdBuffer: return GL_FLOAT16_IMAGE_BUFFER_AMD; } -#endif case EbtInt: switch ((int)sampler.dim) { case Esd1D: @@ -674,13 +904,11 @@ public: switch (type.getBasicType()) { case EbtFloat: return GL_FLOAT_VEC2 + offset; case EbtDouble: return GL_DOUBLE_VEC2 + offset; -#ifdef AMD_EXTENSIONS case EbtFloat16: return GL_FLOAT16_VEC2_NV + offset; -#endif case EbtInt: return GL_INT_VEC2 + offset; case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset; - case EbtInt64: return GL_INT64_ARB + offset; - case EbtUint64: return GL_UNSIGNED_INT64_ARB + offset; + case EbtInt64: return GL_INT64_VEC2_ARB + offset; + case EbtUint64: return GL_UNSIGNED_INT64_VEC2_ARB + offset; case EbtBool: return GL_BOOL_VEC2 + offset; case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset; default: return 0; @@ -736,7 +964,6 @@ public: default: return 0; } } -#ifdef AMD_EXTENSIONS case EbtFloat16: switch (type.getMatrixCols()) { case 2: @@ -761,7 +988,6 @@ public: default: return 0; } } -#endif default: return 0; } @@ -770,9 +996,7 @@ public: switch (type.getBasicType()) { case EbtFloat: return GL_FLOAT; case EbtDouble: return GL_DOUBLE; -#ifdef AMD_EXTENSIONS case EbtFloat16: return GL_FLOAT16_NV; -#endif case EbtInt: return GL_INT; case EbtUint: return GL_UNSIGNED_INT; case EbtInt64: return GL_INT64_ARB; @@ -791,8 +1015,10 @@ public: return type.isArray() ? type.getOuterArraySize() : 1; } + const TIntermediate& intermediate; TReflection& reflection; std::set processedDerefs; + bool updateStageMasks; protected: TReflectionTraverser(TReflectionTraverser&); @@ -825,11 +1051,64 @@ bool TReflectionTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) // To reflect non-dereferenced objects. void TReflectionTraverser::visitSymbol(TIntermSymbol* base) { - if (base->getQualifier().storage == EvqUniform) + if (base->getQualifier().storage == EvqUniform) { + if (base->getBasicType() == EbtBlock) { + if (reflection.options & EShReflectionSharedStd140UBO) { + addUniform(*base); + } + } else { + addUniform(*base); + } + } + + // #TODO add std140/layout active rules for ssbo, same with ubo. + // Storage buffer blocks will be collected and expanding in this part. + if((reflection.options & EShReflectionSharedStd140SSBO) && + (base->getQualifier().storage == EvqBuffer && base->getBasicType() == EbtBlock && + (base->getQualifier().layoutPacking == ElpStd140 || base->getQualifier().layoutPacking == ElpShared))) addUniform(*base); - if (intermediate.getStage() == EShLangVertex && base->getQualifier().isPipeInput()) - addAttribute(*base); + if ((intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput()) || + (intermediate.getStage() == reflection.lastStage && base->getQualifier().isPipeOutput())) + addPipeIOVariable(*base); +} + +// +// Implement TObjectReflection methods. +// + +TObjectReflection::TObjectReflection(const std::string &pName, const TType &pType, int pOffset, int pGLDefineType, + int pSize, int pIndex) + : name(pName), offset(pOffset), glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), + numMembers(-1), arrayStride(0), topLevelArrayStride(0), stages(EShLanguageMask(0)), type(pType.clone()) +{ +} + +int TObjectReflection::getBinding() const +{ + if (type == nullptr || !type->getQualifier().hasBinding()) + return -1; + return type->getQualifier().layoutBinding; +} + +void TObjectReflection::dump() const +{ + printf("%s: offset %d, type %x, size %d, index %d, binding %d, stages %d", name.c_str(), offset, glDefineType, size, + index, getBinding(), stages); + + if (counterIndex != -1) + printf(", counter %d", counterIndex); + + if (numMembers != -1) + printf(", numMembers %d", numMembers); + + if (arrayStride != 0) + printf(", arrayStride %d", arrayStride); + + if (topLevelArrayStride != 0) + printf(", topLevelArrayStride %d", topLevelArrayStride); + + printf("\n"); } // @@ -850,6 +1129,7 @@ void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediat // build counter block index associations for buffers void TReflection::buildCounterIndices(const TIntermediate& intermediate) { +#ifdef ENABLE_HLSL // search for ones that have counters for (int i = 0; i < int(indexToUniformBlock.size()); ++i) { const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str()); @@ -858,14 +1138,25 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate) if (index >= 0) indexToUniformBlock[i].counterIndex = index; } +#else + (void)intermediate; +#endif } // build Shader Stages mask for all uniforms void TReflection::buildUniformStageMask(const TIntermediate& intermediate) { + if (options & EShReflectionAllBlockVariables) + return; + for (int i = 0; i < int(indexToUniform.size()); ++i) { indexToUniform[i].stages = static_cast(indexToUniform[i].stages | 1 << intermediate.getStage()); } + + for (int i = 0; i < int(indexToBufferVariable.size()); ++i) { + indexToBufferVariable[i].stages = + static_cast(indexToBufferVariable[i].stages | 1 << intermediate.getStage()); + } } // Merge live symbols from 'intermediate' into the existing reflection database. @@ -882,15 +1173,47 @@ bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate) TReflectionTraverser it(intermediate, *this); - // put the entry point on the list of functions to process - it.pushFunction(intermediate.getEntryPointMangledName().c_str()); - - // process all the functions - while (! it.functions.empty()) { - TIntermNode* function = it.functions.back(); - it.functions.pop_back(); - function->traverse(&it); + for (auto& sequnence : intermediate.getTreeRoot()->getAsAggregate()->getSequence()) { + if (sequnence->getAsAggregate() != nullptr) { + if (sequnence->getAsAggregate()->getOp() == glslang::EOpLinkerObjects) { + it.updateStageMasks = false; + TIntermAggregate* linkerObjects = sequnence->getAsAggregate(); + for (auto& sequnence : linkerObjects->getSequence()) { + auto pNode = sequnence->getAsSymbolNode(); + if (pNode != nullptr) { + if ((pNode->getQualifier().storage == EvqUniform && + (options & EShReflectionSharedStd140UBO)) || + (pNode->getQualifier().storage == EvqBuffer && + (options & EShReflectionSharedStd140SSBO))) { + // collect std140 and shared uniform block form AST + if ((pNode->getBasicType() == EbtBlock) && + ((pNode->getQualifier().layoutPacking == ElpStd140) || + (pNode->getQualifier().layoutPacking == ElpShared))) { + pNode->traverse(&it); + } + } + else if ((options & EShReflectionAllIOVariables) && + (pNode->getQualifier().isPipeInput() || pNode->getQualifier().isPipeOutput())) + { + pNode->traverse(&it); + } + } + } + } else { + // This traverser will travers all function in AST. + // If we want reflect uncalled function, we need set linke message EShMsgKeepUncalled. + // When EShMsgKeepUncalled been set to true, all function will be keep in AST, even it is a uncalled function. + // This will keep some uniform variables in reflection, if those uniform variables is used in these uncalled function. + // + // If we just want reflect only live node, we can use a default link message or set EShMsgKeepUncalled false. + // When linke message not been set EShMsgKeepUncalled, linker won't keep uncalled function in AST. + // So, travers all function node can equivalent to travers live function. + it.updateStageMasks = true; + sequnence->getAsAggregate()->traverse(&it); + } + } } + it.updateStageMasks = true; buildCounterIndices(intermediate); buildUniformStageMask(intermediate); @@ -910,9 +1233,24 @@ void TReflection::dump() indexToUniformBlock[i].dump(); printf("\n"); - printf("Vertex attribute reflection:\n"); - for (size_t i = 0; i < indexToAttribute.size(); ++i) - indexToAttribute[i].dump(); + printf("Buffer variable reflection:\n"); + for (size_t i = 0; i < indexToBufferVariable.size(); ++i) + indexToBufferVariable[i].dump(); + printf("\n"); + + printf("Buffer block reflection:\n"); + for (size_t i = 0; i < indexToBufferBlock.size(); ++i) + indexToBufferBlock[i].dump(); + printf("\n"); + + printf("Pipeline input reflection:\n"); + for (size_t i = 0; i < indexToPipeInput.size(); ++i) + indexToPipeInput[i].dump(); + printf("\n"); + + printf("Pipeline output reflection:\n"); + for (size_t i = 0; i < indexToPipeOutput.size(); ++i) + indexToPipeOutput[i].dump(); printf("\n"); if (getLocalSize(0) > 1) { @@ -920,7 +1258,7 @@ void TReflection::dump() for (int dim=0; dim<3; ++dim) if (getLocalSize(dim) > 1) - printf("Local size %s: %d\n", axis[dim], getLocalSize(dim)); + printf("Local size %s: %u\n", axis[dim], getLocalSize(dim)); printf("\n"); } @@ -932,3 +1270,5 @@ void TReflection::dump() } } // end namespace glslang + +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.h b/thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.h index dab9ab0..5af4467 100644 --- a/thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.h +++ b/thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.h @@ -33,6 +33,8 @@ // POSSIBILITY OF SUCH DAMAGE. // +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + #ifndef _REFLECTION_INCLUDED #define _REFLECTION_INCLUDED @@ -52,51 +54,11 @@ class TIntermediate; class TIntermAggregate; class TReflectionTraverser; -// Data needed for just a single object at the granularity exchanged by the reflection API -class TObjectReflection { -public: - TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) : - name(pName), offset(pOffset), - glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), stages(EShLanguageMask(0)), type(pType.clone()) { } - - const TType* getType() const { return type; } - int getBinding() const - { - if (type == nullptr || !type->getQualifier().hasBinding()) - return -1; - return type->getQualifier().layoutBinding; - } - void dump() const - { - printf("%s: offset %d, type %x, size %d, index %d, binding %d, stages %d", - name.c_str(), offset, glDefineType, size, index, getBinding(), stages ); - - if (counterIndex != -1) - printf(", counter %d", counterIndex); - - printf("\n"); - } - static TObjectReflection badReflection() { return TObjectReflection(); } - - std::string name; - int offset; - int glDefineType; - int size; // data size in bytes for a block, array size for a (non-block) object that's an array - int index; - int counterIndex; - EShLanguageMask stages; - -protected: - TObjectReflection() : - offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), stages(EShLanguageMask(0)), type(nullptr) { } - - const TType* type; -}; - // The full reflection database class TReflection { public: - TReflection() : badReflection(TObjectReflection::badReflection()) + TReflection(EShReflectionOptions opts, EShLanguage first, EShLanguage last) + : options(opts), firstStage(first), lastStage(last), badReflection(TObjectReflection::badReflection()) { for (int dim=0; dim<3; ++dim) localSize[dim] = 0; @@ -127,17 +89,57 @@ public: return badReflection; } - // for mapping an attribute index to the attribute's description - int getNumAttributes() { return (int)indexToAttribute.size(); } - const TObjectReflection& getAttribute(int i) const + // for mapping an pipeline input index to the input's description + int getNumPipeInputs() { return (int)indexToPipeInput.size(); } + const TObjectReflection& getPipeInput(int i) const { - if (i >= 0 && i < (int)indexToAttribute.size()) - return indexToAttribute[i]; + if (i >= 0 && i < (int)indexToPipeInput.size()) + return indexToPipeInput[i]; else return badReflection; } - // for mapping any name to its index (block names, uniform names and attribute names) + // for mapping an pipeline output index to the output's description + int getNumPipeOutputs() { return (int)indexToPipeOutput.size(); } + const TObjectReflection& getPipeOutput(int i) const + { + if (i >= 0 && i < (int)indexToPipeOutput.size()) + return indexToPipeOutput[i]; + else + return badReflection; + } + + // for mapping from an atomic counter to the uniform index + int getNumAtomicCounters() const { return (int)atomicCounterUniformIndices.size(); } + const TObjectReflection& getAtomicCounter(int i) const + { + if (i >= 0 && i < (int)atomicCounterUniformIndices.size()) + return getUniform(atomicCounterUniformIndices[i]); + else + return badReflection; + } + + // for mapping a buffer variable index to a buffer variable object's description + int getNumBufferVariables() { return (int)indexToBufferVariable.size(); } + const TObjectReflection& getBufferVariable(int i) const + { + if (i >= 0 && i < (int)indexToBufferVariable.size()) + return indexToBufferVariable[i]; + else + return badReflection; + } + + // for mapping a storage block index to the storage block's description + int getNumStorageBuffers() const { return (int)indexToBufferBlock.size(); } + const TObjectReflection& getStorageBufferBlock(int i) const + { + if (i >= 0 && i < (int)indexToBufferBlock.size()) + return indexToBufferBlock[i]; + else + return badReflection; + } + + // for mapping any name to its index (block names, uniform names and input/output names) int getIndex(const char* name) const { TNameToIndex::const_iterator it = nameToIndex.find(name); @@ -150,6 +152,20 @@ public: // see getIndex(const char*) int getIndex(const TString& name) const { return getIndex(name.c_str()); } + + // for mapping any name to its index (only pipe input/output names) + int getPipeIOIndex(const char* name, const bool inOrOut) const + { + TNameToIndex::const_iterator it = inOrOut ? pipeInNameToIndex.find(name) : pipeOutNameToIndex.find(name); + if (it == (inOrOut ? pipeInNameToIndex.end() : pipeOutNameToIndex.end())) + return -1; + else + return it->second; + } + + // see gePipeIOIndex(const char*, const bool) + int getPipeIOIndex(const TString& name, const bool inOrOut) const { return getPipeIOIndex(name.c_str(), inOrOut); } + // Thread local size unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; } @@ -165,12 +181,37 @@ protected: // Need a TString hash: typedef std::unordered_map TNameToIndex; typedef std::map TNameToIndex; typedef std::vector TMapIndexToReflection; + typedef std::vector TIndices; + + TMapIndexToReflection& GetBlockMapForStorage(TStorageQualifier storage) + { + if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer) + return indexToBufferBlock; + return indexToUniformBlock; + } + TMapIndexToReflection& GetVariableMapForStorage(TStorageQualifier storage) + { + if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer) + return indexToBufferVariable; + return indexToUniform; + } + + EShReflectionOptions options; + + EShLanguage firstStage; + EShLanguage lastStage; TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this TNameToIndex nameToIndex; // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed + TNameToIndex pipeInNameToIndex; // maps pipe in names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers. + TNameToIndex pipeOutNameToIndex; // maps pipe out names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers. TMapIndexToReflection indexToUniform; TMapIndexToReflection indexToUniformBlock; - TMapIndexToReflection indexToAttribute; + TMapIndexToReflection indexToBufferVariable; + TMapIndexToReflection indexToBufferBlock; + TMapIndexToReflection indexToPipeInput; + TMapIndexToReflection indexToPipeOutput; + TIndices atomicCounterUniformIndices; unsigned int localSize[3]; }; @@ -178,3 +219,5 @@ protected: } // end namespace glslang #endif // _REFLECTION_INCLUDED + +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/thirdparty/ShaderCompiler/glslang/OSDependent/Unix/CMakeLists.txt b/thirdparty/ShaderCompiler/glslang/OSDependent/Unix/CMakeLists.txt new file mode 100644 index 0000000..354a3e9 --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/OSDependent/Unix/CMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright (C) 2020 The Khronos Group Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# Neither the name of The Khronos Group Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +add_library(OSDependent STATIC ossource.cpp ../osinclude.h) +set_property(TARGET OSDependent PROPERTY FOLDER glslang) +set_property(TARGET OSDependent PROPERTY POSITION_INDEPENDENT_CODE ON) + +# Link pthread +set(CMAKE_THREAD_PREFER_PTHREAD ON) +if(${CMAKE_VERSION} VERSION_LESS "3.1.0" OR CMAKE_CROSSCOMPILING) + # Needed as long as we support CMake 2.8 for Ubuntu 14.04, + # which does not support the recommended Threads::Threads target. + # https://cmake.org/cmake/help/v2.8.12/cmake.html#module:FindThreads + # Also needed when cross-compiling to work around + # https://gitlab.kitware.com/cmake/cmake/issues/16920 + find_package(Threads) + target_link_libraries(OSDependent ${CMAKE_THREAD_LIBS_INIT}) +else() + # This is the recommended way, so we use it for 3.1+. + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads) + target_link_libraries(OSDependent Threads::Threads) +endif() + +if(ENABLE_GLSLANG_INSTALL) + install(TARGETS OSDependent EXPORT OSDependentTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) +endif(ENABLE_GLSLANG_INSTALL) diff --git a/thirdparty/ShaderCompiler/glslang/OSDependent/Web/CMakeLists.txt b/thirdparty/ShaderCompiler/glslang/OSDependent/Web/CMakeLists.txt new file mode 100644 index 0000000..0f60dbc --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/OSDependent/Web/CMakeLists.txt @@ -0,0 +1,71 @@ +# Copyright (C) 2020 The Khronos Group Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# Neither the name of The Khronos Group Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +if(ENABLE_GLSLANG_JS) + add_executable(glslang.js "glslang.js.cpp") + glslang_set_link_args(glslang.js) + target_link_libraries(glslang.js glslang SPIRV) + + # Link library names that start with "-" are treated as link flags. + # "-Os" should be OK in MSVC; don't use /Os because CMake won't + # treat it as a link flag. + target_link_libraries(glslang.js "-Os") + + if(EMSCRIPTEN) + set_target_properties(glslang.js PROPERTIES + OUTPUT_NAME "glslang" + SUFFIX ".js") + em_link_pre_js(glslang.js "${CMAKE_CURRENT_SOURCE_DIR}/glslang.pre.js") + + target_link_libraries(glslang.js "--llvm-lto 1") + target_link_libraries(glslang.js "--closure 1") + target_link_libraries(glslang.js "-s MODULARIZE=1") + target_link_libraries(glslang.js "-s ALLOW_MEMORY_GROWTH=1") + target_link_libraries(glslang.js "-s FILESYSTEM=0") + + if(ENABLE_EMSCRIPTEN_SINGLE_FILE) + target_link_libraries(glslang.js "-s SINGLE_FILE=1") + endif(ENABLE_EMSCRIPTEN_SINGLE_FILE) + + if(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE) + target_link_libraries(glslang.js "-s ENVIRONMENT=node -s BINARYEN_ASYNC_COMPILATION=0") + else() + target_link_libraries(glslang.js "-s ENVIRONMENT=web,worker") + endif() + + if(NOT ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE) + add_custom_command(TARGET glslang.js POST_BUILD + COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/glslang.after.js >> ${CMAKE_CURRENT_BINARY_DIR}/glslang.js) + endif() + endif(EMSCRIPTEN) +endif(ENABLE_GLSLANG_JS) diff --git a/thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.after.js b/thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.after.js new file mode 100644 index 0000000..c2cfc35 --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.after.js @@ -0,0 +1,26 @@ +export default (() => { + const initialize = () => { + return new Promise(resolve => { + Module({ + locateFile() { + const i = import.meta.url.lastIndexOf('/') + return import.meta.url.substring(0, i) + '/glslang.wasm'; + }, + onRuntimeInitialized() { + resolve({ + compileGLSLZeroCopy: this.compileGLSLZeroCopy, + compileGLSL: this.compileGLSL, + }); + }, + }); + }); + }; + + let instance; + return () => { + if (!instance) { + instance = initialize(); + } + return instance; + }; +})(); diff --git a/thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.js.cpp b/thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.js.cpp new file mode 100644 index 0000000..f2306a6 --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.js.cpp @@ -0,0 +1,287 @@ +// +// Copyright (C) 2019 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include "../../../SPIRV/GlslangToSpv.h" +#include "../../../glslang/Public/ShaderLang.h" + +#ifndef __EMSCRIPTEN__ +#define EMSCRIPTEN_KEEPALIVE +#endif + +const TBuiltInResource DefaultTBuiltInResource = { + /* .MaxLights = */ 32, + /* .MaxClipPlanes = */ 6, + /* .MaxTextureUnits = */ 32, + /* .MaxTextureCoords = */ 32, + /* .MaxVertexAttribs = */ 64, + /* .MaxVertexUniformComponents = */ 4096, + /* .MaxVaryingFloats = */ 64, + /* .MaxVertexTextureImageUnits = */ 32, + /* .MaxCombinedTextureImageUnits = */ 80, + /* .MaxTextureImageUnits = */ 32, + /* .MaxFragmentUniformComponents = */ 4096, + /* .MaxDrawBuffers = */ 32, + /* .MaxVertexUniformVectors = */ 128, + /* .MaxVaryingVectors = */ 8, + /* .MaxFragmentUniformVectors = */ 16, + /* .MaxVertexOutputVectors = */ 16, + /* .MaxFragmentInputVectors = */ 15, + /* .MinProgramTexelOffset = */ -8, + /* .MaxProgramTexelOffset = */ 7, + /* .MaxClipDistances = */ 8, + /* .MaxComputeWorkGroupCountX = */ 65535, + /* .MaxComputeWorkGroupCountY = */ 65535, + /* .MaxComputeWorkGroupCountZ = */ 65535, + /* .MaxComputeWorkGroupSizeX = */ 1024, + /* .MaxComputeWorkGroupSizeY = */ 1024, + /* .MaxComputeWorkGroupSizeZ = */ 64, + /* .MaxComputeUniformComponents = */ 1024, + /* .MaxComputeTextureImageUnits = */ 16, + /* .MaxComputeImageUniforms = */ 8, + /* .MaxComputeAtomicCounters = */ 8, + /* .MaxComputeAtomicCounterBuffers = */ 1, + /* .MaxVaryingComponents = */ 60, + /* .MaxVertexOutputComponents = */ 64, + /* .MaxGeometryInputComponents = */ 64, + /* .MaxGeometryOutputComponents = */ 128, + /* .MaxFragmentInputComponents = */ 128, + /* .MaxImageUnits = */ 8, + /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, + /* .MaxCombinedShaderOutputResources = */ 8, + /* .MaxImageSamples = */ 0, + /* .MaxVertexImageUniforms = */ 0, + /* .MaxTessControlImageUniforms = */ 0, + /* .MaxTessEvaluationImageUniforms = */ 0, + /* .MaxGeometryImageUniforms = */ 0, + /* .MaxFragmentImageUniforms = */ 8, + /* .MaxCombinedImageUniforms = */ 8, + /* .MaxGeometryTextureImageUnits = */ 16, + /* .MaxGeometryOutputVertices = */ 256, + /* .MaxGeometryTotalOutputComponents = */ 1024, + /* .MaxGeometryUniformComponents = */ 1024, + /* .MaxGeometryVaryingComponents = */ 64, + /* .MaxTessControlInputComponents = */ 128, + /* .MaxTessControlOutputComponents = */ 128, + /* .MaxTessControlTextureImageUnits = */ 16, + /* .MaxTessControlUniformComponents = */ 1024, + /* .MaxTessControlTotalOutputComponents = */ 4096, + /* .MaxTessEvaluationInputComponents = */ 128, + /* .MaxTessEvaluationOutputComponents = */ 128, + /* .MaxTessEvaluationTextureImageUnits = */ 16, + /* .MaxTessEvaluationUniformComponents = */ 1024, + /* .MaxTessPatchComponents = */ 120, + /* .MaxPatchVertices = */ 32, + /* .MaxTessGenLevel = */ 64, + /* .MaxViewports = */ 16, + /* .MaxVertexAtomicCounters = */ 0, + /* .MaxTessControlAtomicCounters = */ 0, + /* .MaxTessEvaluationAtomicCounters = */ 0, + /* .MaxGeometryAtomicCounters = */ 0, + /* .MaxFragmentAtomicCounters = */ 8, + /* .MaxCombinedAtomicCounters = */ 8, + /* .MaxAtomicCounterBindings = */ 1, + /* .MaxVertexAtomicCounterBuffers = */ 0, + /* .MaxTessControlAtomicCounterBuffers = */ 0, + /* .MaxTessEvaluationAtomicCounterBuffers = */ 0, + /* .MaxGeometryAtomicCounterBuffers = */ 0, + /* .MaxFragmentAtomicCounterBuffers = */ 1, + /* .MaxCombinedAtomicCounterBuffers = */ 1, + /* .MaxAtomicCounterBufferSize = */ 16384, + /* .MaxTransformFeedbackBuffers = */ 4, + /* .MaxTransformFeedbackInterleavedComponents = */ 64, + /* .MaxCullDistances = */ 8, + /* .MaxCombinedClipAndCullDistances = */ 8, + /* .MaxSamples = */ 4, + /* .maxMeshOutputVerticesNV = */ 256, + /* .maxMeshOutputPrimitivesNV = */ 512, + /* .maxMeshWorkGroupSizeX_NV = */ 32, + /* .maxMeshWorkGroupSizeY_NV = */ 1, + /* .maxMeshWorkGroupSizeZ_NV = */ 1, + /* .maxTaskWorkGroupSizeX_NV = */ 32, + /* .maxTaskWorkGroupSizeY_NV = */ 1, + /* .maxTaskWorkGroupSizeZ_NV = */ 1, + /* .maxMeshViewCountNV = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, + + /* .limits = */ { + /* .nonInductiveForLoops = */ 1, + /* .whileLoops = */ 1, + /* .doWhileLoops = */ 1, + /* .generalUniformIndexing = */ 1, + /* .generalAttributeMatrixVectorIndexing = */ 1, + /* .generalVaryingIndexing = */ 1, + /* .generalSamplerIndexing = */ 1, + /* .generalVariableIndexing = */ 1, + /* .generalConstantMatrixVectorIndexing = */ 1, + }}; + +static bool initialized = false; + +extern "C" { + +/* + * Takes in a GLSL shader as a string and converts it to SPIR-V in binary form. + * + * |glsl| Null-terminated string containing the shader to be converted. + * |stage_int| Magic number indicating the type of shader being processed. +* Legal values are as follows: + * Vertex = 0 + * Fragment = 4 + * Compute = 5 + * |gen_debug| Flag to indicate if debug information should be generated. + * |spirv| Output parameter for a pointer to the resulting SPIR-V data. + * |spirv_len| Output parameter for the length of the output binary buffer. + * + * Returns a void* pointer which, if not null, must be destroyed by + * destroy_output_buffer.o. (This is not the same pointer returned in |spirv|.) + * If null, the compilation failed. + */ +EMSCRIPTEN_KEEPALIVE +void* convert_glsl_to_spirv(const char* glsl, + int stage_int, + bool gen_debug, + glslang::EShTargetLanguageVersion spirv_version, + uint32_t** spirv, + size_t* spirv_len) +{ + if (glsl == nullptr) { + fprintf(stderr, "Input pointer null\n"); + return nullptr; + } + if (spirv == nullptr || spirv_len == nullptr) { + fprintf(stderr, "Output pointer null\n"); + return nullptr; + } + *spirv = nullptr; + *spirv_len = 0; + + if (stage_int != 0 && stage_int != 4 && stage_int != 5) { + fprintf(stderr, "Invalid shader stage\n"); + return nullptr; + } + EShLanguage stage = static_cast(stage_int); + switch (spirv_version) { + case glslang::EShTargetSpv_1_0: + case glslang::EShTargetSpv_1_1: + case glslang::EShTargetSpv_1_2: + case glslang::EShTargetSpv_1_3: + case glslang::EShTargetSpv_1_4: + case glslang::EShTargetSpv_1_5: + break; + default: + fprintf(stderr, "Invalid SPIR-V version number\n"); + return nullptr; + } + + if (!initialized) { + glslang::InitializeProcess(); + initialized = true; + } + + glslang::TShader shader(stage); + shader.setStrings(&glsl, 1); + shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 100); + shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0); + shader.setEnvTarget(glslang::EShTargetSpv, spirv_version); + if (!shader.parse(&DefaultTBuiltInResource, 100, true, EShMsgDefault)) { + fprintf(stderr, "Parse failed\n"); + fprintf(stderr, "%s\n", shader.getInfoLog()); + return nullptr; + } + + glslang::TProgram program; + program.addShader(&shader); + if (!program.link(EShMsgDefault)) { + fprintf(stderr, "Link failed\n"); + fprintf(stderr, "%s\n", program.getInfoLog()); + return nullptr; + } + + glslang::SpvOptions spvOptions; + spvOptions.generateDebugInfo = gen_debug; + spvOptions.optimizeSize = false; + spvOptions.disassemble = false; + spvOptions.validate = false; + + std::vector* output = new std::vector; + glslang::GlslangToSpv(*program.getIntermediate(stage), *output, nullptr, &spvOptions); + + *spirv_len = output->size(); + *spirv = output->data(); + return output; +} + +/* + * Destroys a buffer created by convert_glsl_to_spirv + */ +EMSCRIPTEN_KEEPALIVE +void destroy_output_buffer(void* p) +{ + delete static_cast*>(p); +} + +} // extern "C" + +/* + * For non-Emscripten builds we supply a generic main, so that the glslang.js + * build target can generate an executable with a trivial use case instead of + * generating a WASM binary. This is done so that there is a target that can be + * built and output analyzed using desktop tools, since WASM binaries are + * specific to the Emscripten toolchain. + */ +#ifndef __EMSCRIPTEN__ +int main() { + const char* input = R"(#version 310 es + +void main() { })"; + + uint32_t* output; + size_t output_len; + + void* id = convert_glsl_to_spirv(input, 4, false, glslang::EShTargetSpv_1_0, &output, &output_len); + assert(output != nullptr); + assert(output_len != 0); + destroy_output_buffer(id); + return 0; +} +#endif // ifndef __EMSCRIPTEN__ diff --git a/thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.pre.js b/thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.pre.js new file mode 100644 index 0000000..46a5695 --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.pre.js @@ -0,0 +1,56 @@ +Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug, spirv_version) { + gen_debug = !!gen_debug; + + var shader_stage_int; // EShLanguage + switch (shader_stage) { + case 'vertex': shader_stage_int = 0; break; + case 'fragment': shader_stage_int = 4; break; + case 'compute': shader_stage_int = 5; break; + default: + throw new Error("shader_stage must be 'vertex', 'fragment', or 'compute'."); + } + + spirv_version = spirv_version || '1.0'; + var spirv_version_int; // EShTargetLanguageVersion + switch (spirv_version) { + case '1.0': spirv_version_int = (1 << 16) | (0 << 8); break; + case '1.1': spirv_version_int = (1 << 16) | (1 << 8); break; + case '1.2': spirv_version_int = (1 << 16) | (2 << 8); break; + case '1.3': spirv_version_int = (1 << 16) | (3 << 8); break; + case '1.4': spirv_version_int = (1 << 16) | (4 << 8); break; + case '1.5': spirv_version_int = (1 << 16) | (5 << 8); break; + default: + throw new Error("spirv_version must be '1.0' ~ '1.5'."); + } + + var p_output = Module['_malloc'](4); + var p_output_len = Module['_malloc'](4); + var id = ccall('convert_glsl_to_spirv', + 'number', + ['string', 'number', 'boolean', 'number', 'number', 'number'], + [glsl, shader_stage_int, gen_debug, spirv_version_int, p_output, p_output_len]); + var output = getValue(p_output, 'i32'); + var output_len = getValue(p_output_len, 'i32'); + Module['_free'](p_output); + Module['_free'](p_output_len); + + if (id === 0) { + throw new Error('GLSL compilation failed'); + } + + var ret = {}; + var outputIndexU32 = output / 4; + ret['data'] = Module['HEAPU32'].subarray(outputIndexU32, outputIndexU32 + output_len); + ret['free'] = function() { + Module['_destroy_output_buffer'](id); + }; + + return ret; +}; + +Module['compileGLSL'] = function(glsl, shader_stage, gen_debug, spirv_version) { + var compiled = Module['compileGLSLZeroCopy'](glsl, shader_stage, gen_debug, spirv_version); + var ret = compiled['data'].slice() + compiled['free'](); + return ret; +}; diff --git a/thirdparty/ShaderCompiler/glslang/OSDependent/Windows/CMakeLists.txt b/thirdparty/ShaderCompiler/glslang/OSDependent/Windows/CMakeLists.txt new file mode 100644 index 0000000..9cf1b7f --- /dev/null +++ b/thirdparty/ShaderCompiler/glslang/OSDependent/Windows/CMakeLists.txt @@ -0,0 +1,54 @@ +# Copyright (C) 2020 The Khronos Group Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# Neither the name of The Khronos Group Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +set(SOURCES ossource.cpp ../osinclude.h) + +add_library(OSDependent STATIC ${SOURCES}) +set_property(TARGET OSDependent PROPERTY FOLDER glslang) +set_property(TARGET OSDependent PROPERTY POSITION_INDEPENDENT_CODE ON) + +# MinGW GCC complains about function pointer casts to void*. +# Turn that off with -fpermissive. +if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") + target_compile_options(OSDependent PRIVATE -fpermissive) +endif() + +if(WIN32) + source_group("Source" FILES ${SOURCES}) +endif(WIN32) + +if(ENABLE_GLSLANG_INSTALL) + install(TARGETS OSDependent EXPORT OSDependentTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) +endif(ENABLE_GLSLANG_INSTALL) diff --git a/thirdparty/ShaderCompiler/glslang/OSDependent/Windows/main.cpp b/thirdparty/ShaderCompiler/glslang/OSDependent/Windows/main.cpp index db11cc8..0bcde7b 100644 --- a/thirdparty/ShaderCompiler/glslang/OSDependent/Windows/main.cpp +++ b/thirdparty/ShaderCompiler/glslang/OSDependent/Windows/main.cpp @@ -32,7 +32,7 @@ // POSSIBILITY OF SUCH DAMAGE. // -#include "Thirdparty/ShaderCompiler/OGLCompilersDLL/InitializeDll.h" +#include "InitializeDll.h" #define STRICT #define VC_EXTRALEAN 1 diff --git a/thirdparty/ShaderCompiler/glslang/Public/ShaderLang.h b/thirdparty/ShaderCompiler/glslang/Public/ShaderLang.h index 26bf8bf..d2a4bf4 100644 --- a/thirdparty/ShaderCompiler/glslang/Public/ShaderLang.h +++ b/thirdparty/ShaderCompiler/glslang/Public/ShaderLang.h @@ -44,16 +44,25 @@ #include #ifdef _WIN32 -#define C_DECL __cdecl -//#ifdef SH_EXPORTING -// #define SH_IMPORT_EXPORT __declspec(dllexport) -//#else -// #define SH_IMPORT_EXPORT __declspec(dllimport) -//#endif -#define SH_IMPORT_EXPORT + #define C_DECL __cdecl #else -#define SH_IMPORT_EXPORT -#define C_DECL + #define C_DECL +#endif + +#ifdef GLSLANG_IS_SHARED_LIBRARY + #ifdef _WIN32 + #ifdef GLSLANG_EXPORTING + #define GLSLANG_EXPORT __declspec(dllexport) + #else + #define GLSLANG_EXPORT __declspec(dllimport) + #endif + #elif __GNUC__ >= 4 + #define GLSLANG_EXPORT __attribute__((visibility("default"))) + #endif +#endif // GLSLANG_IS_SHARED_LIBRARY + +#ifndef GLSLANG_EXPORT +#define GLSLANG_EXPORT #endif // @@ -65,22 +74,17 @@ extern "C" { #endif -// This should always increase, as some paths to do not consume -// a more major number. -// It should increment by one when new functionality is added. -#define GLSLANG_MINOR_VERSION 11 - // // Call before doing any other compiler/linker operations. // // (Call once per process, not once per thread.) // -SH_IMPORT_EXPORT int ShInitialize(); +GLSLANG_EXPORT int ShInitialize(); // // Call this at process shutdown to clean up memory. // -SH_IMPORT_EXPORT int ShFinalize(); +GLSLANG_EXPORT int ShFinalize(); // // Types of languages the compiler can consume. @@ -92,32 +96,45 @@ typedef enum { EShLangGeometry, EShLangFragment, EShLangCompute, - EShLangRayGenNV, - EShLangIntersectNV, - EShLangAnyHitNV, - EShLangClosestHitNV, - EShLangMissNV, - EShLangCallableNV, + EShLangRayGen, + EShLangRayGenNV = EShLangRayGen, + EShLangIntersect, + EShLangIntersectNV = EShLangIntersect, + EShLangAnyHit, + EShLangAnyHitNV = EShLangAnyHit, + EShLangClosestHit, + EShLangClosestHitNV = EShLangClosestHit, + EShLangMiss, + EShLangMissNV = EShLangMiss, + EShLangCallable, + EShLangCallableNV = EShLangCallable, EShLangTaskNV, EShLangMeshNV, - EShLangCount, + LAST_ELEMENT_MARKER(EShLangCount), } EShLanguage; // would be better as stage, but this is ancient now -typedef enum { +typedef enum : unsigned { EShLangVertexMask = (1 << EShLangVertex), EShLangTessControlMask = (1 << EShLangTessControl), EShLangTessEvaluationMask = (1 << EShLangTessEvaluation), EShLangGeometryMask = (1 << EShLangGeometry), EShLangFragmentMask = (1 << EShLangFragment), EShLangComputeMask = (1 << EShLangCompute), - EShLangRayGenNVMask = (1 << EShLangRayGenNV), - EShLangIntersectNVMask = (1 << EShLangIntersectNV), - EShLangAnyHitNVMask = (1 << EShLangAnyHitNV), - EShLangClosestHitNVMask = (1 << EShLangClosestHitNV), - EShLangMissNVMask = (1 << EShLangMissNV), - EShLangCallableNVMask = (1 << EShLangCallableNV), + EShLangRayGenMask = (1 << EShLangRayGen), + EShLangRayGenNVMask = EShLangRayGenMask, + EShLangIntersectMask = (1 << EShLangIntersect), + EShLangIntersectNVMask = EShLangIntersectMask, + EShLangAnyHitMask = (1 << EShLangAnyHit), + EShLangAnyHitNVMask = EShLangAnyHitMask, + EShLangClosestHitMask = (1 << EShLangClosestHit), + EShLangClosestHitNVMask = EShLangClosestHitMask, + EShLangMissMask = (1 << EShLangMiss), + EShLangMissNVMask = EShLangMissMask, + EShLangCallableMask = (1 << EShLangCallable), + EShLangCallableNVMask = EShLangCallableMask, EShLangTaskNVMask = (1 << EShLangTaskNV), EShLangMeshNVMask = (1 << EShLangMeshNV), + LAST_ELEMENT_MARKER(EShLanguageMaskCount), } EShLanguageMask; namespace glslang { @@ -126,36 +143,43 @@ class TType; typedef enum { EShSourceNone, - EShSourceGlsl, - EShSourceHlsl, -} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead + EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL) + EShSourceHlsl, // HLSL + LAST_ELEMENT_MARKER(EShSourceCount), +} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead typedef enum { - EShClientNone, + EShClientNone, // use when there is no client, e.g. for validation EShClientVulkan, EShClientOpenGL, + LAST_ELEMENT_MARKER(EShClientCount), } EShClient; typedef enum { EShTargetNone, - EShTargetSpv, // preferred spelling + EShTargetSpv, // SPIR-V (preferred spelling) EshTargetSpv = EShTargetSpv, // legacy spelling + LAST_ELEMENT_MARKER(EShTargetCount), } EShTargetLanguage; typedef enum { - EShTargetVulkan_1_0 = (1 << 22), - EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), - EShTargetOpenGL_450 = 450, + EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0 + EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1 + EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2 + EShTargetOpenGL_450 = 450, // OpenGL + LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 4), } EShTargetClientVersion; typedef EShTargetClientVersion EshTargetClientVersion; typedef enum { - EShTargetSpv_1_0 = (1 << 16), - EShTargetSpv_1_1 = (1 << 16) | (1 << 8), - EShTargetSpv_1_2 = (1 << 16) | (2 << 8), - EShTargetSpv_1_3 = (1 << 16) | (3 << 8), - EShTargetSpv_1_4 = (1 << 16) | (4 << 8), + EShTargetSpv_1_0 = (1 << 16), // SPIR-V 1.0 + EShTargetSpv_1_1 = (1 << 16) | (1 << 8), // SPIR-V 1.1 + EShTargetSpv_1_2 = (1 << 16) | (2 << 8), // SPIR-V 1.2 + EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3 + EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4 + EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5 + LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 6), } EShTargetLanguageVersion; struct TInputLanguage { @@ -163,6 +187,7 @@ struct TInputLanguage { EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone EShClient dialect; int dialectVersion; // version of client's language definition, not the client (when not EShClientNone) + bool vulkanRulesRelaxed; }; struct TClient { @@ -185,7 +210,7 @@ struct TEnvironment { TTarget target; // what to generate }; -const char* StageName(EShLanguage); +GLSLANG_EXPORT const char* StageName(EShLanguage); } // end namespace glslang @@ -205,6 +230,7 @@ typedef enum { EShOptNone, EShOptSimple, // Optimizations that can be done quickly EShOptFull, // Optimizations that will take more time + LAST_ELEMENT_MARKER(EshOptLevelCount), } EShOptimizationLevel; // @@ -213,12 +239,13 @@ typedef enum { typedef enum { EShTexSampTransKeep, // keep textures and samplers as is (default) EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers + LAST_ELEMENT_MARKER(EShTexSampTransCount), } EShTextureSamplerTransformMode; // // Message choices for what errors and warnings are given. // -enum EShMessages { +enum EShMessages : unsigned { EShMsgDefault = 0, // default is to give all required errors and extra warnings EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification @@ -233,9 +260,28 @@ enum EShMessages { EShMsgDebugInfo = (1 << 10), // save debug information EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages - EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers) + EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics) + EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table + LAST_ELEMENT_MARKER(EShMsgCount), }; +// +// Options for building reflection +// +typedef enum { + EShReflectionDefault = 0, // default is original behaviour before options were added + EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes + EShReflectionBasicArraySuffix = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection + EShReflectionIntermediateIO = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader + EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately + EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive + EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks + EShReflectionAllIOVariables = (1 << 6), // reflect all input/output variables, even if they are inactive + EShReflectionSharedStd140SSBO = (1 << 7), // Apply std140/shared rules for ubo to ssbo + EShReflectionSharedStd140UBO = (1 << 8), // Apply std140/shared rules for ubo to ssbo + LAST_ELEMENT_MARKER(EShReflectionCount), +} EShReflectionOptions; + // // Build a table for bindings. This can be used for locating // attributes, uniforms, globals, etc., as needed. @@ -265,10 +311,10 @@ typedef void* ShHandle; // Driver calls these to create and destroy compiler/linker // objects. // -SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader -SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair -SH_IMPORT_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object) -SH_IMPORT_EXPORT void ShDestruct(ShHandle); +GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader +GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair +GLSLANG_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object) +GLSLANG_EXPORT void ShDestruct(ShHandle); // // The return value of ShCompile is boolean, non-zero indicating @@ -277,7 +323,7 @@ SH_IMPORT_EXPORT void ShDestruct(ShHandle); // The info-log should be written by ShCompile into // ShHandle, so it can answer future queries. // -SH_IMPORT_EXPORT int ShCompile( +GLSLANG_EXPORT int ShCompile( const ShHandle, const char* const shaderStrings[], const int numStrings, @@ -290,7 +336,7 @@ SH_IMPORT_EXPORT int ShCompile( EShMessages messages = EShMsgDefault // warnings and errors ); -SH_IMPORT_EXPORT int ShLinkExt( +GLSLANG_EXPORT int ShLinkExt( const ShHandle, // linker object const ShHandle h[], // compiler objects to link together const int numHandles); @@ -299,26 +345,26 @@ SH_IMPORT_EXPORT int ShLinkExt( // ShSetEncrpytionMethod is a place-holder for specifying // how source code is encrypted. // -SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle); +GLSLANG_EXPORT void ShSetEncryptionMethod(ShHandle); // // All the following return 0 if the information is not // available in the object passed down, or the object is bad. // -SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle); -SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle); -SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing -SH_IMPORT_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings +GLSLANG_EXPORT const char* ShGetInfoLog(const ShHandle); +GLSLANG_EXPORT const void* ShGetExecutable(const ShHandle); +GLSLANG_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing +GLSLANG_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings // // Tell the linker to never assign a vertex attribute to this list of physical attributes // -SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count); +GLSLANG_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count); // // Returns the location ID of the named uniform. // Returns -1 if error. // -SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name); +GLSLANG_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name); #ifdef __cplusplus } // end extern "C" @@ -349,19 +395,27 @@ class TInfoSink; namespace glslang { -const char* GetEsslVersionString(); -const char* GetGlslVersionString(); -int GetKhronosToolId(); +struct Version { + int major; + int minor; + int patch; + const char* flavor; +}; + +GLSLANG_EXPORT Version GetVersion(); +GLSLANG_EXPORT const char* GetEsslVersionString(); +GLSLANG_EXPORT const char* GetGlslVersionString(); +GLSLANG_EXPORT int GetKhronosToolId(); class TIntermediate; class TProgram; class TPoolAllocator; // Call this exactly once per process before using anything else -bool InitializeProcess(); +GLSLANG_EXPORT bool InitializeProcess(); // Call once per process to tear down everything -void FinalizeProcess(); +GLSLANG_EXPORT void FinalizeProcess(); // Resource type for IO resolver enum TResourceType { @@ -374,11 +428,22 @@ enum TResourceType { EResCount }; +enum TBlockStorageClass +{ + EbsUniform = 0, + EbsStorageBuffer, + EbsPushConstant, + EbsNone, // not a uniform or buffer variable + EbsCount, +}; + // Make one TShader per shader that you will link into a program. Then // - provide the shader through setStrings() or setStringsWithLengths() // - optionally call setEnv*(), see below for more detail // - optionally use setPreamble() to set a special shader string that will be // processed before all others but won't affect the validity of #version +// - optionally call addProcesses() for each setting/transform, +// see comment for class TProcesses // - call parse(): source language and target environment must be selected // either by correct setting of EShMessages sent to parse(), or by // explicitly calling setEnv*() @@ -391,42 +456,79 @@ enum TResourceType { // class TShader { public: - explicit TShader(EShLanguage); - virtual ~TShader(); - void setStrings(const char* const* s, int n); - void setStringsWithLengths(const char* const* s, const int* l, int n); - void setStringsWithLengthsAndNames( + GLSLANG_EXPORT explicit TShader(EShLanguage); + GLSLANG_EXPORT virtual ~TShader(); + GLSLANG_EXPORT void setStrings(const char* const* s, int n); + GLSLANG_EXPORT void setStringsWithLengths( + const char* const* s, const int* l, int n); + GLSLANG_EXPORT void setStringsWithLengthsAndNames( const char* const* s, const int* l, const char* const* names, int n); void setPreamble(const char* s) { preamble = s; } - void setEntryPoint(const char* entryPoint); - void setSourceEntryPoint(const char* sourceEntryPointName); - void addProcesses(const std::vector&); + GLSLANG_EXPORT void setEntryPoint(const char* entryPoint); + GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName); + GLSLANG_EXPORT void addProcesses(const std::vector&); + GLSLANG_EXPORT void setUniqueId(unsigned long long id); // IO resolver binding data: see comments in ShaderLang.cpp - void setShiftBinding(TResourceType res, unsigned int base); - void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding - void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set); - void setResourceSetBinding(const std::vector& base); - void setAutoMapBindings(bool map); - void setAutoMapLocations(bool map); - void addUniformLocationOverride(const char* name, int loc); - void setUniformLocationBase(int base); - void setInvertY(bool invert); - void setHlslIoMapping(bool hlslIoMap); - void setFlattenUniformArrays(bool flatten); - void setNoStorageFormat(bool useUnknownFormat); - void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); + GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base); + GLSLANG_EXPORT void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding + GLSLANG_EXPORT void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set); + GLSLANG_EXPORT void setResourceSetBinding(const std::vector& base); + GLSLANG_EXPORT void setAutoMapBindings(bool map); + GLSLANG_EXPORT void setAutoMapLocations(bool map); + GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc); + GLSLANG_EXPORT void setUniformLocationBase(int base); + GLSLANG_EXPORT void setInvertY(bool invert); +#ifdef ENABLE_HLSL + GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap); + GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten); +#endif + GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat); + GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp); + GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); + GLSLANG_EXPORT void addBlockStorageOverride(const char* nameStr, glslang::TBlockStorageClass backing); + + GLSLANG_EXPORT void setGlobalUniformBlockName(const char* name); + GLSLANG_EXPORT void setAtomicCounterBlockName(const char* name); + GLSLANG_EXPORT void setGlobalUniformSet(unsigned int set); + GLSLANG_EXPORT void setGlobalUniformBinding(unsigned int binding); + GLSLANG_EXPORT void setAtomicCounterBlockSet(unsigned int set); + GLSLANG_EXPORT void setAtomicCounterBlockBinding(unsigned int binding); // For setting up the environment (cleared to nothingness in the constructor). // These must be called so that parsing is done for the right source language and // target environment, either indirectly through TranslateEnvironment() based on // EShMessages et. al., or directly by the user. + // + // setEnvInput: The input source language and stage. If generating code for a + // specific client, the input client semantics to use and the + // version of that client's input semantics to use, otherwise + // use EShClientNone and version of 0, e.g. for validation mode. + // Note 'version' does not describe the target environment, + // just the version of the source dialect to compile under. + // + // See the definitions of TEnvironment, EShSource, EShLanguage, + // and EShClient for choices and more detail. + // + // setEnvClient: The client that will be hosting the execution, and it's version. + // Note 'version' is not the version of the languages involved, but + // the version of the client environment. + // Use EShClientNone and version of 0 if there is no client, e.g. + // for validation mode. + // + // See EShTargetClientVersion for choices. + // + // setEnvTarget: The language to translate to when generating code, and that + // language's version. + // Use EShTargetNone and version of 0 if there is no client, e.g. + // for validation mode. + // void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version) { environment.input.languageFamily = lang; @@ -444,8 +546,18 @@ public: environment.target.language = lang; environment.target.version = version; } + + void getStrings(const char* const* &s, int& n) { s = strings; n = numStrings; } + +#ifdef ENABLE_HLSL void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; } bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; } +#else + bool getEnvTargetHlslFunctionality1() const { return false; } +#endif + + void setEnvInputVulkanRulesRelaxed() { environment.input.vulkanRulesRelaxed = true; } + bool getEnvInputVulkanRulesRelaxed() const { return environment.input.vulkanRulesRelaxed; } // Interface to #include handlers. // @@ -530,8 +642,10 @@ public: virtual void releaseInclude(IncludeResult*) override { } }; - bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, - bool forwardCompatible, EShMessages, Includer&); + GLSLANG_EXPORT bool parse( + const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, + bool forceDefaultVersionAndProfile, bool forwardCompatible, + EShMessages, Includer&); bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, bool forwardCompatible, EShMessages messages) @@ -554,13 +668,14 @@ public: // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string // is not an officially supported or fully working path. - bool preprocess(const TBuiltInResource* builtInResources, - int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, - bool forwardCompatible, EShMessages message, std::string* outputString, - Includer& includer); + GLSLANG_EXPORT bool preprocess( + const TBuiltInResource* builtInResources, int defaultVersion, + EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, EShMessages message, std::string* outputString, + Includer& includer); - const char* getInfoLog(); - const char* getInfoDebugLog(); + GLSLANG_EXPORT const char* getInfoLog(); + GLSLANG_EXPORT const char* getInfoDebugLog(); EShLanguage getStage() const { return stage; } TIntermediate* getIntermediate() const { return intermediate; } @@ -579,11 +694,11 @@ protected: // stringNames is the optional names for all the strings. If stringNames // is null, then none of the strings has name. If a certain element in // stringNames is null, then the corresponding string does not have name. - const char* const* strings; + const char* const* strings; // explicit code to compile, see previous comment const int* lengths; const char* const* stringNames; - const char* preamble; - int numStrings; + int numStrings; // size of the above arrays + const char* preamble; // string of implicit code to compile before the explicitly provided code // a function in the source string can be renamed FROM this TO the name given in setEntryPoint. std::string sourceEntryPointName; @@ -596,8 +711,47 @@ private: TShader& operator=(TShader&); }; -class TReflection; -class TIoMapper; +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + +// +// A reflection database and its interface, consistent with the OpenGL API reflection queries. +// + +// Data needed for just a single object at the granularity exchanged by the reflection API +class TObjectReflection { +public: + GLSLANG_EXPORT TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex); + + const TType* getType() const { return type; } + GLSLANG_EXPORT int getBinding() const; + GLSLANG_EXPORT void dump() const; + static TObjectReflection badReflection() { return TObjectReflection(); } + + std::string name; + int offset; + int glDefineType; + int size; // data size in bytes for a block, array size for a (non-block) object that's an array + int index; + int counterIndex; + int numMembers; + int arrayStride; // stride of an array variable + int topLevelArraySize; // size of the top-level variable in a storage buffer member + int topLevelArrayStride; // stride of the top-level variable in a storage buffer member + EShLanguageMask stages; + +protected: + TObjectReflection() + : offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), numMembers(-1), arrayStride(0), + topLevelArrayStride(0), stages(EShLanguageMask(0)), type(nullptr) + { + } + + const TType* type; +}; + +class TReflection; +class TIoMapper; +struct TVarEntryInfo; // Allows to customize the binding layout after linking. // All used uniform variables will invoke at least validateBinding. @@ -618,53 +772,65 @@ class TIoMapper; // notifiy callbacks, this phase ends with a call to endNotifications. // Phase two starts directly after the call to endNotifications // and calls all other callbacks to validate and to get the -// bindings, sets, locations, component and color indices. +// bindings, sets, locations, component and color indices. // // NOTE: that still limit checks are applied to bindings and sets // and may result in an error. class TIoMapResolver { public: - virtual ~TIoMapResolver() {} + virtual ~TIoMapResolver() {} - // Should return true if the resulting/current binding would be okay. - // Basic idea is to do aliasing binding checks with this. - virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current binding should be overridden. - // Return -1 if the current binding (including no binding) should be kept. - virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current set should be overridden. - // Return -1 if the current set (including no set) should be kept. - virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current location should be overridden. - // Return -1 if the current location (including no location) should be kept. - virtual int resolveUniformLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return true if the resulting/current setup would be okay. - // Basic idea is to do aliasing checks and reject invalid semantic names. - virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current location should be overridden. - // Return -1 if the current location (including no location) should be kept. - virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current component index should be overridden. - // Return -1 if the current component index (including no index) should be kept. - virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current color index should be overridden. - // Return -1 if the current color index (including no index) should be kept. - virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Notification of a uniform variable - virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Notification of a in or out variable - virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Called by mapIO when it has finished the notify pass - virtual void endNotifications(EShLanguage stage) = 0; - // Called by mapIO when it starts its notify pass for the given stage - virtual void beginNotifications(EShLanguage stage) = 0; - // Called by mipIO when it starts its resolve pass for the given stage - virtual void beginResolve(EShLanguage stage) = 0; - // Called by mapIO when it has finished the resolve pass - virtual void endResolve(EShLanguage stage) = 0; + // Should return true if the resulting/current binding would be okay. + // Basic idea is to do aliasing binding checks with this. + virtual bool validateBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current binding should be overridden. + // Return -1 if the current binding (including no binding) should be kept. + virtual int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current set should be overridden. + // Return -1 if the current set (including no set) should be kept. + virtual int resolveSet(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current location should be overridden. + // Return -1 if the current location (including no location) should be kept. + virtual int resolveUniformLocation(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return true if the resulting/current setup would be okay. + // Basic idea is to do aliasing checks and reject invalid semantic names. + virtual bool validateInOut(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current location should be overridden. + // Return -1 if the current location (including no location) should be kept. + virtual int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current component index should be overridden. + // Return -1 if the current component index (including no index) should be kept. + virtual int resolveInOutComponent(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current color index should be overridden. + // Return -1 if the current color index (including no index) should be kept. + virtual int resolveInOutIndex(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Notification of a uniform variable + virtual void notifyBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Notification of a in or out variable + virtual void notifyInOut(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Called by mapIO when it starts its notify pass for the given stage + virtual void beginNotifications(EShLanguage stage) = 0; + // Called by mapIO when it has finished the notify pass + virtual void endNotifications(EShLanguage stage) = 0; + // Called by mipIO when it starts its resolve pass for the given stage + virtual void beginResolve(EShLanguage stage) = 0; + // Called by mapIO when it has finished the resolve pass + virtual void endResolve(EShLanguage stage) = 0; + // Called by mapIO when it starts its symbol collect for teh given stage + virtual void beginCollect(EShLanguage stage) = 0; + // Called by mapIO when it has finished the symbol collect + virtual void endCollect(EShLanguage stage) = 0; + // Called by TSlotCollector to resolve storage locations or bindings + virtual void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; + // Called by TSlotCollector to resolve resource locations or bindings + virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; + // Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline + virtual void addStage(EShLanguage stage, TIntermediate& stageIntermediate) = 0; }; +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE + // Make one TProgram per set of shaders that will get linked together. Add all // the shaders that are to be linked together. After calling shader.parse() // for all shaders, call link(). @@ -673,58 +839,125 @@ public: // class TProgram { public: - TProgram(); - virtual ~TProgram(); + GLSLANG_EXPORT TProgram(); + GLSLANG_EXPORT virtual ~TProgram(); void addShader(TShader* shader) { stages[shader->stage].push_back(shader); } - + std::list& getShaders(EShLanguage stage) { return stages[stage]; } // Link Validation interface - bool link(EShMessages); - const char* getInfoLog(); - const char* getInfoDebugLog(); + GLSLANG_EXPORT bool link(EShMessages); + GLSLANG_EXPORT const char* getInfoLog(); + GLSLANG_EXPORT const char* getInfoDebugLog(); TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; } +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + // Reflection Interface - bool buildReflection(); // call first, to do liveness analysis, index mapping, etc.; returns false on failure - int getNumLiveUniformVariables() const; // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) - int getNumLiveUniformBlocks() const; // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) - const char* getUniformName(int index) const; // can be used for "name" part of glGetActiveUniform() - const char* getUniformBlockName(int blockIndex) const; // can be used for glGetActiveUniformBlockName() - int getUniformBlockSize(int blockIndex) const; // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) - int getUniformIndex(const char* name) const; // can be used for glGetUniformIndices() - int getUniformBinding(int index) const; // returns the binding number - EShLanguageMask getUniformStages(int index) const; // returns Shaders Stages where a Uniform is present - int getUniformBlockBinding(int index) const; // returns the block binding number - int getUniformBlockIndex(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) - int getUniformBlockCounterIndex(int index) const; // returns block index of associated counter. - int getUniformType(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) - int getUniformBufferOffset(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) - int getUniformArraySize(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) - int getNumLiveAttributes() const; // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) - unsigned getLocalSize(int dim) const; // return dim'th local size - const char *getAttributeName(int index) const; // can be used for glGetActiveAttrib() - int getAttributeType(int index) const; // can be used for glGetActiveAttrib() - const TType* getUniformTType(int index) const; // returns a TType* - const TType* getUniformBlockTType(int index) const; // returns a TType* - const TType* getAttributeTType(int index) const; // returns a TType* - void dumpReflection(); + // call first, to do liveness analysis, index mapping, etc.; returns false on failure + GLSLANG_EXPORT bool buildReflection(int opts = EShReflectionDefault); + GLSLANG_EXPORT unsigned getLocalSize(int dim) const; // return dim'th local size + GLSLANG_EXPORT int getReflectionIndex(const char *name) const; + GLSLANG_EXPORT int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const; + GLSLANG_EXPORT int getNumUniformVariables() const; + GLSLANG_EXPORT const TObjectReflection& getUniform(int index) const; + GLSLANG_EXPORT int getNumUniformBlocks() const; + GLSLANG_EXPORT const TObjectReflection& getUniformBlock(int index) const; + GLSLANG_EXPORT int getNumPipeInputs() const; + GLSLANG_EXPORT const TObjectReflection& getPipeInput(int index) const; + GLSLANG_EXPORT int getNumPipeOutputs() const; + GLSLANG_EXPORT const TObjectReflection& getPipeOutput(int index) const; + GLSLANG_EXPORT int getNumBufferVariables() const; + GLSLANG_EXPORT const TObjectReflection& getBufferVariable(int index) const; + GLSLANG_EXPORT int getNumBufferBlocks() const; + GLSLANG_EXPORT const TObjectReflection& getBufferBlock(int index) const; + GLSLANG_EXPORT int getNumAtomicCounters() const; + GLSLANG_EXPORT const TObjectReflection& getAtomicCounter(int index) const; + // Legacy Reflection Interface - expressed in terms of above interface + + // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) + int getNumLiveUniformVariables() const { return getNumUniformVariables(); } + + // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) + int getNumLiveUniformBlocks() const { return getNumUniformBlocks(); } + + // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) + int getNumLiveAttributes() const { return getNumPipeInputs(); } + + // can be used for glGetUniformIndices() + int getUniformIndex(const char *name) const { return getReflectionIndex(name); } + + int getPipeIOIndex(const char *name, const bool inOrOut) const + { return getReflectionPipeIOIndex(name, inOrOut); } + + // can be used for "name" part of glGetActiveUniform() + const char *getUniformName(int index) const { return getUniform(index).name.c_str(); } + + // returns the binding number + int getUniformBinding(int index) const { return getUniform(index).getBinding(); } + + // returns Shaders Stages where a Uniform is present + EShLanguageMask getUniformStages(int index) const { return getUniform(index).stages; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) + int getUniformBlockIndex(int index) const { return getUniform(index).index; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) + int getUniformType(int index) const { return getUniform(index).glDefineType; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) + int getUniformBufferOffset(int index) const { return getUniform(index).offset; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) + int getUniformArraySize(int index) const { return getUniform(index).size; } + + // returns a TType* + const TType *getUniformTType(int index) const { return getUniform(index).getType(); } + + // can be used for glGetActiveUniformBlockName() + const char *getUniformBlockName(int index) const { return getUniformBlock(index).name.c_str(); } + + // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) + int getUniformBlockSize(int index) const { return getUniformBlock(index).size; } + + // returns the block binding number + int getUniformBlockBinding(int index) const { return getUniformBlock(index).getBinding(); } + + // returns block index of associated counter. + int getUniformBlockCounterIndex(int index) const { return getUniformBlock(index).counterIndex; } + + // returns a TType* + const TType *getUniformBlockTType(int index) const { return getUniformBlock(index).getType(); } + + // can be used for glGetActiveAttrib() + const char *getAttributeName(int index) const { return getPipeInput(index).name.c_str(); } + + // can be used for glGetActiveAttrib() + int getAttributeType(int index) const { return getPipeInput(index).glDefineType; } + + // returns a TType* + const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); } + + GLSLANG_EXPORT void dumpReflection(); // I/O mapping: apply base offsets and map live unbound variables // If resolver is not provided it uses the previous approach // and respects auto assignment and offsets. - bool mapIO(TIoMapResolver* resolver = NULL); + GLSLANG_EXPORT bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr); +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE protected: - bool linkStage(EShLanguage, EShMessages); + GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages); + GLSLANG_EXPORT bool crossStageCheck(EShMessages); TPoolAllocator* pool; std::list stages[EShLangCount]; TIntermediate* intermediate[EShLangCount]; bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage TInfoSink* infoSink; +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) TReflection* reflection; - TIoMapper* ioMapper; +#endif bool linked; private: diff --git a/thirdparty/ShaderCompiler/glslang/updateGrammar b/thirdparty/ShaderCompiler/glslang/updateGrammar index a546dd2..9209493 100644 --- a/thirdparty/ShaderCompiler/glslang/updateGrammar +++ b/thirdparty/ShaderCompiler/glslang/updateGrammar @@ -1,3 +1,49 @@ -#!/usr/bin/env bash +#!/bin/bash + +# Copyright (C) 2020 The Khronos Group Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# Neither the name of The Khronos Group Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +if [ "$1" = 'web' ] +then + m4 -P -DGLSLANG_WEB MachineIndependent/glslang.m4 > MachineIndependent/glslang.y +elif [ "$#" -eq 0 ] +then + m4 -P MachineIndependent/glslang.m4 > MachineIndependent/glslang.y +else + echo usage: + echo $0 web + echo $0 + exit +fi bison --defines=MachineIndependent/glslang_tab.cpp.h -t MachineIndependent/glslang.y -o MachineIndependent/glslang_tab.cpp diff --git a/thirdparty/ShaderCompiler/spirv/GLSL.ext.EXT.h b/thirdparty/ShaderCompiler/spirv/GLSL.ext.EXT.h index e29c055..f48f130 100644 --- a/thirdparty/ShaderCompiler/spirv/GLSL.ext.EXT.h +++ b/thirdparty/ShaderCompiler/spirv/GLSL.ext.EXT.h @@ -34,5 +34,10 @@ static const char* const E_SPV_EXT_shader_stencil_export = "SPV_EXT_shade static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shader_viewport_index_layer"; static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered"; static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density"; +static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation"; +static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add"; +static const char* const E_SPV_EXT_shader_atomic_float16_add = "SPV_EXT_shader_atomic_float16_add"; +static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader_atomic_float_min_max"; +static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64"; #endif // #ifndef GLSLextEXT_H diff --git a/thirdparty/ShaderCompiler/spirv/GLSL.ext.KHR.h b/thirdparty/ShaderCompiler/spirv/GLSL.ext.KHR.h index 333442b..5eb3e94 100644 --- a/thirdparty/ShaderCompiler/spirv/GLSL.ext.KHR.h +++ b/thirdparty/ShaderCompiler/spirv/GLSL.ext.KHR.h @@ -1,5 +1,6 @@ /* -** Copyright (c) 2014-2016 The Khronos Group Inc. +** Copyright (c) 2014-2020 The Khronos Group Inc. +** Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and/or associated documentation files (the "Materials"), @@ -41,5 +42,15 @@ static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_stora static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage"; static const char* const E_SPV_KHR_vulkan_memory_model = "SPV_KHR_vulkan_memory_model"; static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physical_storage_buffer"; +static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer"; +static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock"; +static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock"; +static const char* const E_SPV_KHR_non_semantic_info = "SPV_KHR_non_semantic_info"; +static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_tracing"; +static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query"; +static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragment_shading_rate"; +static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation"; +static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout"; +static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow"; #endif // #ifndef GLSLextKHR_H diff --git a/thirdparty/ShaderCompiler/spirv/GLSL.ext.NV.h b/thirdparty/ShaderCompiler/spirv/GLSL.ext.NV.h index 102d645..93c98bf 100644 --- a/thirdparty/ShaderCompiler/spirv/GLSL.ext.NV.h +++ b/thirdparty/ShaderCompiler/spirv/GLSL.ext.NV.h @@ -69,7 +69,16 @@ const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader"; //SPV_NV_raytracing const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing"; +//SPV_NV_ray_tracing_motion_blur +const char* const E_SPV_NV_ray_tracing_motion_blur = "SPV_NV_ray_tracing_motion_blur"; + //SPV_NV_shading_rate const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate"; +//SPV_NV_cooperative_matrix +const char* const E_SPV_NV_cooperative_matrix = "SPV_NV_cooperative_matrix"; + +//SPV_NV_shader_sm_builtins +const char* const E_SPV_NV_shader_sm_builtins = "SPV_NV_shader_sm_builtins"; + #endif // #ifndef GLSLextNV_H diff --git a/thirdparty/ShaderCompiler/spirv/GlslangToSpv.cpp b/thirdparty/ShaderCompiler/spirv/GlslangToSpv.cpp index 9bf3704..42b084c 100644 --- a/thirdparty/ShaderCompiler/spirv/GlslangToSpv.cpp +++ b/thirdparty/ShaderCompiler/spirv/GlslangToSpv.cpp @@ -1,7 +1,8 @@ // // Copyright (C) 2014-2016 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -46,19 +47,18 @@ namespace spv { #include "GLSL.std.450.h" #include "GLSL.ext.KHR.h" #include "GLSL.ext.EXT.h" -#ifdef AMD_EXTENSIONS #include "GLSL.ext.AMD.h" -#endif -#ifdef NV_EXTENSIONS #include "GLSL.ext.NV.h" -#endif + #include "NonSemanticDebugPrintf.h" } // Glslang includes #include "../glslang/MachineIndependent/localintermediate.h" #include "../glslang/MachineIndependent/SymbolTable.h" #include "../glslang/Include/Common.h" -#include "../glslang/Include/revision.h" + +// Build-time generated includes +#include "../glslang/Include/build_info.h" #include #include @@ -91,9 +91,29 @@ private: }; struct OpDecorations { + public: + OpDecorations(spv::Decoration precision, spv::Decoration noContraction, spv::Decoration nonUniform) : + precision(precision) +#ifndef GLSLANG_WEB + , + noContraction(noContraction), + nonUniform(nonUniform) +#endif + { } + spv::Decoration precision; - spv::Decoration noContraction; - spv::Decoration nonUniform; + +#ifdef GLSLANG_WEB + void addNoContraction(spv::Builder&, spv::Id) const { } + void addNonUniform(spv::Builder&, spv::Id) const { } +#else + void addNoContraction(spv::Builder& builder, spv::Id t) { builder.addDecoration(t, noContraction); } + void addNonUniform(spv::Builder& builder, spv::Id t) { builder.addDecoration(t, nonUniform); } + protected: + spv::Decoration noContraction; + spv::Decoration nonUniform; +#endif + }; } // namespace @@ -129,6 +149,7 @@ protected: spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier); spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier); spv::Decoration TranslateNonUniformDecoration(const glslang::TQualifier& qualifier); + spv::Decoration TranslateNonUniformDecoration(const spv::Builder::AccessChain::CoherentFlags& coherentFlags); spv::Builder::AccessChain::CoherentFlags TranslateCoherent(const glslang::TType& type); spv::MemoryAccessMask TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags); spv::ImageOperandsMask TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags); @@ -137,10 +158,11 @@ protected: spv::ImageFormat TranslateImageFormat(const glslang::TType& type); spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const; spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const; - spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, unsigned int& dependencyLength) const; + spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, std::vector& operands) const; spv::StorageClass TranslateStorageClass(const glslang::TType&); + void TranslateLiterals(const glslang::TVector&, std::vector&) const; void addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType); - spv::Id createSpvVariable(const glslang::TIntermSymbol*); + spv::Id createSpvVariable(const glslang::TIntermSymbol*, spv::Id forcedType); spv::Id getSampledType(const glslang::TSampler&); spv::Id getInvertedSwizzleType(const glslang::TIntermTyped&); spv::Id createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped&, spv::Id parentResult); @@ -157,6 +179,7 @@ protected: spv::Id accessChainLoad(const glslang::TType& type); void accessChainStore(const glslang::TType& type, spv::Id rvalue); void multiTypeStore(const glslang::TType&, spv::Id rValue); + spv::Id convertLoadedBoolInUniformToUint(const glslang::TType& type, spv::Id nominalTypeId, spv::Id loadedId); glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const; int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix); int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix); @@ -169,9 +192,11 @@ protected: bool originalParam(glslang::TStorageQualifier, const glslang::TType&, bool implicitThisParam); void makeFunctions(const glslang::TIntermSequence&); void makeGlobalInitializers(const glslang::TIntermSequence&); + void collectRayTracingLinkerObjects(); void visitFunctions(const glslang::TIntermSequence&); void handleFunctionEntry(const glslang::TIntermAggregate* node); - void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments); + void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, + spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); void translateArguments(glslang::TIntermUnary& node, std::vector& arguments); spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node); spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*); @@ -180,45 +205,38 @@ protected: glslang::TBasicType typeProxy, bool reduceComparison = true); spv::Id createBinaryMatrixOperation(spv::Op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right); spv::Id createUnaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id operand, - glslang::TBasicType typeProxy); + glslang::TBasicType typeProxy, + const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); spv::Id createUnaryMatrixOperation(spv::Op op, OpDecorations&, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy); spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand, glslang::TBasicType typeProxy); spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize); spv::Id makeSmearedConstant(spv::Id constant, int vectorSize); - spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); - spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); - spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector& operands); - spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); - spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); + spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, + std::vector& operands, glslang::TBasicType typeProxy, + const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); + spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, + glslang::TBasicType typeProxy); + spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, + spv::Id typeId, std::vector& operands); + spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, + glslang::TBasicType typeProxy); + spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, + std::vector& operands, glslang::TBasicType typeProxy); spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId); spv::Id getSymbolId(const glslang::TIntermSymbol* node); -#ifdef NV_EXTENSIONS void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier); -#endif spv::Id createSpvConstant(const glslang::TIntermTyped&); - spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant); + spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, + int& nextConst, bool specConstant); bool isTrivialLeaf(const glslang::TIntermTyped* node); bool isTrivial(const glslang::TIntermTyped* node); spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right); -#ifdef AMD_EXTENSIONS spv::Id getExtBuiltins(const char* name); -#endif - void addPre13Extension(const char* ext) - { - if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3) - builder.addExtension(ext); - } - - unsigned int getBufferReferenceAlignment(const glslang::TType &type) const { - if (type.getBasicType() == glslang::EbtReference) { - return type.getReferentType()->getQualifier().hasBufferReferenceAlign() ? - (1u << type.getReferentType()->getQualifier().layoutBufferReferenceAlign) : 16u; - } else { - return 0; - } - } + std::pair getForcedType(glslang::TBuiltInVariable builtIn, const glslang::TType&); + spv::Id translateForcedType(spv::Id object); + spv::Id createCompositeConstruct(spv::Id typeId, std::vector constituents); glslang::SpvOptions& options; spv::Function* shaderEntry; @@ -232,22 +250,35 @@ protected: spv::Builder builder; bool inEntryPoint; bool entryPointTerminated; - bool linkageOnly; // true when visiting the set of objects in the AST present only for establishing interface, whether or not they were statically used + bool linkageOnly; // true when visiting the set of objects in the AST present only for + // establishing interface, whether or not they were statically used std::set iOSet; // all input/output variables from either static use or declaration of interface const glslang::TIntermediate* glslangIntermediate; + bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp spv::Id stdBuiltins; - std::unordered_map extBuiltinMap; + spv::Id nonSemanticDebugPrintf; + std::unordered_map extBuiltinMap; - std::unordered_map symbolValues; - std::unordered_set rValueParameters; // set of formal function parameters passed as rValues, rather than a pointer + std::unordered_map symbolValues; + std::unordered_set rValueParameters; // set of formal function parameters passed as rValues, + // rather than a pointer std::unordered_map functionMap; std::unordered_map structMap[glslang::ElpCount][glslang::ElmCount]; // for mapping glslang block indices to spv indices (e.g., due to hidden members): - std::unordered_map > memberRemapper; + std::unordered_map> memberRemapper; + // for mapping glslang symbol struct to symbol Id + std::unordered_map glslangTypeToIdMap; std::stack breakForLoop; // false means break for switch std::unordered_map counterOriginator; // Map pointee types for EbtReference to their forward pointers std::map forwardPointers; + // Type forcing, for when SPIR-V wants a different type than the AST, + // requiring local translation to and from SPIR-V type on every access. + // Maps AST-required-type-id> + std::unordered_map forceType; + + // Used later for generating OpTraceKHR/OpExecuteCallableKHR + std::unordered_map locationToSymbol[2]; }; // @@ -257,6 +288,12 @@ protected: // Translate glslang profile to SPIR-V source language. spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile) { +#ifdef GLSLANG_WEB + return spv::SourceLanguageESSL; +#elif defined(GLSLANG_ANGLE) + return spv::SourceLanguageGLSL; +#endif + switch (source) { case glslang::EShSourceGlsl: switch (profile) { @@ -281,18 +318,18 @@ spv::ExecutionModel TranslateExecutionModel(EShLanguage stage) { switch (stage) { case EShLangVertex: return spv::ExecutionModelVertex; + case EShLangFragment: return spv::ExecutionModelFragment; + case EShLangCompute: return spv::ExecutionModelGLCompute; +#ifndef GLSLANG_WEB case EShLangTessControl: return spv::ExecutionModelTessellationControl; case EShLangTessEvaluation: return spv::ExecutionModelTessellationEvaluation; case EShLangGeometry: return spv::ExecutionModelGeometry; - case EShLangFragment: return spv::ExecutionModelFragment; - case EShLangCompute: return spv::ExecutionModelGLCompute; -#ifdef NV_EXTENSIONS - case EShLangRayGenNV: return spv::ExecutionModelRayGenerationNV; - case EShLangIntersectNV: return spv::ExecutionModelIntersectionNV; - case EShLangAnyHitNV: return spv::ExecutionModelAnyHitNV; - case EShLangClosestHitNV: return spv::ExecutionModelClosestHitNV; - case EShLangMissNV: return spv::ExecutionModelMissNV; - case EShLangCallableNV: return spv::ExecutionModelCallableNV; + case EShLangRayGen: return spv::ExecutionModelRayGenerationKHR; + case EShLangIntersect: return spv::ExecutionModelIntersectionKHR; + case EShLangAnyHit: return spv::ExecutionModelAnyHitKHR; + case EShLangClosestHit: return spv::ExecutionModelClosestHitKHR; + case EShLangMiss: return spv::ExecutionModelMissKHR; + case EShLangCallable: return spv::ExecutionModelCallableKHR; case EShLangTaskNV: return spv::ExecutionModelTaskNV; case EShLangMeshNV: return spv::ExecutionModelMeshNV; #endif @@ -345,12 +382,13 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock; case glslang::EvqVaryingIn: return spv::DecorationBlock; case glslang::EvqVaryingOut: return spv::DecorationBlock; -#ifdef NV_EXTENSIONS - case glslang::EvqPayloadNV: return spv::DecorationBlock; - case glslang::EvqPayloadInNV: return spv::DecorationBlock; - case glslang::EvqHitAttrNV: return spv::DecorationBlock; - case glslang::EvqCallableDataNV: return spv::DecorationBlock; - case glslang::EvqCallableDataInNV: return spv::DecorationBlock; + case glslang::EvqShared: return spv::DecorationBlock; +#ifndef GLSLANG_WEB + case glslang::EvqPayload: return spv::DecorationBlock; + case glslang::EvqPayloadIn: return spv::DecorationBlock; + case glslang::EvqHitAttr: return spv::DecorationBlock; + case glslang::EvqCallableData: return spv::DecorationBlock; + case glslang::EvqCallableDataIn: return spv::DecorationBlock; #endif default: assert(0); @@ -362,21 +400,22 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto } // Translate glslang type to SPIR-V memory decorations. -void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector& memory, bool useVulkanMemoryModel) +void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector& memory, + bool useVulkanMemoryModel) { if (!useVulkanMemoryModel) { - if (qualifier.coherent) + if (qualifier.isCoherent()) memory.push_back(spv::DecorationCoherent); - if (qualifier.volatil) { + if (qualifier.isVolatile()) { memory.push_back(spv::DecorationVolatile); memory.push_back(spv::DecorationCoherent); } } - if (qualifier.restrict) + if (qualifier.isRestrict()) memory.push_back(spv::DecorationRestrict); - if (qualifier.readonly) + if (qualifier.isReadOnly()) memory.push_back(spv::DecorationNonWritable); - if (qualifier.writeonly) + if (qualifier.isWriteOnly()) memory.push_back(spv::DecorationNonReadable); } @@ -400,6 +439,7 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T break; case glslang::EbtBlock: switch (type.getQualifier().storage) { + case glslang::EvqShared: case glslang::EvqUniform: case glslang::EvqBuffer: switch (type.getQualifier().layoutPacking) { @@ -420,12 +460,12 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T assert(type.getQualifier().layoutPacking == glslang::ElpNone); } return spv::DecorationMax; -#ifdef NV_EXTENSIONS - case glslang::EvqPayloadNV: - case glslang::EvqPayloadInNV: - case glslang::EvqHitAttrNV: - case glslang::EvqCallableDataNV: - case glslang::EvqCallableDataInNV: +#ifndef GLSLANG_WEB + case glslang::EvqPayload: + case glslang::EvqPayloadIn: + case glslang::EvqHitAttr: + case glslang::EvqCallableData: + case glslang::EvqCallableDataIn: return spv::DecorationMax; #endif default: @@ -444,16 +484,14 @@ spv::Decoration TGlslangToSpvTraverser::TranslateInterpolationDecoration(const g if (qualifier.smooth) // Smooth decoration doesn't exist in SPIR-V 1.0 return spv::DecorationMax; - else if (qualifier.nopersp) + else if (qualifier.isNonPerspective()) return spv::DecorationNoPerspective; else if (qualifier.flat) return spv::DecorationFlat; -#ifdef AMD_EXTENSIONS - else if (qualifier.explicitInterp) { + else if (qualifier.isExplicitInterpolation()) { builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter); return spv::DecorationExplicitInterpAMD; } -#endif else return spv::DecorationMax; } @@ -463,15 +501,18 @@ spv::Decoration TGlslangToSpvTraverser::TranslateInterpolationDecoration(const g // should be applied. spv::Decoration TGlslangToSpvTraverser::TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier) { - if (qualifier.patch) - return spv::DecorationPatch; - else if (qualifier.centroid) + if (qualifier.centroid) return spv::DecorationCentroid; +#ifndef GLSLANG_WEB + else if (qualifier.patch) + return spv::DecorationPatch; else if (qualifier.sample) { builder.addCapability(spv::CapabilitySampleRateShading); return spv::DecorationSample; - } else - return spv::DecorationMax; + } +#endif + + return spv::DecorationMax; } // If glslang type is invariant, return SPIR-V invariant decoration. @@ -486,38 +527,55 @@ spv::Decoration TranslateInvariantDecoration(const glslang::TQualifier& qualifie // If glslang type is noContraction, return SPIR-V NoContraction decoration. spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qualifier) { - if (qualifier.noContraction) +#ifndef GLSLANG_WEB + if (qualifier.isNoContraction()) return spv::DecorationNoContraction; else +#endif return spv::DecorationMax; } // If glslang type is nonUniform, return SPIR-V NonUniform decoration. spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glslang::TQualifier& qualifier) { +#ifndef GLSLANG_WEB if (qualifier.isNonUniform()) { - builder.addExtension("SPV_EXT_descriptor_indexing"); + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityShaderNonUniformEXT); return spv::DecorationNonUniformEXT; } else +#endif return spv::DecorationMax; } -spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags) +// If lvalue flags contains nonUniform, return SPIR-V NonUniform decoration. +spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration( + const spv::Builder::AccessChain::CoherentFlags& coherentFlags) +{ +#ifndef GLSLANG_WEB + if (coherentFlags.isNonUniform()) { + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); + builder.addCapability(spv::CapabilityShaderNonUniformEXT); + return spv::DecorationNonUniformEXT; + } else +#endif + return spv::DecorationMax; +} + +spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess( + const spv::Builder::AccessChain::CoherentFlags &coherentFlags) { - if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) { - return spv::MemoryAccessMaskNone; - } spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone; - if (coherentFlags.volatil || - coherentFlags.coherent || - coherentFlags.devicecoherent || - coherentFlags.queuefamilycoherent || - coherentFlags.workgroupcoherent || - coherentFlags.subgroupcoherent) { + +#ifndef GLSLANG_WEB + if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) + return mask; + + if (coherentFlags.isVolatile() || coherentFlags.anyCoherent()) { mask = mask | spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask; } + if (coherentFlags.nonprivate) { mask = mask | spv::MemoryAccessNonPrivatePointerKHRMask; } @@ -527,21 +585,22 @@ spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(const spv::B if (mask != spv::MemoryAccessMaskNone) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } +#endif + return mask; } -spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags) +spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands( + const spv::Builder::AccessChain::CoherentFlags &coherentFlags) { - if (!glslangIntermediate->usingVulkanMemoryModel()) { - return spv::ImageOperandsMaskNone; - } spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; + +#ifndef GLSLANG_WEB + if (!glslangIntermediate->usingVulkanMemoryModel()) + return mask; + if (coherentFlags.volatil || - coherentFlags.coherent || - coherentFlags.devicecoherent || - coherentFlags.queuefamilycoherent || - coherentFlags.workgroupcoherent || - coherentFlags.subgroupcoherent) { + coherentFlags.anyCoherent()) { mask = mask | spv::ImageOperandsMakeTexelAvailableKHRMask | spv::ImageOperandsMakeTexelVisibleKHRMask; } @@ -554,12 +613,15 @@ spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(const spv: if (mask != spv::ImageOperandsMaskNone) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } +#endif + return mask; } spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCoherent(const glslang::TType& type) { - spv::Builder::AccessChain::CoherentFlags flags; + spv::Builder::AccessChain::CoherentFlags flags = {}; +#ifndef GLSLANG_WEB flags.coherent = type.getQualifier().coherent; flags.devicecoherent = type.getQualifier().devicecoherent; flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent; @@ -567,22 +629,25 @@ spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCohere flags.workgroupcoherent = type.getQualifier().workgroupcoherent || type.getQualifier().storage == glslang::EvqShared; flags.subgroupcoherent = type.getQualifier().subgroupcoherent; + flags.shadercallcoherent = type.getQualifier().shadercallcoherent; + flags.volatil = type.getQualifier().volatil; // *coherent variables are implicitly nonprivate in GLSL flags.nonprivate = type.getQualifier().nonprivate || - flags.subgroupcoherent || - flags.workgroupcoherent || - flags.queuefamilycoherent || - flags.devicecoherent || - flags.coherent; - flags.volatil = type.getQualifier().volatil; + flags.anyCoherent() || + flags.volatil; flags.isImage = type.getBasicType() == glslang::EbtSampler; +#endif + flags.nonUniform = type.getQualifier().nonUniform; return flags; } -spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags) +spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope( + const spv::Builder::AccessChain::CoherentFlags &coherentFlags) { - spv::Scope scope; - if (coherentFlags.coherent) { + spv::Scope scope = spv::ScopeMax; + +#ifndef GLSLANG_WEB + if (coherentFlags.volatil || coherentFlags.coherent) { // coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice; } else if (coherentFlags.devicecoherent) { @@ -593,12 +658,14 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::Acce scope = spv::ScopeWorkgroup; } else if (coherentFlags.subgroupcoherent) { scope = spv::ScopeSubgroup; - } else { - scope = spv::ScopeMax; + } else if (coherentFlags.shadercallcoherent) { + scope = spv::ScopeShaderCallKHR; } if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) { builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); } +#endif + return scope; } @@ -607,10 +674,12 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::Acce // is generated only when using the variable in an executable instruction, but not when // just declaring a struct member variable with it. This is true for PointSize, // ClipDistance, and CullDistance. -spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, bool memberDeclaration) +spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, + bool memberDeclaration) { switch (builtIn) { case glslang::EbvPointSize: +#ifndef GLSLANG_WEB // Defer adding the capability until the built-in is actually used. if (! memberDeclaration) { switch (glslangIntermediate->getStage()) { @@ -625,8 +694,28 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI break; } } +#endif return spv::BuiltInPointSize; + case glslang::EbvPosition: return spv::BuiltInPosition; + case glslang::EbvVertexId: return spv::BuiltInVertexId; + case glslang::EbvInstanceId: return spv::BuiltInInstanceId; + case glslang::EbvVertexIndex: return spv::BuiltInVertexIndex; + case glslang::EbvInstanceIndex: return spv::BuiltInInstanceIndex; + + case glslang::EbvFragCoord: return spv::BuiltInFragCoord; + case glslang::EbvPointCoord: return spv::BuiltInPointCoord; + case glslang::EbvFace: return spv::BuiltInFrontFacing; + case glslang::EbvFragDepth: return spv::BuiltInFragDepth; + + case glslang::EbvNumWorkGroups: return spv::BuiltInNumWorkgroups; + case glslang::EbvWorkGroupSize: return spv::BuiltInWorkgroupSize; + case glslang::EbvWorkGroupId: return spv::BuiltInWorkgroupId; + case glslang::EbvLocalInvocationId: return spv::BuiltInLocalInvocationId; + case glslang::EbvLocalInvocationIndex: return spv::BuiltInLocalInvocationIndex; + case glslang::EbvGlobalInvocationId: return spv::BuiltInGlobalInvocationId; + +#ifndef GLSLANG_WEB // These *Distance capabilities logically belong here, but if the member is declared and // then never used, consumers of SPIR-V prefer the capability not be declared. // They are now generated when used, rather than here when declared. @@ -644,13 +733,20 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI return spv::BuiltInCullDistance; case glslang::EbvViewportIndex: - builder.addCapability(spv::CapabilityMultiViewport); + if (glslangIntermediate->getStage() == EShLangGeometry || + glslangIntermediate->getStage() == EShLangFragment) { + builder.addCapability(spv::CapabilityMultiViewport); + } if (glslangIntermediate->getStage() == EShLangVertex || glslangIntermediate->getStage() == EShLangTessControl || glslangIntermediate->getStage() == EShLangTessEvaluation) { - builder.addExtension(spv::E_SPV_EXT_shader_viewport_index_layer); - builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT); + if (builder.getSpvVersion() < spv::Spv_1_5) { + builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5); + builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT); + } + else + builder.addCapability(spv::CapabilityShaderViewportIndex); } return spv::BuiltInViewportIndex; @@ -666,39 +762,37 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI return spv::BuiltInSampleMask; case glslang::EbvLayer: -#ifdef NV_EXTENSIONS if (glslangIntermediate->getStage() == EShLangMeshNV) { return spv::BuiltInLayer; } -#endif - builder.addCapability(spv::CapabilityGeometry); + if (glslangIntermediate->getStage() == EShLangGeometry || + glslangIntermediate->getStage() == EShLangFragment) { + builder.addCapability(spv::CapabilityGeometry); + } if (glslangIntermediate->getStage() == EShLangVertex || glslangIntermediate->getStage() == EShLangTessControl || glslangIntermediate->getStage() == EShLangTessEvaluation) { - builder.addExtension(spv::E_SPV_EXT_shader_viewport_index_layer); - builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT); + if (builder.getSpvVersion() < spv::Spv_1_5) { + builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5); + builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT); + } else + builder.addCapability(spv::CapabilityShaderLayer); } return spv::BuiltInLayer; - case glslang::EbvPosition: return spv::BuiltInPosition; - case glslang::EbvVertexId: return spv::BuiltInVertexId; - case glslang::EbvInstanceId: return spv::BuiltInInstanceId; - case glslang::EbvVertexIndex: return spv::BuiltInVertexIndex; - case glslang::EbvInstanceIndex: return spv::BuiltInInstanceIndex; - case glslang::EbvBaseVertex: - addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters); + builder.addIncorporatedExtension(spv::E_SPV_KHR_shader_draw_parameters, spv::Spv_1_3); builder.addCapability(spv::CapabilityDrawParameters); return spv::BuiltInBaseVertex; case glslang::EbvBaseInstance: - addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters); + builder.addIncorporatedExtension(spv::E_SPV_KHR_shader_draw_parameters, spv::Spv_1_3); builder.addCapability(spv::CapabilityDrawParameters); return spv::BuiltInBaseInstance; case glslang::EbvDrawId: - addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters); + builder.addIncorporatedExtension(spv::E_SPV_KHR_shader_draw_parameters, spv::Spv_1_3); builder.addCapability(spv::CapabilityDrawParameters); return spv::BuiltInDrawIndex; @@ -712,22 +806,22 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addCapability(spv::CapabilityStencilExportEXT); return spv::BuiltInFragStencilRefEXT; + case glslang::EbvShadingRateKHR: + builder.addExtension(spv::E_SPV_KHR_fragment_shading_rate); + builder.addCapability(spv::CapabilityFragmentShadingRateKHR); + return spv::BuiltInShadingRateKHR; + + case glslang::EbvPrimitiveShadingRateKHR: + builder.addExtension(spv::E_SPV_KHR_fragment_shading_rate); + builder.addCapability(spv::CapabilityFragmentShadingRateKHR); + return spv::BuiltInPrimitiveShadingRateKHR; + case glslang::EbvInvocationId: return spv::BuiltInInvocationId; case glslang::EbvTessLevelInner: return spv::BuiltInTessLevelInner; case glslang::EbvTessLevelOuter: return spv::BuiltInTessLevelOuter; case glslang::EbvTessCoord: return spv::BuiltInTessCoord; case glslang::EbvPatchVertices: return spv::BuiltInPatchVertices; - case glslang::EbvFragCoord: return spv::BuiltInFragCoord; - case glslang::EbvPointCoord: return spv::BuiltInPointCoord; - case glslang::EbvFace: return spv::BuiltInFrontFacing; - case glslang::EbvFragDepth: return spv::BuiltInFragDepth; case glslang::EbvHelperInvocation: return spv::BuiltInHelperInvocation; - case glslang::EbvNumWorkGroups: return spv::BuiltInNumWorkgroups; - case glslang::EbvWorkGroupSize: return spv::BuiltInWorkgroupSize; - case glslang::EbvWorkGroupId: return spv::BuiltInWorkgroupId; - case glslang::EbvLocalInvocationId: return spv::BuiltInLocalInvocationId; - case glslang::EbvLocalInvocationIndex: return spv::BuiltInLocalInvocationIndex; - case glslang::EbvGlobalInvocationId: return spv::BuiltInGlobalInvocationId; case glslang::EbvSubGroupSize: builder.addExtension(spv::E_SPV_KHR_shader_ballot); @@ -742,27 +836,27 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvSubGroupEqMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupEqMaskKHR; + return spv::BuiltInSubgroupEqMask; case glslang::EbvSubGroupGeMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupGeMaskKHR; + return spv::BuiltInSubgroupGeMask; case glslang::EbvSubGroupGtMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupGtMaskKHR; + return spv::BuiltInSubgroupGtMask; case glslang::EbvSubGroupLeMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupLeMaskKHR; + return spv::BuiltInSubgroupLeMask; case glslang::EbvSubGroupLtMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupLtMaskKHR; + return spv::BuiltInSubgroupLtMask; case glslang::EbvNumSubgroups: builder.addCapability(spv::CapabilityGroupNonUniform); @@ -804,7 +898,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addCapability(spv::CapabilityGroupNonUniform); builder.addCapability(spv::CapabilityGroupNonUniformBallot); return spv::BuiltInSubgroupLtMask; -#ifdef AMD_EXTENSIONS + case glslang::EbvBaryCoordNoPersp: builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter); return spv::BuiltInBaryCoordNoPerspAMD; @@ -832,15 +926,14 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvBaryCoordPullModel: builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter); return spv::BuiltInBaryCoordPullModelAMD; -#endif case glslang::EbvDeviceIndex: - addPre13Extension(spv::E_SPV_KHR_device_group); + builder.addIncorporatedExtension(spv::E_SPV_KHR_device_group, spv::Spv_1_3); builder.addCapability(spv::CapabilityDeviceGroup); return spv::BuiltInDeviceIndex; case glslang::EbvViewIndex: - addPre13Extension(spv::E_SPV_KHR_multiview); + builder.addIncorporatedExtension(spv::E_SPV_KHR_multiview, spv::Spv_1_3); builder.addCapability(spv::CapabilityMultiView); return spv::BuiltInViewIndex; @@ -854,7 +947,6 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addCapability(spv::CapabilityFragmentDensityEXT); return spv::BuiltInFragInvocationCountEXT; -#ifdef NV_EXTENSIONS case glslang::EbvViewportMaskNV: if (!memberDeclaration) { builder.addExtension(spv::E_SPV_NV_viewport_array2); @@ -898,35 +990,55 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addCapability(spv::CapabilityShadingRateNV); return spv::BuiltInInvocationsPerPixelNV; - // raytracing - case glslang::EbvLaunchIdNV: - return spv::BuiltInLaunchIdNV; - case glslang::EbvLaunchSizeNV: - return spv::BuiltInLaunchSizeNV; - case glslang::EbvWorldRayOriginNV: - return spv::BuiltInWorldRayOriginNV; - case glslang::EbvWorldRayDirectionNV: - return spv::BuiltInWorldRayDirectionNV; - case glslang::EbvObjectRayOriginNV: - return spv::BuiltInObjectRayOriginNV; - case glslang::EbvObjectRayDirectionNV: - return spv::BuiltInObjectRayDirectionNV; - case glslang::EbvRayTminNV: - return spv::BuiltInRayTminNV; - case glslang::EbvRayTmaxNV: - return spv::BuiltInRayTmaxNV; - case glslang::EbvInstanceCustomIndexNV: - return spv::BuiltInInstanceCustomIndexNV; - case glslang::EbvHitTNV: - return spv::BuiltInHitTNV; - case glslang::EbvHitKindNV: - return spv::BuiltInHitKindNV; - case glslang::EbvObjectToWorldNV: - return spv::BuiltInObjectToWorldNV; - case glslang::EbvWorldToObjectNV: - return spv::BuiltInWorldToObjectNV; - case glslang::EbvIncomingRayFlagsNV: - return spv::BuiltInIncomingRayFlagsNV; + // ray tracing + case glslang::EbvLaunchId: + return spv::BuiltInLaunchIdKHR; + case glslang::EbvLaunchSize: + return spv::BuiltInLaunchSizeKHR; + case glslang::EbvWorldRayOrigin: + return spv::BuiltInWorldRayOriginKHR; + case glslang::EbvWorldRayDirection: + return spv::BuiltInWorldRayDirectionKHR; + case glslang::EbvObjectRayOrigin: + return spv::BuiltInObjectRayOriginKHR; + case glslang::EbvObjectRayDirection: + return spv::BuiltInObjectRayDirectionKHR; + case glslang::EbvRayTmin: + return spv::BuiltInRayTminKHR; + case glslang::EbvRayTmax: + return spv::BuiltInRayTmaxKHR; + case glslang::EbvInstanceCustomIndex: + return spv::BuiltInInstanceCustomIndexKHR; + case glslang::EbvHitT: + { + // this is a GLSL alias of RayTmax + // in SPV_NV_ray_tracing it has a dedicated builtin + // but in SPV_KHR_ray_tracing it gets mapped to RayTmax + auto& extensions = glslangIntermediate->getRequestedExtensions(); + if (extensions.find("GL_NV_ray_tracing") != extensions.end()) { + return spv::BuiltInHitTNV; + } else { + return spv::BuiltInRayTmaxKHR; + } + } + case glslang::EbvHitKind: + return spv::BuiltInHitKindKHR; + case glslang::EbvObjectToWorld: + case glslang::EbvObjectToWorld3x4: + return spv::BuiltInObjectToWorldKHR; + case glslang::EbvWorldToObject: + case glslang::EbvWorldToObject3x4: + return spv::BuiltInWorldToObjectKHR; + case glslang::EbvIncomingRayFlags: + return spv::BuiltInIncomingRayFlagsKHR; + case glslang::EbvGeometryIndex: + return spv::BuiltInRayGeometryIndexKHR; + case glslang::EbvCurrentRayTimeNV: + builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur); + builder.addCapability(spv::CapabilityRayTracingMotionBlurNV); + return spv::BuiltInCurrentRayTimeNV; + + // barycentrics case glslang::EbvBaryCoordNV: builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric); builder.addCapability(spv::CapabilityFragmentBarycentricNV); @@ -935,23 +1047,44 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric); builder.addCapability(spv::CapabilityFragmentBarycentricNV); return spv::BuiltInBaryCoordNoPerspNV; - case glslang::EbvTaskCountNV: + + // mesh shaders + case glslang::EbvTaskCountNV: return spv::BuiltInTaskCountNV; - case glslang::EbvPrimitiveCountNV: + case glslang::EbvPrimitiveCountNV: return spv::BuiltInPrimitiveCountNV; - case glslang::EbvPrimitiveIndicesNV: + case glslang::EbvPrimitiveIndicesNV: return spv::BuiltInPrimitiveIndicesNV; - case glslang::EbvClipDistancePerViewNV: + case glslang::EbvClipDistancePerViewNV: return spv::BuiltInClipDistancePerViewNV; - case glslang::EbvCullDistancePerViewNV: + case glslang::EbvCullDistancePerViewNV: return spv::BuiltInCullDistancePerViewNV; - case glslang::EbvLayerPerViewNV: + case glslang::EbvLayerPerViewNV: return spv::BuiltInLayerPerViewNV; - case glslang::EbvMeshViewCountNV: + case glslang::EbvMeshViewCountNV: return spv::BuiltInMeshViewCountNV; - case glslang::EbvMeshViewIndicesNV: + case glslang::EbvMeshViewIndicesNV: return spv::BuiltInMeshViewIndicesNV; -#endif + + // sm builtins + case glslang::EbvWarpsPerSM: + builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); + builder.addCapability(spv::CapabilityShaderSMBuiltinsNV); + return spv::BuiltInWarpsPerSMNV; + case glslang::EbvSMCount: + builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); + builder.addCapability(spv::CapabilityShaderSMBuiltinsNV); + return spv::BuiltInSMCountNV; + case glslang::EbvWarpID: + builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); + builder.addCapability(spv::CapabilityShaderSMBuiltinsNV); + return spv::BuiltInWarpIDNV; + case glslang::EbvSMID: + builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); + builder.addCapability(spv::CapabilityShaderSMBuiltinsNV); + return spv::BuiltInSMIDNV; +#endif + default: return spv::BuiltInMax; } @@ -962,8 +1095,12 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy { assert(type.getBasicType() == glslang::EbtSampler); +#ifdef GLSLANG_WEB + return spv::ImageFormatUnknown; +#endif + // Check for capabilities - switch (type.getQualifier().layoutFormat) { + switch (type.getQualifier().getFormat()) { case glslang::ElfRg32f: case glslang::ElfRg16f: case glslang::ElfR11fG11fB10f: @@ -995,12 +1132,16 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy builder.addCapability(spv::CapabilityStorageImageExtendedFormats); break; + case glslang::ElfR64ui: + case glslang::ElfR64i: + builder.addExtension(spv::E_SPV_EXT_shader_image_int64); + builder.addCapability(spv::CapabilityInt64ImageEXT); default: break; } // do the translation - switch (type.getQualifier().layoutFormat) { + switch (type.getQualifier().getFormat()) { case glslang::ElfNone: return spv::ImageFormatUnknown; case glslang::ElfRgba32f: return spv::ImageFormatRgba32f; case glslang::ElfRgba16f: return spv::ImageFormatRgba16f; @@ -1041,11 +1182,14 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy case glslang::ElfRg8ui: return spv::ImageFormatRg8ui; case glslang::ElfR16ui: return spv::ImageFormatR16ui; case glslang::ElfR8ui: return spv::ImageFormatR8ui; + case glslang::ElfR64ui: return spv::ImageFormatR64ui; + case glslang::ElfR64i: return spv::ImageFormatR64i; default: return spv::ImageFormatMax; } } -spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(const glslang::TIntermSelection& selectionNode) const +spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl( + const glslang::TIntermSelection& selectionNode) const { if (selectionNode.getFlatten()) return spv::SelectionControlFlattenMask; @@ -1054,7 +1198,8 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(cons return spv::SelectionControlMaskNone; } -spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode) const +spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode) + const { if (switchNode.getFlatten()) return spv::SelectionControlFlattenMask; @@ -1065,7 +1210,7 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const g // return a non-0 dependency if the dependency argument must be set spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang::TIntermLoop& loopNode, - unsigned int& dependencyLength) const + std::vector& operands) const { spv::LoopControlMask control = spv::LoopControlMaskNone; @@ -1077,7 +1222,29 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang: control = control | spv::LoopControlDependencyInfiniteMask; else if (loopNode.getLoopDependency() > 0) { control = control | spv::LoopControlDependencyLengthMask; - dependencyLength = loopNode.getLoopDependency(); + operands.push_back((unsigned int)loopNode.getLoopDependency()); + } + if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) { + if (loopNode.getMinIterations() > 0) { + control = control | spv::LoopControlMinIterationsMask; + operands.push_back(loopNode.getMinIterations()); + } + if (loopNode.getMaxIterations() < glslang::TIntermLoop::iterationsInfinite) { + control = control | spv::LoopControlMaxIterationsMask; + operands.push_back(loopNode.getMaxIterations()); + } + if (loopNode.getIterationMultiple() > 1) { + control = control | spv::LoopControlIterationMultipleMask; + operands.push_back(loopNode.getIterationMultiple()); + } + if (loopNode.getPeelCount() > 0) { + control = control | spv::LoopControlPeelCountMask; + operands.push_back(loopNode.getPeelCount()); + } + if (loopNode.getPartialCount() > 0) { + control = control | spv::LoopControlPartialCountMask; + operands.push_back(loopNode.getPartialCount()); + } } return control; @@ -1086,50 +1253,61 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang: // Translate glslang type to SPIR-V storage class. spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::TType& type) { + if (type.getBasicType() == glslang::EbtRayQuery) + return spv::StorageClassPrivate; +#ifndef GLSLANG_WEB + if (type.getQualifier().isSpirvByReference()) + return spv::StorageClassFunction; +#endif if (type.getQualifier().isPipeInput()) return spv::StorageClassInput; if (type.getQualifier().isPipeOutput()) return spv::StorageClassOutput; if (glslangIntermediate->getSource() != glslang::EShSourceHlsl || - type.getQualifier().storage == glslang::EvqUniform) { - if (type.getBasicType() == glslang::EbtAtomicUint) + type.getQualifier().storage == glslang::EvqUniform) { + if (type.isAtomic()) return spv::StorageClassAtomicCounter; if (type.containsOpaque()) return spv::StorageClassUniformConstant; } -#ifdef NV_EXTENSIONS if (type.getQualifier().isUniformOrBuffer() && - type.getQualifier().layoutShaderRecordNV) { - return spv::StorageClassShaderRecordBufferNV; + type.getQualifier().isShaderRecord()) { + return spv::StorageClassShaderRecordBufferKHR; } -#endif if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) { - addPre13Extension(spv::E_SPV_KHR_storage_buffer_storage_class); + builder.addIncorporatedExtension(spv::E_SPV_KHR_storage_buffer_storage_class, spv::Spv_1_3); return spv::StorageClassStorageBuffer; } if (type.getQualifier().isUniformOrBuffer()) { - if (type.getQualifier().layoutPushConstant) + if (type.getQualifier().isPushConstant()) return spv::StorageClassPushConstant; if (type.getBasicType() == glslang::EbtBlock) return spv::StorageClassUniform; return spv::StorageClassUniformConstant; } + if (type.getQualifier().storage == glslang::EvqShared && type.getBasicType() == glslang::EbtBlock) { + builder.addExtension(spv::E_SPV_KHR_workgroup_memory_explicit_layout); + builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR); + return spv::StorageClassWorkgroup; + } + switch (type.getQualifier().storage) { - case glslang::EvqShared: return spv::StorageClassWorkgroup; case glslang::EvqGlobal: return spv::StorageClassPrivate; case glslang::EvqConstReadOnly: return spv::StorageClassFunction; case glslang::EvqTemporary: return spv::StorageClassFunction; -#ifdef NV_EXTENSIONS - case glslang::EvqPayloadNV: return spv::StorageClassRayPayloadNV; - case glslang::EvqPayloadInNV: return spv::StorageClassIncomingRayPayloadNV; - case glslang::EvqHitAttrNV: return spv::StorageClassHitAttributeNV; - case glslang::EvqCallableDataNV: return spv::StorageClassCallableDataNV; - case glslang::EvqCallableDataInNV: return spv::StorageClassIncomingCallableDataNV; + case glslang::EvqShared: return spv::StorageClassWorkgroup; +#ifndef GLSLANG_WEB + case glslang::EvqPayload: return spv::StorageClassRayPayloadKHR; + case glslang::EvqPayloadIn: return spv::StorageClassIncomingRayPayloadKHR; + case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR; + case glslang::EvqCallableData: return spv::StorageClassCallableDataKHR; + case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR; + case glslang::EvqSpirvStorageClass: return static_cast(type.getQualifier().spirvStorageClass); #endif default: assert(0); @@ -1139,19 +1317,66 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T return spv::StorageClassFunction; } +// Translate glslang constants to SPIR-V literals +void TGlslangToSpvTraverser::TranslateLiterals(const glslang::TVector& constants, + std::vector& literals) const +{ + for (auto constant : constants) { + if (constant->getBasicType() == glslang::EbtFloat) { + float floatValue = static_cast(constant->getConstArray()[0].getDConst()); + unsigned literal = *reinterpret_cast(&floatValue); + literals.push_back(literal); + } else if (constant->getBasicType() == glslang::EbtInt) { + unsigned literal = constant->getConstArray()[0].getIConst(); + literals.push_back(literal); + } else if (constant->getBasicType() == glslang::EbtUint) { + unsigned literal = constant->getConstArray()[0].getUConst(); + literals.push_back(literal); + } else if (constant->getBasicType() == glslang::EbtBool) { + unsigned literal = constant->getConstArray()[0].getBConst(); + literals.push_back(literal); + } else if (constant->getBasicType() == glslang::EbtString) { + auto str = constant->getConstArray()[0].getSConst()->c_str(); + unsigned literal = 0; + char* literalPtr = reinterpret_cast(&literal); + unsigned charCount = 0; + char ch = 0; + do { + ch = *(str++); + *(literalPtr++) = ch; + ++charCount; + if (charCount == 4) { + literals.push_back(literal); + literalPtr = reinterpret_cast(&literal); + charCount = 0; + } + } while (ch != 0); + + // Partial literal is padded with 0 + if (charCount > 0) { + for (; charCount < 4; ++charCount) + *(literalPtr++) = 0; + literals.push_back(literal); + } + } else + assert(0); // Unexpected type + } +} + // Add capabilities pertaining to how an array is indexed. void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType) { +#ifndef GLSLANG_WEB if (indexType.getQualifier().isNonUniform()) { // deal with an asserted non-uniform index // SPV_EXT_descriptor_indexing already added in TranslateNonUniformDecoration if (baseType.getBasicType() == glslang::EbtSampler) { if (baseType.getQualifier().hasAttachment()) builder.addCapability(spv::CapabilityInputAttachmentArrayNonUniformIndexingEXT); - else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer) + else if (baseType.isImage() && baseType.getSampler().isBuffer()) builder.addCapability(spv::CapabilityStorageTexelBufferArrayNonUniformIndexingEXT); - else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer) + else if (baseType.isTexture() && baseType.getSampler().isBuffer()) builder.addCapability(spv::CapabilityUniformTexelBufferArrayNonUniformIndexingEXT); else if (baseType.isImage()) builder.addCapability(spv::CapabilityStorageImageArrayNonUniformIndexingEXT); @@ -1167,17 +1392,18 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp // assume a dynamically uniform index if (baseType.getBasicType() == glslang::EbtSampler) { if (baseType.getQualifier().hasAttachment()) { - builder.addExtension("SPV_EXT_descriptor_indexing"); + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT); - } else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer) { - builder.addExtension("SPV_EXT_descriptor_indexing"); + } else if (baseType.isImage() && baseType.getSampler().isBuffer()) { + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT); - } else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer) { - builder.addExtension("SPV_EXT_descriptor_indexing"); + } else if (baseType.isTexture() && baseType.getSampler().isBuffer()) { + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT); } } } +#endif } // Return whether or not the given type is something that should be tied to a @@ -1187,16 +1413,15 @@ bool IsDescriptorResource(const glslang::TType& type) // uniform and buffer blocks are included, unless it is a push_constant if (type.getBasicType() == glslang::EbtBlock) return type.getQualifier().isUniformOrBuffer() && -#ifdef NV_EXTENSIONS - ! type.getQualifier().layoutShaderRecordNV && -#endif - ! type.getQualifier().layoutPushConstant; + ! type.getQualifier().isShaderRecord() && + ! type.getQualifier().isPushConstant(); // non block... // basically samplerXXX/subpass/sampler/texture are all included // if they are the global-scope-class, not the function parameter // (or local, if they ever exist) class. - if (type.getBasicType() == glslang::EbtSampler) + if (type.getBasicType() == glslang::EbtSampler || + type.getBasicType() == glslang::EbtAccStruct) return type.getQualifier().isUniformOrBuffer(); // None of the above. @@ -1210,16 +1435,21 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa if (parent.invariant) child.invariant = true; - if (parent.nopersp) - child.nopersp = true; -#ifdef AMD_EXTENSIONS - if (parent.explicitInterp) - child.explicitInterp = true; -#endif if (parent.flat) child.flat = true; if (parent.centroid) child.centroid = true; +#ifndef GLSLANG_WEB + if (parent.nopersp) + child.nopersp = true; + if (parent.explicitInterp) + child.explicitInterp = true; + if (parent.perPrimitiveNV) + child.perPrimitiveNV = true; + if (parent.perViewNV) + child.perViewNV = true; + if (parent.perTaskNV) + child.perTaskNV = true; if (parent.patch) child.patch = true; if (parent.sample) @@ -1234,6 +1464,8 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa child.workgroupcoherent = true; if (parent.subgroupcoherent) child.subgroupcoherent = true; + if (parent.shadercallcoherent) + child.shadercallcoherent = true; if (parent.nonprivate) child.nonprivate = true; if (parent.volatil) @@ -1244,14 +1476,9 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa child.readonly = true; if (parent.writeonly) child.writeonly = true; -#ifdef NV_EXTENSIONS - if (parent.perPrimitiveNV) - child.perPrimitiveNV = true; - if (parent.perViewNV) - child.perViewNV = true; - if (parent.perTaskNV) - child.perTaskNV = true; #endif + if (parent.nonUniform) + child.nonUniform = true; } bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifier& qualifier) @@ -1271,15 +1498,18 @@ bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifie // Implement the TGlslangToSpvTraverser class. // -TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const glslang::TIntermediate* glslangIntermediate, - spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options) - : TIntermTraverser(true, false, true), - options(options), - shaderEntry(nullptr), currentFunction(nullptr), - sequenceDepth(0), logger(buildLogger), - builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger), - inEntryPoint(false), entryPointTerminated(false), linkageOnly(false), - glslangIntermediate(glslangIntermediate) +TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, + const glslang::TIntermediate* glslangIntermediate, + spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options) : + TIntermTraverser(true, false, true), + options(options), + shaderEntry(nullptr), currentFunction(nullptr), + sequenceDepth(0), logger(buildLogger), + builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger), + inEntryPoint(false), entryPointTerminated(false), linkageOnly(false), + glslangIntermediate(glslangIntermediate), + nanMinMaxClamp(glslangIntermediate->getNanMinMaxClamp()), + nonSemanticDebugPrintf(0) { spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage()); @@ -1320,16 +1550,20 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl if (glslangIntermediate->usingPhysicalStorageBuffer()) { addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT; - builder.addExtension(spv::E_SPV_EXT_physical_storage_buffer); + builder.addIncorporatedExtension(spv::E_SPV_KHR_physical_storage_buffer, spv::Spv_1_5); builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT); - }; + } if (glslangIntermediate->usingVulkanMemoryModel()) { memoryModel = spv::MemoryModelVulkanKHR; builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); - builder.addExtension(spv::E_SPV_KHR_vulkan_memory_model); + builder.addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5); } builder.setMemoryModel(addressingModel, memoryModel); + if (glslangIntermediate->usingVariablePointers()) { + builder.addCapability(spv::CapabilityVariablePointers); + } + shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str()); entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str()); @@ -1345,12 +1579,103 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb); } + if (glslangIntermediate->getLayoutPrimitiveCulling()) { + builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR); + } + +#ifndef GLSLANG_WEB + if (glslangIntermediate->getSubgroupUniformControlFlow()) { + builder.addExtension(spv::E_SPV_KHR_subgroup_uniform_control_flow); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeSubgroupUniformControlFlowKHR); + } +#endif + unsigned int mode; switch (glslangIntermediate->getStage()) { case EShLangVertex: builder.addCapability(spv::CapabilityShader); break; + case EShLangFragment: + builder.addCapability(spv::CapabilityShader); + if (glslangIntermediate->getPixelCenterInteger()) + builder.addExecutionMode(shaderEntry, spv::ExecutionModePixelCenterInteger); + + if (glslangIntermediate->getOriginUpperLeft()) + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginUpperLeft); + else + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginLowerLeft); + + if (glslangIntermediate->getEarlyFragmentTests()) + builder.addExecutionMode(shaderEntry, spv::ExecutionModeEarlyFragmentTests); + + if (glslangIntermediate->getPostDepthCoverage()) { + builder.addCapability(spv::CapabilitySampleMaskPostDepthCoverage); + builder.addExecutionMode(shaderEntry, spv::ExecutionModePostDepthCoverage); + builder.addExtension(spv::E_SPV_KHR_post_depth_coverage); + } + + if (glslangIntermediate->isDepthReplacing()) + builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing); + +#ifndef GLSLANG_WEB + + switch(glslangIntermediate->getDepth()) { + case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break; + case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break; + case glslang::EldUnchanged: mode = spv::ExecutionModeDepthUnchanged; break; + default: mode = spv::ExecutionModeMax; break; + } + if (mode != spv::ExecutionModeMax) + builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); + switch (glslangIntermediate->getInterlockOrdering()) { + case glslang::EioPixelInterlockOrdered: mode = spv::ExecutionModePixelInterlockOrderedEXT; + break; + case glslang::EioPixelInterlockUnordered: mode = spv::ExecutionModePixelInterlockUnorderedEXT; + break; + case glslang::EioSampleInterlockOrdered: mode = spv::ExecutionModeSampleInterlockOrderedEXT; + break; + case glslang::EioSampleInterlockUnordered: mode = spv::ExecutionModeSampleInterlockUnorderedEXT; + break; + case glslang::EioShadingRateInterlockOrdered: mode = spv::ExecutionModeShadingRateInterlockOrderedEXT; + break; + case glslang::EioShadingRateInterlockUnordered: mode = spv::ExecutionModeShadingRateInterlockUnorderedEXT; + break; + default: mode = spv::ExecutionModeMax; + break; + } + if (mode != spv::ExecutionModeMax) { + builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); + if (mode == spv::ExecutionModeShadingRateInterlockOrderedEXT || + mode == spv::ExecutionModeShadingRateInterlockUnorderedEXT) { + builder.addCapability(spv::CapabilityFragmentShaderShadingRateInterlockEXT); + } else if (mode == spv::ExecutionModePixelInterlockOrderedEXT || + mode == spv::ExecutionModePixelInterlockUnorderedEXT) { + builder.addCapability(spv::CapabilityFragmentShaderPixelInterlockEXT); + } else { + builder.addCapability(spv::CapabilityFragmentShaderSampleInterlockEXT); + } + builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock); + } +#endif + break; + + case EShLangCompute: + builder.addCapability(spv::CapabilityShader); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0), + glslangIntermediate->getLocalSize(1), + glslangIntermediate->getLocalSize(2)); + if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) { + builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupQuadsNV); + builder.addExtension(spv::E_SPV_NV_compute_shader_derivatives); + } else if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupLinear) { + builder.addCapability(spv::CapabilityComputeDerivativeGroupLinearNV); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupLinearNV); + builder.addExtension(spv::E_SPV_NV_compute_shader_derivatives); + } + break; +#ifndef GLSLANG_WEB case EShLangTessEvaluation: case EShLangTessControl: builder.addCapability(spv::CapabilityTessellation); @@ -1358,7 +1683,8 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl glslang::TLayoutGeometry primitive; if (glslangIntermediate->getStage() == EShLangTessControl) { - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, + glslangIntermediate->getVertices()); primitive = glslangIntermediate->getOutputPrimitive(); } else { primitive = glslangIntermediate->getInputPrimitive(); @@ -1420,65 +1746,24 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); break; - case EShLangFragment: - builder.addCapability(spv::CapabilityShader); - if (glslangIntermediate->getPixelCenterInteger()) - builder.addExecutionMode(shaderEntry, spv::ExecutionModePixelCenterInteger); - - if (glslangIntermediate->getOriginUpperLeft()) - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginUpperLeft); - else - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginLowerLeft); - - if (glslangIntermediate->getEarlyFragmentTests()) - builder.addExecutionMode(shaderEntry, spv::ExecutionModeEarlyFragmentTests); - - if (glslangIntermediate->getPostDepthCoverage()) { - builder.addCapability(spv::CapabilitySampleMaskPostDepthCoverage); - builder.addExecutionMode(shaderEntry, spv::ExecutionModePostDepthCoverage); - builder.addExtension(spv::E_SPV_KHR_post_depth_coverage); + case EShLangRayGen: + case EShLangIntersect: + case EShLangAnyHit: + case EShLangClosestHit: + case EShLangMiss: + case EShLangCallable: + { + auto& extensions = glslangIntermediate->getRequestedExtensions(); + if (extensions.find("GL_NV_ray_tracing") == extensions.end()) { + builder.addCapability(spv::CapabilityRayTracingKHR); + builder.addExtension("SPV_KHR_ray_tracing"); } - - switch(glslangIntermediate->getDepth()) { - case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break; - case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break; - default: mode = spv::ExecutionModeMax; break; + else { + builder.addCapability(spv::CapabilityRayTracingNV); + builder.addExtension("SPV_NV_ray_tracing"); } - if (mode != spv::ExecutionModeMax) - builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); - - if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing()) - builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing); - break; - - case EShLangCompute: - builder.addCapability(spv::CapabilityShader); - builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0), - glslangIntermediate->getLocalSize(1), - glslangIntermediate->getLocalSize(2)); -#ifdef NV_EXTENSIONS - if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) { - builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV); - builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupQuadsNV); - builder.addExtension(spv::E_SPV_NV_compute_shader_derivatives); - } else if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupLinear) { - builder.addCapability(spv::CapabilityComputeDerivativeGroupLinearNV); - builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupLinearNV); - builder.addExtension(spv::E_SPV_NV_compute_shader_derivatives); - } -#endif - break; - -#ifdef NV_EXTENSIONS - case EShLangRayGenNV: - case EShLangIntersectNV: - case EShLangAnyHitNV: - case EShLangClosestHitNV: - case EShLangMissNV: - case EShLangCallableNV: - builder.addCapability(spv::CapabilityRayTracingNV); - builder.addExtension("SPV_NV_ray_tracing"); break; + } case EShLangTaskNV: case EShLangMeshNV: builder.addCapability(spv::CapabilityMeshShadingNV); @@ -1487,8 +1772,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl glslangIntermediate->getLocalSize(1), glslangIntermediate->getLocalSize(2)); if (glslangIntermediate->getStage() == EShLangMeshNV) { - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, glslangIntermediate->getPrimitives()); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, + glslangIntermediate->getVertices()); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, + glslangIntermediate->getPrimitives()); switch (glslangIntermediate->getOutputPrimitive()) { case glslang::ElgPoints: mode = spv::ExecutionModeOutputPoints; break; @@ -1505,6 +1792,53 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl default: break; } + +#ifndef GLSLANG_WEB + // + // Add SPIR-V requirements (GL_EXT_spirv_intrinsics) + // + if (glslangIntermediate->hasSpirvRequirement()) { + const glslang::TSpirvRequirement& spirvRequirement = glslangIntermediate->getSpirvRequirement(); + + // Add SPIR-V extension requirement + for (auto& extension : spirvRequirement.extensions) + builder.addExtension(extension.c_str()); + + // Add SPIR-V capability requirement + for (auto capability : spirvRequirement.capabilities) + builder.addCapability(static_cast(capability)); + } + + // + // Add SPIR-V execution mode qualifiers (GL_EXT_spirv_intrinsics) + // + if (glslangIntermediate->hasSpirvExecutionMode()) { + const glslang::TSpirvExecutionMode spirvExecutionMode = glslangIntermediate->getSpirvExecutionMode(); + + // Add spirv_execution_mode + for (auto& mode : spirvExecutionMode.modes) { + if (!mode.second.empty()) { + std::vector literals; + TranslateLiterals(mode.second, literals); + builder.addExecutionMode(shaderEntry, static_cast(mode.first), literals); + } else + builder.addExecutionMode(shaderEntry, static_cast(mode.first)); + } + + // Add spirv_execution_mode_id + for (auto& modeId : spirvExecutionMode.modeIds) { + std::vector operandIds; + assert(!modeId.second.empty()); + for (auto extraOperand : modeId.second) { + int nextConst = 0; + spv::Id operandId = createSpvConstantFromConstUnionArray( + extraOperand->getType(), extraOperand->getConstArray(), nextConst, false); + operandIds.push_back(operandId); + } + builder.addExecutionModeId(shaderEntry, static_cast(modeId.first), operandIds); + } + } +#endif } // Finish creating SPV, after the traversal is complete. @@ -1520,8 +1854,10 @@ void TGlslangToSpvTraverser::finishSpv() for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it) entryPoint->addIdOperand(*it); - // Add capabilities, extensions, remove unneeded decorations, etc., + // Add capabilities, extensions, remove unneeded decorations, etc., // based on the resulting SPIR-V. + // Note: WebGPU code generation must have the opportunity to aggressively + // prune unreachable merge blocks and continue targets. builder.postProcess(); } @@ -1549,20 +1885,47 @@ void TGlslangToSpvTraverser::dumpSpv(std::vector& out) void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) { SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); + if (symbol->getType().isStruct()) + glslangTypeToIdMap[symbol->getType().getStruct()] = symbol->getId(); + if (symbol->getType().getQualifier().isSpecConstant()) spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); +#ifdef ENABLE_HLSL + // Skip symbol handling if it is string-typed + if (symbol->getBasicType() == glslang::EbtString) + return; +#endif + // getSymbolId() will set up all the IO decorations on the first call. // Formal function parameters were mapped during makeFunctions(). spv::Id id = getSymbolId(symbol); - // Include all "static use" and "linkage only" interface variables on the OpEntryPoint instruction if (builder.isPointer(id)) { - spv::StorageClass sc = builder.getStorageClass(id); - if (sc == spv::StorageClassInput || sc == spv::StorageClassOutput) { - if (!symbol->getType().isStruct() || symbol->getType().getStruct()->size() > 0) - iOSet.insert(id); + if (!symbol->getType().getQualifier().isParamInput() && + !symbol->getType().getQualifier().isParamOutput()) { + // Include all "static use" and "linkage only" interface variables on the OpEntryPoint instruction + // Consider adding to the OpEntryPoint interface list. + // Only looking at structures if they have at least one member. + if (!symbol->getType().isStruct() || symbol->getType().getStruct()->size() > 0) { + spv::StorageClass sc = builder.getStorageClass(id); + // Before SPIR-V 1.4, we only want to include Input and Output. + // Starting with SPIR-V 1.4, we want all globals. + if ((glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4 && builder.isGlobalStorage(id)) || + (sc == spv::StorageClassInput || sc == spv::StorageClassOutput)) { + iOSet.insert(id); + } + } } + + // If the SPIR-V type is required to be different than the AST type + // (for ex SubgroupMasks or 3x4 ObjectToWorld/WorldToObject matrices), + // translate now from the SPIR-V type to the AST type, for the consuming + // operation. + // Note this turns it from an l-value to an r-value. + // Currently, all symbols needing this are inputs; avoid the map lookup when non-input. + if (symbol->getType().getQualifier().storage == glslang::EvqVaryingIn) + id = translateForcedType(id); } // Only process non-linkage-only nodes for generating actual static uses @@ -1580,13 +1943,16 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) // See comments in handleUserFunctionCall(). // B) Specialization constants (normal constants don't even come in as a variable), // These are also pure R-values. + // C) R-Values from type translation, see above call to translateForcedType() glslang::TQualifier qualifier = symbol->getQualifier(); - if (qualifier.isSpecConstant() || rValueParameters.find(symbol->getId()) != rValueParameters.end()) + if (qualifier.isSpecConstant() || rValueParameters.find(symbol->getId()) != rValueParameters.end() || + !builder.isPointerType(builder.getTypeId(id))) builder.setAccessChainRValue(id); else builder.setAccessChainLValue(id); } +#ifdef ENABLE_HLSL // Process linkage-only nodes for any special additional interface work. if (linkageOnly) { if (glslangIntermediate->getHlslFunctionality1()) { @@ -1618,11 +1984,18 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) } } } +#endif } bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node) { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); + if (node->getLeft()->getAsSymbolNode() != nullptr && node->getLeft()->getType().isStruct()) { + glslangTypeToIdMap[node->getLeft()->getType().getStruct()] = node->getLeft()->getAsSymbolNode()->getId(); + } + if (node->getRight()->getAsSymbolNode() != nullptr && node->getRight()->getType().isStruct()) { + glslangTypeToIdMap[node->getRight()->getType().getStruct()] = node->getRight()->getAsSymbolNode()->getId(); + } SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); if (node->getType().getQualifier().isSpecConstant()) @@ -1666,9 +2039,11 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T spv::Id leftRValue = accessChainLoad(node->getLeft()->getType()); // do the operation + spv::Builder::AccessChain::CoherentFlags coherentFlags = TranslateCoherent(node->getLeft()->getType()); + coherentFlags |= TranslateCoherent(node->getRight()->getType()); OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()), TranslateNoContractionDecoration(node->getType().getQualifier()), - TranslateNonUniformDecoration(node->getType().getQualifier()) }; + TranslateNonUniformDecoration(coherentFlags) }; rValue = createBinaryOperation(node->getOp(), decorations, convertGlslangToSpvType(node->getType()), leftRValue, rValue, node->getType().getBasicType()); @@ -1689,6 +2064,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T case glslang::EOpIndexDirect: case glslang::EOpIndexDirectStruct: { + // Structure, array, matrix, or vector indirection with statically known index. // Get the left part of the access chain. node->getLeft()->traverse(this); @@ -1698,20 +2074,24 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector() && node->getOp() == glslang::EOpIndexDirect) { + // Swizzle is uniform so propagate uniform into access chain + spv::Builder::AccessChain::CoherentFlags coherentFlags = TranslateCoherent(node->getLeft()->getType()); + coherentFlags.nonUniform = 0; // This is essentially a hard-coded vector swizzle of size 1, // so short circuit the access-chain stuff with a swizzle. std::vector swizzle; swizzle.push_back(glslangIndex); int dummySize; builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()), - TranslateCoherent(node->getLeft()->getType()), - glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + coherentFlags, + glslangIntermediate->getBaseAlignmentScalar( + node->getLeft()->getType(), dummySize)); } else { // Load through a block reference is performed with a dot operator that // is mapped to EOpIndexDirectStruct. When we get to the actual reference, // do a load and reset the access chain. - if (node->getLeft()->getBasicType() == glslang::EbtReference && + if (node->getLeft()->isReference() && !node->getLeft()->getType().isArray() && node->getOp() == glslang::EOpIndexDirectStruct) { @@ -1726,13 +2106,23 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T { // This may be, e.g., an anonymous block-member selection, which generally need // index remapping due to hidden members in anonymous blocks. - std::vector& remapper = memberRemapper[node->getLeft()->getType().getStruct()]; - assert(remapper.size() > 0); - spvIndex = remapper[glslangIndex]; + long long glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()]; + if (memberRemapper.find(glslangId) != memberRemapper.end()) { + std::vector& remapper = memberRemapper[glslangId]; + assert(remapper.size() > 0); + spvIndex = remapper[glslangIndex]; + } } + // Struct reference propagates uniform lvalue + spv::Builder::AccessChain::CoherentFlags coherentFlags = + TranslateCoherent(node->getLeft()->getType()); + coherentFlags.nonUniform = 0; + // normal case for indexing array or structure or block - builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()), getBufferReferenceAlignment(node->getLeft()->getType())); + builder.accessChainPush(builder.makeIntConstant(spvIndex), + coherentFlags, + node->getLeft()->getType().getBufferReferenceAlignment()); // Add capabilities here for accessing PointSize and clip/cull distance. // We have deferred generation of associated capabilities until now. @@ -1743,8 +2133,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T return false; case glslang::EOpIndexIndirect: { - // Structure or array or vector indirection. - // Will use native SPIR-V access-chain for struct and array indirection; + // Array, matrix, or vector indirection with variable index. + // Will use native SPIR-V access-chain for and array indirection; // matrices are arrays of vectors, so will also work for a matrix. // Will use the access chain's 'component' for variable index into a vector. @@ -1765,13 +2155,20 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // restore the saved access chain builder.setAccessChain(partial); + // Only if index is nonUniform should we propagate nonUniform into access chain + spv::Builder::AccessChain::CoherentFlags index_flags = TranslateCoherent(node->getRight()->getType()); + spv::Builder::AccessChain::CoherentFlags coherent_flags = TranslateCoherent(node->getLeft()->getType()); + coherent_flags.nonUniform = index_flags.nonUniform; + if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) { int dummySize; - builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()), - TranslateCoherent(node->getLeft()->getType()), - glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + builder.accessChainPushComponent( + index, convertGlslangToSpvType(node->getLeft()->getType()), coherent_flags, + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), + dummySize)); } else - builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), getBufferReferenceAlignment(node->getLeft()->getType())); + builder.accessChainPush(index, coherent_flags, + node->getLeft()->getType().getBufferReferenceAlignment()); } return false; case glslang::EOpVectorSwizzle: @@ -1782,7 +2179,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T int dummySize; builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()), TranslateCoherent(node->getLeft()->getType()), - glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), + dummySize)); } return false; case glslang::EOpMatrixSwizzle: @@ -1798,7 +2196,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T if (isTrivial(node->getRight()->getAsTyped())) break; // handle below as a normal binary operation // otherwise, we need to do dynamic short circuiting on the right operand - spv::Id result = createShortCircuit(node->getOp(), *node->getLeft()->getAsTyped(), *node->getRight()->getAsTyped()); + spv::Id result = createShortCircuit(node->getOp(), *node->getLeft()->getAsTyped(), + *node->getRight()->getAsTyped()); builder.clearAccessChain(); builder.setAccessChainRValue(result); } @@ -1837,6 +2236,132 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T } } +spv::Id TGlslangToSpvTraverser::convertLoadedBoolInUniformToUint(const glslang::TType& type, + spv::Id nominalTypeId, + spv::Id loadedId) +{ + if (builder.isScalarType(nominalTypeId)) { + // Conversion for bool + spv::Id boolType = builder.makeBoolType(); + if (nominalTypeId != boolType) + return builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0)); + } else if (builder.isVectorType(nominalTypeId)) { + // Conversion for bvec + int vecSize = builder.getNumTypeComponents(nominalTypeId); + spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize); + if (nominalTypeId != bvecType) + loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId, + makeSmearedConstant(builder.makeUintConstant(0), vecSize)); + } else if (builder.isArrayType(nominalTypeId)) { + // Conversion for bool array + spv::Id boolArrayTypeId = convertGlslangToSpvType(type); + if (nominalTypeId != boolArrayTypeId) + { + // Use OpCopyLogical from SPIR-V 1.4 if available. + if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) + return builder.createUnaryOp(spv::OpCopyLogical, boolArrayTypeId, loadedId); + + glslang::TType glslangElementType(type, 0); + spv::Id elementNominalTypeId = builder.getContainedTypeId(nominalTypeId); + std::vector constituents; + for (int index = 0; index < type.getOuterArraySize(); ++index) { + // get the element + spv::Id elementValue = builder.createCompositeExtract(loadedId, elementNominalTypeId, index); + + // recursively convert it + spv::Id elementConvertedValue = convertLoadedBoolInUniformToUint(glslangElementType, elementNominalTypeId, elementValue); + constituents.push_back(elementConvertedValue); + } + return builder.createCompositeConstruct(boolArrayTypeId, constituents); + } + } + + return loadedId; +} + +// Figure out what, if any, type changes are needed when accessing a specific built-in. +// Returns . +// Also see comment for 'forceType', regarding tracking SPIR-V-required types. +std::pair TGlslangToSpvTraverser::getForcedType(glslang::TBuiltInVariable glslangBuiltIn, + const glslang::TType& glslangType) +{ + switch(glslangBuiltIn) + { + case glslang::EbvSubGroupEqMask: + case glslang::EbvSubGroupGeMask: + case glslang::EbvSubGroupGtMask: + case glslang::EbvSubGroupLeMask: + case glslang::EbvSubGroupLtMask: { + // these require changing a 64-bit scaler -> a vector of 32-bit components + if (glslangType.isVector()) + break; + spv::Id ivec4_type = builder.makeVectorType(builder.makeUintType(32), 4); + spv::Id uint64_type = builder.makeUintType(64); + std::pair ret(ivec4_type, uint64_type); + return ret; + } + // There are no SPIR-V builtins defined for these and map onto original non-transposed + // builtins. During visitBinary we insert a transpose + case glslang::EbvWorldToObject3x4: + case glslang::EbvObjectToWorld3x4: { + spv::Id mat43 = builder.makeMatrixType(builder.makeFloatType(32), 4, 3); + spv::Id mat34 = builder.makeMatrixType(builder.makeFloatType(32), 3, 4); + std::pair ret(mat43, mat34); + return ret; + } + default: + break; + } + + std::pair ret(spv::NoType, spv::NoType); + return ret; +} + +// For an object previously identified (see getForcedType() and forceType) +// as needing type translations, do the translation needed for a load, turning +// an L-value into in R-value. +spv::Id TGlslangToSpvTraverser::translateForcedType(spv::Id object) +{ + const auto forceIt = forceType.find(object); + if (forceIt == forceType.end()) + return object; + + spv::Id desiredTypeId = forceIt->second; + spv::Id objectTypeId = builder.getTypeId(object); + assert(builder.isPointerType(objectTypeId)); + objectTypeId = builder.getContainedTypeId(objectTypeId); + if (builder.isVectorType(objectTypeId) && + builder.getScalarTypeWidth(builder.getContainedTypeId(objectTypeId)) == 32) { + if (builder.getScalarTypeWidth(desiredTypeId) == 64) { + // handle 32-bit v.xy* -> 64-bit + builder.clearAccessChain(); + builder.setAccessChainLValue(object); + object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, spv::DecorationMax, objectTypeId); + std::vector components; + components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 0)); + components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 1)); + + spv::Id vecType = builder.makeVectorType(builder.getContainedTypeId(objectTypeId), 2); + return builder.createUnaryOp(spv::OpBitcast, desiredTypeId, + builder.createCompositeConstruct(vecType, components)); + } else { + logger->missingFunctionality("forcing 32-bit vector type to non 64-bit scalar"); + } + } else if (builder.isMatrixType(objectTypeId)) { + // There are no SPIR-V builtins defined for 3x4 variants of ObjectToWorld/WorldToObject + // and we insert a transpose after loading the original non-transposed builtins + builder.clearAccessChain(); + builder.setAccessChainLValue(object); + object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, spv::DecorationMax, objectTypeId); + return builder.createUnaryOp(spv::OpTranspose, desiredTypeId, object); + + } else { + logger->missingFunctionality("forcing non 32-bit vector type"); + } + + return object; +} + bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node) { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); @@ -1870,16 +2395,32 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // So, this has to be block.lastMember.length(). // SPV wants "block" and member number as the operands, go get them. - glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft(); - block->traverse(this); - unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst(); - spv::Id length = builder.createArrayLength(builder.accessChainGetLValue(), member); + spv::Id length; + if (node->getOperand()->getType().isCoopMat()) { + spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); + + spv::Id typeId = convertGlslangToSpvType(node->getOperand()->getType()); + assert(builder.isCooperativeMatrixType(typeId)); + + length = builder.createCooperativeMatrixLength(typeId); + } else { + glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft(); + block->traverse(this); + unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion() + ->getConstArray()[0].getUConst(); + length = builder.createArrayLength(builder.accessChainGetLValue(), member); + } // GLSL semantics say the result of .length() is an int, while SPIR-V says // signedness must be 0. So, convert from SPIR-V unsigned back to GLSL's // AST expectation of a signed result. - if (glslangIntermediate->getSource() == glslang::EShSourceGlsl) - length = builder.createUnaryOp(spv::OpBitcast, builder.makeIntType(32), length); + if (glslangIntermediate->getSource() == glslang::EShSourceGlsl) { + if (builder.isInSpecConstCodeGenMode()) { + length = builder.createBinOp(spv::OpIAdd, builder.makeIntType(32), length, builder.makeIntConstant(0)); + } else { + length = builder.createUnaryOp(spv::OpBitcast, builder.makeIntType(32), length); + } + } builder.clearAccessChain(); builder.setAccessChainRValue(length); @@ -1892,25 +2433,50 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // Does it need a swizzle inversion? If so, evaluation is inverted; // operate first on the swizzle base, then apply the swizzle. spv::Id invertedType = spv::NoType; - auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? invertedType : convertGlslangToSpvType(node->getType()); }; + auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? + invertedType : convertGlslangToSpvType(node->getType()); }; if (node->getOp() == glslang::EOpInterpolateAtCentroid) invertedType = getInvertedSwizzleType(*node->getOperand()); builder.clearAccessChain(); + TIntermNode *operandNode; if (invertedType != spv::NoType) - node->getOperand()->getAsBinaryNode()->getLeft()->traverse(this); + operandNode = node->getOperand()->getAsBinaryNode()->getLeft(); else - node->getOperand()->traverse(this); + operandNode = node->getOperand(); + + operandNode->traverse(this); spv::Id operand = spv::NoResult; + spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; + +#ifndef GLSLANG_WEB if (node->getOp() == glslang::EOpAtomicCounterIncrement || node->getOp() == glslang::EOpAtomicCounterDecrement || node->getOp() == glslang::EOpAtomicCounter || - node->getOp() == glslang::EOpInterpolateAtCentroid) + (node->getOp() == glslang::EOpInterpolateAtCentroid && + glslangIntermediate->getSource() != glslang::EShSourceHlsl) || + node->getOp() == glslang::EOpRayQueryProceed || + node->getOp() == glslang::EOpRayQueryGetRayTMin || + node->getOp() == glslang::EOpRayQueryGetRayFlags || + node->getOp() == glslang::EOpRayQueryGetWorldRayOrigin || + node->getOp() == glslang::EOpRayQueryGetWorldRayDirection || + node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque || + node->getOp() == glslang::EOpRayQueryTerminate || + node->getOp() == glslang::EOpRayQueryConfirmIntersection || + (node->getOp() == glslang::EOpSpirvInst && operandNode->getAsTyped()->getQualifier().isSpirvByReference())) { operand = builder.accessChainGetLValue(); // Special case l-value operands - else + lvalueCoherentFlags = builder.getAccessChain().coherentFlags; + lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType()); + } else if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) { + // Will be translated to a literal value, make a placeholder here + operand = spv::NoResult; + } else +#endif + { operand = accessChainLoad(node->getOperand()->getType()); + } OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()), TranslateNoContractionDecoration(node->getType().getQualifier()), @@ -1918,16 +2484,50 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // it could be a conversion if (! result) - result = createConversion(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType()); + result = createConversion(node->getOp(), decorations, resultType(), operand, + node->getOperand()->getBasicType()); // if not, then possibly an operation if (! result) - result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType()); + result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, + node->getOperand()->getBasicType(), lvalueCoherentFlags); + +#ifndef GLSLANG_WEB + // it could be attached to a SPIR-V intruction + if (!result) { + if (node->getOp() == glslang::EOpSpirvInst) { + const auto& spirvInst = node->getSpirvInstruction(); + if (spirvInst.set == "") { + spv::IdImmediate idImmOp = {true, operand}; + if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) { + // Translate the constant to a literal value + std::vector literals; + glslang::TVector constants; + constants.push_back(operandNode->getAsConstantUnion()); + TranslateLiterals(constants, literals); + idImmOp = {false, literals[0]}; + } + + if (node->getBasicType() == glslang::EbtVoid) + builder.createNoResultOp(static_cast(spirvInst.id), {idImmOp}); + else + result = builder.createOp(static_cast(spirvInst.id), resultType(), {idImmOp}); + } else { + result = builder.createBuiltinCall( + resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()), + spirvInst.id, {operand}); + } + + if (node->getBasicType() == glslang::EbtVoid) + return false; // done with this node + } + } +#endif if (result) { if (invertedType) { result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); } builder.clearAccessChain(); @@ -1947,6 +2547,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI spv::Id one = 0; if (node->getBasicType() == glslang::EbtFloat) one = builder.makeFloatConstant(1.0F); +#ifndef GLSLANG_WEB else if (node->getBasicType() == glslang::EbtDouble) one = builder.makeDoubleConstant(1.0); else if (node->getBasicType() == glslang::EbtFloat16) @@ -1957,6 +2558,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI one = builder.makeInt16Constant(1); else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64) one = builder.makeInt64Constant(1); +#endif else one = builder.makeIntConstant(1); glslang::TOperator op; @@ -1973,7 +2575,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // The result of operation is always stored, but conditionally the // consumed result. The consumed result is always an r-value. - builder.accessChainStore(result); + builder.accessChainStore(result, + TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags)); builder.clearAccessChain(); if (node->getOp() == glslang::EOpPreIncrement || node->getOp() == glslang::EOpPreDecrement) @@ -1984,12 +2587,20 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI return false; +#ifndef GLSLANG_WEB case glslang::EOpEmitStreamVertex: builder.createNoResultOp(spv::OpEmitStreamVertex, operand); return false; case glslang::EOpEndStreamPrimitive: builder.createNoResultOp(spv::OpEndStreamPrimitive, operand); return false; + case glslang::EOpRayQueryTerminate: + builder.createNoResultOp(spv::OpRayQueryTerminateKHR, operand); + return false; + case glslang::EOpRayQueryConfirmIntersection: + builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR, operand); + return false; +#endif default: logger->missingFunctionality("unknown glslang unary"); @@ -1997,6 +2608,40 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI } } +// Construct a composite object, recursively copying members if their types don't match +spv::Id TGlslangToSpvTraverser::createCompositeConstruct(spv::Id resultTypeId, std::vector constituents) +{ + for (int c = 0; c < (int)constituents.size(); ++c) { + spv::Id& constituent = constituents[c]; + spv::Id lType = builder.getContainedTypeId(resultTypeId, c); + spv::Id rType = builder.getTypeId(constituent); + if (lType != rType) { + if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) { + constituent = builder.createUnaryOp(spv::OpCopyLogical, lType, constituent); + } else if (builder.isStructType(rType)) { + std::vector rTypeConstituents; + int numrTypeConstituents = builder.getNumTypeConstituents(rType); + for (int i = 0; i < numrTypeConstituents; ++i) { + rTypeConstituents.push_back(builder.createCompositeExtract(constituent, + builder.getContainedTypeId(rType, i), i)); + } + constituents[c] = createCompositeConstruct(lType, rTypeConstituents); + } else { + assert(builder.isArrayType(rType)); + std::vector rTypeConstituents; + int numrTypeConstituents = builder.getNumTypeConstituents(rType); + + spv::Id elementRType = builder.getContainedTypeId(rType); + for (int i = 0; i < numrTypeConstituents; ++i) { + rTypeConstituents.push_back(builder.createCompositeExtract(constituent, elementRType, i)); + } + constituents[c] = createCompositeConstruct(lType, rTypeConstituents); + } + } + } + return builder.createCompositeConstruct(resultTypeId, constituents); +} + bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TIntermAggregate* node) { SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); @@ -2004,8 +2649,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); spv::Id result = spv::NoResult; - spv::Id invertedType = spv::NoType; // to use to override the natural type of the node - auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? invertedType : convertGlslangToSpvType(node->getType()); }; + spv::Id invertedType = spv::NoType; // to use to override the natural type of the node + std::vector complexLvalues; // for holding swizzling l-values too complex for + // SPIR-V, for an out parameter + std::vector temporaryLvalues; // temporaries to pass, as proxies for complexLValues + + auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? + invertedType : + convertGlslangToSpvType(node->getType()); }; // try texturing result = createImageTextureFunctionCall(node); @@ -2014,14 +2665,15 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.setAccessChainRValue(result); return false; - } else if (node->getOp() == glslang::EOpImageStore || -#ifdef AMD_EXTENSIONS + } +#ifndef GLSLANG_WEB + else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod || -#endif node->getOp() == glslang::EOpImageAtomicStore) { // "imageStore" is a special case, which has no result return false; } +#endif glslang::TOperator binOp = glslang::EOpNull; bool reduceComparison = true; @@ -2029,6 +2681,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt bool noReturnValue = false; bool atomic = false; + spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; + assert(node->getOp()); spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); @@ -2051,6 +2705,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // anything else gets there, so visit out of order, doing them all now. makeGlobalInitializers(node->getAsAggregate()->getSequence()); + //Pre process linker objects for ray tracing stages + if (glslangIntermediate->isRayTracingStage()) + collectRayTracingLinkerObjects(); + // Initializers are done, don't want to visit again, but functions and link objects need to be processed, // so do them manually. visitFunctions(node->getAsAggregate()->getSequence()); @@ -2106,7 +2764,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.setLine(node->getLoc().line, node->getLoc().getFilename()); if (node->isUserDefined()) result = handleUserFunctionCall(node); - // assert(result); // this can happen for bad shaders because the call graph completeness checking is not yet done if (result) { builder.clearAccessChain(); builder.setAccessChainRValue(result); @@ -2222,23 +2879,30 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt case glslang::EOpConstructStruct: case glslang::EOpConstructTextureSampler: case glslang::EOpConstructReference: + case glslang::EOpConstructCooperativeMatrix: { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); std::vector arguments; - translateArguments(*node, arguments); + translateArguments(*node, arguments, lvalueCoherentFlags); spv::Id constructed; if (node->getOp() == glslang::EOpConstructTextureSampler) constructed = builder.createOp(spv::OpSampledImage, resultType(), arguments); - else if (node->getOp() == glslang::EOpConstructStruct || node->getType().isArray()) { + else if (node->getOp() == glslang::EOpConstructStruct || + node->getOp() == glslang::EOpConstructCooperativeMatrix || + node->getType().isArray()) { std::vector constituents; for (int c = 0; c < (int)arguments.size(); ++c) constituents.push_back(arguments[c]); - constructed = builder.createCompositeConstruct(resultType(), constituents); + constructed = createCompositeConstruct(resultType(), constituents); } else if (isMatrix) constructed = builder.createMatrixConstructor(precision, arguments, resultType()); else constructed = builder.createConstructor(precision, arguments, resultType()); + if (node->getType().getQualifier().isNonUniform()) { + builder.addDecoration(constructed, spv::DecorationNonUniformEXT); + } + builder.clearAccessChain(); builder.setAccessChainRValue(constructed); @@ -2286,6 +2950,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // which can be emitted by the one in createBinaryOperation() binOp = glslang::EOpMod; break; + case glslang::EOpEmitVertex: case glslang::EOpEndPrimitive: case glslang::EOpBarrier: @@ -2309,11 +2974,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // These all have 0 operands and will naturally finish up in the code below for 0 operands break; - case glslang::EOpAtomicStore: - noReturnValue = true; - // fallthrough - case glslang::EOpAtomicLoad: case glslang::EOpAtomicAdd: + case glslang::EOpAtomicSubtract: case glslang::EOpAtomicMin: case glslang::EOpAtomicMax: case glslang::EOpAtomicAnd: @@ -2324,6 +2986,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt atomic = true; break; +#ifndef GLSLANG_WEB + case glslang::EOpAtomicStore: + noReturnValue = true; + // fallthrough + case glslang::EOpAtomicLoad: + atomic = true; + break; + case glslang::EOpAtomicCounterAdd: case glslang::EOpAtomicCounterSubtract: case glslang::EOpAtomicCounterMin: @@ -2338,16 +3008,72 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt atomic = true; break; -#ifdef NV_EXTENSIONS + case glslang::EOpAbsDifference: + case glslang::EOpAddSaturate: + case glslang::EOpSubSaturate: + case glslang::EOpAverage: + case glslang::EOpAverageRounded: + case glslang::EOpMul32x16: + builder.addCapability(spv::CapabilityIntegerFunctions2INTEL); + builder.addExtension("SPV_INTEL_shader_integer_functions2"); + binOp = node->getOp(); + break; + case glslang::EOpIgnoreIntersectionNV: case glslang::EOpTerminateRayNV: case glslang::EOpTraceNV: + case glslang::EOpTraceRayMotionNV: + case glslang::EOpTraceKHR: case glslang::EOpExecuteCallableNV: + case glslang::EOpExecuteCallableKHR: case glslang::EOpWritePackedPrimitiveIndices4x8NV: noReturnValue = true; break; + case glslang::EOpRayQueryInitialize: + case glslang::EOpRayQueryTerminate: + case glslang::EOpRayQueryGenerateIntersection: + case glslang::EOpRayQueryConfirmIntersection: + builder.addExtension("SPV_KHR_ray_query"); + builder.addCapability(spv::CapabilityRayQueryKHR); + noReturnValue = true; + break; + case glslang::EOpRayQueryProceed: + case glslang::EOpRayQueryGetIntersectionType: + case glslang::EOpRayQueryGetRayTMin: + case glslang::EOpRayQueryGetRayFlags: + case glslang::EOpRayQueryGetIntersectionT: + case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex: + case glslang::EOpRayQueryGetIntersectionInstanceId: + case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: + case glslang::EOpRayQueryGetIntersectionGeometryIndex: + case glslang::EOpRayQueryGetIntersectionPrimitiveIndex: + case glslang::EOpRayQueryGetIntersectionBarycentrics: + case glslang::EOpRayQueryGetIntersectionFrontFace: + case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque: + case glslang::EOpRayQueryGetIntersectionObjectRayDirection: + case glslang::EOpRayQueryGetIntersectionObjectRayOrigin: + case glslang::EOpRayQueryGetWorldRayDirection: + case glslang::EOpRayQueryGetWorldRayOrigin: + case glslang::EOpRayQueryGetIntersectionObjectToWorld: + case glslang::EOpRayQueryGetIntersectionWorldToObject: + builder.addExtension("SPV_KHR_ray_query"); + builder.addCapability(spv::CapabilityRayQueryKHR); + break; + case glslang::EOpCooperativeMatrixLoad: + case glslang::EOpCooperativeMatrixStore: + noReturnValue = true; + break; + case glslang::EOpBeginInvocationInterlock: + case glslang::EOpEndInvocationInterlock: + builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock); + noReturnValue = true; + break; #endif + case glslang::EOpDebugPrintf: + noReturnValue = true; + break; + default: break; } @@ -2389,31 +3115,40 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // glslang::TIntermSequence& glslangOperands = node->getSequence(); std::vector operands; + std::vector memoryAccessOperands; for (int arg = 0; arg < (int)glslangOperands.size(); ++arg) { // special case l-value operands; there are just a few bool lvalue = false; switch (node->getOp()) { - case glslang::EOpFrexp: case glslang::EOpModf: if (arg == 1) lvalue = true; break; - case glslang::EOpInterpolateAtSample: - case glslang::EOpInterpolateAtOffset: -#ifdef AMD_EXTENSIONS - case glslang::EOpInterpolateAtVertex: -#endif - if (arg == 0) { - lvalue = true; - // Does it need a swizzle inversion? If so, evaluation is inverted; - // operate first on the swizzle base, then apply the swizzle. - if (glslangOperands[0]->getAsOperator() && - glslangOperands[0]->getAsOperator()->getOp() == glslang::EOpVectorSwizzle) - invertedType = convertGlslangToSpvType(glslangOperands[0]->getAsBinaryNode()->getLeft()->getType()); - } + case glslang::EOpRayQueryInitialize: + case glslang::EOpRayQueryTerminate: + case glslang::EOpRayQueryConfirmIntersection: + case glslang::EOpRayQueryProceed: + case glslang::EOpRayQueryGenerateIntersection: + case glslang::EOpRayQueryGetIntersectionType: + case glslang::EOpRayQueryGetIntersectionT: + case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex: + case glslang::EOpRayQueryGetIntersectionInstanceId: + case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: + case glslang::EOpRayQueryGetIntersectionGeometryIndex: + case glslang::EOpRayQueryGetIntersectionPrimitiveIndex: + case glslang::EOpRayQueryGetIntersectionBarycentrics: + case glslang::EOpRayQueryGetIntersectionFrontFace: + case glslang::EOpRayQueryGetIntersectionObjectRayDirection: + case glslang::EOpRayQueryGetIntersectionObjectRayOrigin: + case glslang::EOpRayQueryGetIntersectionObjectToWorld: + case glslang::EOpRayQueryGetIntersectionWorldToObject: + if (arg == 0) + lvalue = true; break; + case glslang::EOpAtomicAdd: + case glslang::EOpAtomicSubtract: case glslang::EOpAtomicMin: case glslang::EOpAtomicMax: case glslang::EOpAtomicAnd: @@ -2421,6 +3156,39 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt case glslang::EOpAtomicXor: case glslang::EOpAtomicExchange: case glslang::EOpAtomicCompSwap: + if (arg == 0) + lvalue = true; + break; + +#ifndef GLSLANG_WEB + case glslang::EOpFrexp: + if (arg == 1) + lvalue = true; + break; + case glslang::EOpInterpolateAtSample: + case glslang::EOpInterpolateAtOffset: + case glslang::EOpInterpolateAtVertex: + if (arg == 0) { + // If GLSL, use the address of the interpolant argument. + // If HLSL, use an internal version of OpInterolates that takes + // the rvalue of the interpolant. A fixup pass in spirv-opt + // legalization will remove the OpLoad and convert to an lvalue. + // Had to do this because legalization will only propagate a + // builtin into an rvalue. + lvalue = glslangIntermediate->getSource() != glslang::EShSourceHlsl; + + // Does it need a swizzle inversion? If so, evaluation is inverted; + // operate first on the swizzle base, then apply the swizzle. + // That is, we transform + // + // interpolate(v.zy) -> interpolate(v).zy + // + if (glslangOperands[0]->getAsOperator() && + glslangOperands[0]->getAsOperator()->getOp() == glslang::EOpVectorSwizzle) + invertedType = convertGlslangToSpvType( + glslangOperands[0]->getAsBinaryNode()->getLeft()->getType()); + } + break; case glslang::EOpAtomicLoad: case glslang::EOpAtomicStore: case glslang::EOpAtomicCounterAdd: @@ -2445,6 +3213,19 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (arg >= 2) lvalue = true; break; + case glslang::EOpCooperativeMatrixLoad: + if (arg == 0 || arg == 1) + lvalue = true; + break; + case glslang::EOpCooperativeMatrixStore: + if (arg == 1) + lvalue = true; + break; + case glslang::EOpSpirvInst: + if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvByReference()) + lvalue = true; + break; +#endif default: break; } @@ -2453,18 +3234,185 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt glslangOperands[0]->getAsBinaryNode()->getLeft()->traverse(this); else glslangOperands[arg]->traverse(this); - if (lvalue) - operands.push_back(builder.accessChainGetLValue()); - else { + +#ifndef GLSLANG_WEB + if (node->getOp() == glslang::EOpCooperativeMatrixLoad || + node->getOp() == glslang::EOpCooperativeMatrixStore) { + + if (arg == 1) { + // fold "element" parameter into the access chain + spv::Builder::AccessChain save = builder.getAccessChain(); + builder.clearAccessChain(); + glslangOperands[2]->traverse(this); + + spv::Id elementId = accessChainLoad(glslangOperands[2]->getAsTyped()->getType()); + + builder.setAccessChain(save); + + // Point to the first element of the array. + builder.accessChainPush(elementId, + TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()), + glslangOperands[arg]->getAsTyped()->getType().getBufferReferenceAlignment()); + + spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags; + unsigned int alignment = builder.getAccessChain().alignment; + + int memoryAccess = TranslateMemoryAccess(coherentFlags); + if (node->getOp() == glslang::EOpCooperativeMatrixLoad) + memoryAccess &= ~spv::MemoryAccessMakePointerAvailableKHRMask; + if (node->getOp() == glslang::EOpCooperativeMatrixStore) + memoryAccess &= ~spv::MemoryAccessMakePointerVisibleKHRMask; + if (builder.getStorageClass(builder.getAccessChain().base) == + spv::StorageClassPhysicalStorageBufferEXT) { + memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask); + } + + memoryAccessOperands.push_back(spv::IdImmediate(false, memoryAccess)); + + if (memoryAccess & spv::MemoryAccessAlignedMask) { + memoryAccessOperands.push_back(spv::IdImmediate(false, alignment)); + } + + if (memoryAccess & + (spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask)) { + memoryAccessOperands.push_back(spv::IdImmediate(true, + builder.makeUintConstant(TranslateMemoryScope(coherentFlags)))); + } + } else if (arg == 2) { + continue; + } + } +#endif + + // for l-values, pass the address, for r-values, pass the value + if (lvalue) { + if (invertedType == spv::NoType && !builder.isSpvLvalue()) { + // SPIR-V cannot represent an l-value containing a swizzle that doesn't + // reduce to a simple access chain. So, we need a temporary vector to + // receive the result, and must later swizzle that into the original + // l-value. + complexLvalues.push_back(builder.getAccessChain()); + temporaryLvalues.push_back(builder.createVariable( + spv::NoPrecision, spv::StorageClassFunction, + builder.accessChainGetInferredType(), "swizzleTemp")); + operands.push_back(temporaryLvalues.back()); + } else { + operands.push_back(builder.accessChainGetLValue()); + } + lvalueCoherentFlags = builder.getAccessChain().coherentFlags; + lvalueCoherentFlags |= TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()); + } else { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); - operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType())); + glslang::TOperator glslangOp = node->getOp(); + if (arg == 1 && + (glslangOp == glslang::EOpRayQueryGetIntersectionType || + glslangOp == glslang::EOpRayQueryGetIntersectionT || + glslangOp == glslang::EOpRayQueryGetIntersectionInstanceCustomIndex || + glslangOp == glslang::EOpRayQueryGetIntersectionInstanceId || + glslangOp == glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset || + glslangOp == glslang::EOpRayQueryGetIntersectionGeometryIndex || + glslangOp == glslang::EOpRayQueryGetIntersectionPrimitiveIndex || + glslangOp == glslang::EOpRayQueryGetIntersectionBarycentrics || + glslangOp == glslang::EOpRayQueryGetIntersectionFrontFace || + glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayDirection || + glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayOrigin || + glslangOp == glslang::EOpRayQueryGetIntersectionObjectToWorld || + glslangOp == glslang::EOpRayQueryGetIntersectionWorldToObject + )) { + bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst(); + operands.push_back(builder.makeIntConstant(cond ? 1 : 0)); + } else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) || + (arg == 11 && glslangOp == glslang::EOpTraceRayMotionNV) || + (arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR)) { + const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : (glslangOp == glslang::EOpTraceRayMotionNV ? 11 : 1); + const int set = glslangOp == glslang::EOpExecuteCallableKHR ? 1 : 0; + + const int location = glslangOperands[opdNum]->getAsConstantUnion()->getConstArray()[0].getUConst(); + auto itNode = locationToSymbol[set].find(location); + visitSymbol(itNode->second); + spv::Id symId = getSymbolId(itNode->second); + operands.push_back(symId); +#ifndef GLSLANG_WEB + } else if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvLiteral()) { + // Will be translated to a literal value, make a placeholder here + operands.push_back(spv::NoResult); +#endif + } else { + operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType())); + } } } builder.setLine(node->getLoc().line, node->getLoc().getFilename()); +#ifndef GLSLANG_WEB + if (node->getOp() == glslang::EOpCooperativeMatrixLoad) { + std::vector idImmOps; + + idImmOps.push_back(spv::IdImmediate(true, operands[1])); // buf + idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride + idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor + idImmOps.insert(idImmOps.end(), memoryAccessOperands.begin(), memoryAccessOperands.end()); + // get the pointee type + spv::Id typeId = builder.getContainedTypeId(builder.getTypeId(operands[0])); + assert(builder.isCooperativeMatrixType(typeId)); + // do the op + spv::Id result = builder.createOp(spv::OpCooperativeMatrixLoadNV, typeId, idImmOps); + // store the result to the pointer (out param 'm') + builder.createStore(result, operands[0]); + result = 0; + } else if (node->getOp() == glslang::EOpCooperativeMatrixStore) { + std::vector idImmOps; + + idImmOps.push_back(spv::IdImmediate(true, operands[1])); // buf + idImmOps.push_back(spv::IdImmediate(true, operands[0])); // object + idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride + idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor + idImmOps.insert(idImmOps.end(), memoryAccessOperands.begin(), memoryAccessOperands.end()); + + builder.createNoResultOp(spv::OpCooperativeMatrixStoreNV, idImmOps); + result = 0; + } else +#endif if (atomic) { // Handle all atomics - result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType()); + glslang::TBasicType typeProxy = (node->getOp() == glslang::EOpAtomicStore) + ? node->getSequence()[0]->getAsTyped()->getBasicType() : node->getBasicType(); + result = createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy, + lvalueCoherentFlags); +#ifndef GLSLANG_WEB + } else if (node->getOp() == glslang::EOpSpirvInst) { + const auto& spirvInst = node->getSpirvInstruction(); + if (spirvInst.set == "") { + std::vector idImmOps; + for (int i = 0; i < glslangOperands.size(); ++i) { + if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) { + // Translate the constant to a literal value + std::vector literals; + glslang::TVector constants; + constants.push_back(glslangOperands[i]->getAsConstantUnion()); + TranslateLiterals(constants, literals); + idImmOps.push_back({false, literals[0]}); + } else + idImmOps.push_back({true, operands[i]}); + } + + if (node->getBasicType() == glslang::EbtVoid) + builder.createNoResultOp(static_cast(spirvInst.id), idImmOps); + else + result = builder.createOp(static_cast(spirvInst.id), resultType(), idImmOps); + } else { + result = builder.createBuiltinCall( + resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()), + spirvInst.id, operands); + } + noReturnValue = node->getBasicType() == glslang::EbtVoid; +#endif + } else if (node->getOp() == glslang::EOpDebugPrintf) { + if (!nonSemanticDebugPrintf) { + nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf"); + } + result = builder.createBuiltinCall(builder.makeVoidType(), nonSemanticDebugPrintf, spv::NonSemanticDebugPrintfDebugPrintf, operands); + builder.addExtension(spv::E_SPV_KHR_non_semantic_info); } else { // Pass through to generic operations. switch (glslangOperands.size()) { @@ -2479,15 +3427,22 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt result = createUnaryOperation( node->getOp(), decorations, resultType(), operands.front(), - glslangOperands[0]->getAsTyped()->getBasicType()); + glslangOperands[0]->getAsTyped()->getBasicType(), lvalueCoherentFlags); } break; default: result = createMiscOperation(node->getOp(), precision, resultType(), operands, node->getBasicType()); break; } - if (invertedType) + + if (invertedType != spv::NoResult) result = createInvertedSwizzle(precision, *glslangOperands[0]->getAsBinaryNode(), result); + + for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) { + builder.setAccessChain(complexLvalues[i]); + builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision), + TranslateNonUniformDecoration(complexLvalues[i].coherentFlags)); + } } if (noReturnValue) @@ -2514,6 +3469,19 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // next layer copies r-values into memory to use the access-chain mechanism bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang::TIntermSelection* node) { + // see if OpSelect can handle it + const auto isOpSelectable = [&]() { + if (node->getBasicType() == glslang::EbtVoid) + return false; + // OpSelect can do all other types starting with SPV 1.4 + if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_4) { + // pre-1.4, only scalars and vectors can be handled + if ((!node->getType().isScalar() && !node->getType().isVector())) + return false; + } + return true; + }; + // See if it simple and safe, or required, to execute both sides. // Crucially, side effects must be either semantically required or avoided, // and there are performance trade-offs. @@ -2532,9 +3500,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // if not required to execute both, decide based on performance/practicality... - // see if OpSelect can handle it - if ((!node->getType().isScalar() && !node->getType().isVector()) || - node->getBasicType() == glslang::EbtVoid) + if (!isOpSelectable()) return false; assert(node->getType() == node->getTrueBlock() ->getAsTyped()->getType() && @@ -2571,14 +3537,16 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // emit code to select between trueValue and falseValue // see if OpSelect can handle it - if (node->getType().isScalar() || node->getType().isVector()) { + if (isOpSelectable()) { // Emit OpSelect for this selection. // smear condition to vector, if necessary (AST is always scalar) - if (builder.isVector(trueValue)) + // Before 1.4, smear like for mix(), starting with 1.4, keep it scalar + if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_4 && builder.isVector(trueValue)) { condition = builder.smearScalar(spv::NoPrecision, condition, builder.makeVectorType(builder.makeBoolType(), builder.getNumComponents(trueValue))); + } // OpSelect result = builder.createTriOp(spv::OpSelect, @@ -2590,7 +3558,8 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang } else { // We need control flow to select the result. // TODO: Once SPIR-V OpSelect allows arbitrary types, eliminate this path. - result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType())); + result = builder.createVariable(TranslatePrecisionDecoration(node->getType()), + spv::StorageClassFunction, convertGlslangToSpvType(node->getType())); // Selection control: const spv::SelectionControlMask control = TranslateSelectionControl(*node); @@ -2615,8 +3584,10 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // Execute the one side needed, as per the condition const auto executeOneSide = [&]() { // Always emit control flow. - if (node->getBasicType() != glslang::EbtVoid) - result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType())); + if (node->getBasicType() != glslang::EbtVoid) { + result = builder.createVariable(TranslatePrecisionDecoration(node->getType()), spv::StorageClassFunction, + convertGlslangToSpvType(node->getType())); + } // Selection control: const spv::SelectionControlMask control = TranslateSelectionControl(*node); @@ -2681,7 +3652,8 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T defaultSegment = (int)codeSegments.size(); else if (child->getAsBranchNode() && child->getAsBranchNode()->getFlowOp() == glslang::EOpCase) { valueIndexToSegment[caseValues.size()] = (int)codeSegments.size(); - caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion()->getConstArray()[0].getIConst()); + caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion() + ->getConstArray()[0].getIConst()); } else codeSegments.push_back(child); } @@ -2694,7 +3666,8 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T // make the switch statement std::vector segmentBlocks; // returned, as the blocks allocated in the call - builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks); + builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, + segmentBlocks); // emit all the code in the segments breakForLoop.push(false); @@ -2714,6 +3687,11 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node) { +#ifndef GLSLANG_WEB + if (node->getQualifier().isSpirvLiteral()) + return; // Translated to a literal value, skip further processing +#endif + int nextConst = 0; spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false); @@ -2727,8 +3705,8 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn builder.createBranch(&blocks.head); // Loop control: - unsigned int dependencyLength = glslang::TIntermLoop::dependencyInfinite; - const spv::LoopControlMask control = TranslateLoopControl(*node, dependencyLength); + std::vector operands; + const spv::LoopControlMask control = TranslateLoopControl(*node, operands); // Spec requires back edges to target header blocks, and every header block // must dominate its merge block. Make a header block first to ensure these @@ -2738,7 +3716,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn // including merges of its own. builder.setLine(node->getLoc().line, node->getLoc().getFilename()); builder.setBuildPoint(&blocks.head); - builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, dependencyLength); + builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, operands); if (node->testFirst() && node->getTest()) { spv::Block& test = builder.makeNewBlock(); builder.createBranch(&test); @@ -2799,7 +3777,11 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T switch (node->getFlowOp()) { case glslang::EOpKill: - builder.makeDiscard(); + builder.makeStatementTerminator(spv::OpKill, "post-discard"); + break; + case glslang::EOpTerminateInvocation: + builder.addExtension(spv::E_SPV_KHR_terminate_invocation); + builder.makeStatementTerminator(spv::OpTerminateInvocation, "post-terminate-invocation"); break; case glslang::EOpBreak: if (breakForLoop.top()) @@ -2811,15 +3793,17 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T builder.createLoopContinue(); break; case glslang::EOpReturn: - if (node->getExpression()) { + if (node->getExpression() != nullptr) { const glslang::TType& glslangReturnType = node->getExpression()->getType(); spv::Id returnId = accessChainLoad(glslangReturnType); - if (builder.getTypeId(returnId) != currentFunction->getReturnType()) { + if (builder.getTypeId(returnId) != currentFunction->getReturnType() || + TranslatePrecisionDecoration(glslangReturnType) != currentFunction->getReturnPrecision()) { builder.clearAccessChain(); - spv::Id copyId = builder.createVariable(spv::StorageClassFunction, currentFunction->getReturnType()); + spv::Id copyId = builder.createVariable(currentFunction->getReturnPrecision(), + spv::StorageClassFunction, currentFunction->getReturnType()); builder.setAccessChainLValue(copyId); multiTypeStore(glslangReturnType, returnId); - returnId = builder.createLoad(copyId); + returnId = builder.createLoad(copyId, currentFunction->getReturnPrecision()); } builder.makeReturn(false, returnId); } else @@ -2828,6 +3812,20 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T builder.clearAccessChain(); break; +#ifndef GLSLANG_WEB + case glslang::EOpDemote: + builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT); + builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation); + builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT); + break; + case glslang::EOpTerminateRayKHR: + builder.makeStatementTerminator(spv::OpTerminateRayKHR, "post-terminateRayKHR"); + break; + case glslang::EOpIgnoreIntersectionKHR: + builder.makeStatementTerminator(spv::OpIgnoreIntersectionKHR, "post-ignoreIntersectionKHR"); + break; +#endif + default: assert(0); break; @@ -2836,7 +3834,7 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T return false; } -spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* node) +spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* node, spv::Id forcedType) { // First, steer off constants, which are not SPIR-V variables, but // can still have a mapping to a SPIR-V Id. @@ -2849,51 +3847,65 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* // Now, handle actual variables spv::StorageClass storageClass = TranslateStorageClass(node->getType()); - spv::Id spvType = convertGlslangToSpvType(node->getType()); + spv::Id spvType = forcedType == spv::NoType ? convertGlslangToSpvType(node->getType()) + : forcedType; - const bool contains16BitType = node->getType().containsBasicType(glslang::EbtFloat16) || - node->getType().containsBasicType(glslang::EbtInt16) || - node->getType().containsBasicType(glslang::EbtUint16); + const bool contains16BitType = node->getType().contains16BitFloat() || + node->getType().contains16BitInt(); if (contains16BitType) { switch (storageClass) { case spv::StorageClassInput: case spv::StorageClassOutput: - addPre13Extension(spv::E_SPV_KHR_16bit_storage); + builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); builder.addCapability(spv::CapabilityStorageInputOutput16); break; - case spv::StorageClassPushConstant: - addPre13Extension(spv::E_SPV_KHR_16bit_storage); - builder.addCapability(spv::CapabilityStoragePushConstant16); - break; case spv::StorageClassUniform: - addPre13Extension(spv::E_SPV_KHR_16bit_storage); + builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); if (node->getType().getQualifier().storage == glslang::EvqBuffer) builder.addCapability(spv::CapabilityStorageUniformBufferBlock16); else builder.addCapability(spv::CapabilityStorageUniform16); break; +#ifndef GLSLANG_WEB + case spv::StorageClassPushConstant: + builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); + builder.addCapability(spv::CapabilityStoragePushConstant16); + break; case spv::StorageClassStorageBuffer: case spv::StorageClassPhysicalStorageBufferEXT: - addPre13Extension(spv::E_SPV_KHR_16bit_storage); + builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); builder.addCapability(spv::CapabilityStorageUniformBufferBlock16); break; +#endif default: + if (storageClass == spv::StorageClassWorkgroup && + node->getType().getBasicType() == glslang::EbtBlock) { + builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR); + break; + } + if (node->getType().contains16BitFloat()) + builder.addCapability(spv::CapabilityFloat16); + if (node->getType().contains16BitInt()) + builder.addCapability(spv::CapabilityInt16); break; } } - const bool contains8BitType = node->getType().containsBasicType(glslang::EbtInt8) || - node->getType().containsBasicType(glslang::EbtUint8); - if (contains8BitType) { + if (node->getType().contains8BitInt()) { if (storageClass == spv::StorageClassPushConstant) { - builder.addExtension(spv::E_SPV_KHR_8bit_storage); + builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5); builder.addCapability(spv::CapabilityStoragePushConstant8); } else if (storageClass == spv::StorageClassUniform) { - builder.addExtension(spv::E_SPV_KHR_8bit_storage); + builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5); builder.addCapability(spv::CapabilityUniformAndStorageBuffer8BitAccess); } else if (storageClass == spv::StorageClassStorageBuffer) { - builder.addExtension(spv::E_SPV_KHR_8bit_storage); + builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5); builder.addCapability(spv::CapabilityStorageBuffer8BitAccess); + } else if (storageClass == spv::StorageClassWorkgroup && + node->getType().getBasicType() == glslang::EbtBlock) { + builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR); + } else { + builder.addCapability(spv::CapabilityInt8); } } @@ -2901,22 +3913,40 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* if (glslang::IsAnonymous(name)) name = ""; - return builder.createVariable(storageClass, spvType, name); + spv::Id initializer = spv::NoResult; + + if (node->getType().getQualifier().storage == glslang::EvqUniform && !node->getConstArray().empty()) { + int nextConst = 0; + initializer = createSpvConstantFromConstUnionArray(node->getType(), + node->getConstArray(), + nextConst, + false /* specConst */); + } else if (node->getType().getQualifier().isNullInit()) { + initializer = builder.makeNullConstant(spvType); + } + + return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer); } // Return type Id of the sampled type. spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler) { switch (sampler.type) { + case glslang::EbtInt: return builder.makeIntType(32); + case glslang::EbtUint: return builder.makeUintType(32); case glslang::EbtFloat: return builder.makeFloatType(32); -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB case glslang::EbtFloat16: builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch); builder.addCapability(spv::CapabilityFloat16ImageAMD); return builder.makeFloatType(16); + case glslang::EbtInt64: return builder.makeIntType(64); + builder.addExtension(spv::E_SPV_EXT_shader_image_int64); + builder.addCapability(spv::CapabilityFloat16ImageAMD); + case glslang::EbtUint64: return builder.makeUintType(64); + builder.addExtension(spv::E_SPV_EXT_shader_image_int64); + builder.addCapability(spv::CapabilityFloat16ImageAMD); #endif - case glslang::EbtInt: return builder.makeIntType(32); - case glslang::EbtUint: return builder.makeUintType(32); default: assert(0); return builder.makeFloatType(32); @@ -2937,7 +3967,8 @@ spv::Id TGlslangToSpvTraverser::getInvertedSwizzleType(const glslang::TIntermTyp // When inverting a swizzle with a parent op, this function // will apply the swizzle operation to a completed parent operation. -spv::Id TGlslangToSpvTraverser::createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped& node, spv::Id parentResult) +spv::Id TGlslangToSpvTraverser::createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped& node, + spv::Id parentResult) { std::vector swizzle; convertSwizzle(*node.getAsBinaryNode()->getRight()->getAsAggregate(), swizzle); @@ -2974,15 +4005,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty spvType = builder.makeVoidType(); assert (! type.isArray()); break; - case glslang::EbtFloat: - spvType = builder.makeFloatType(32); - break; - case glslang::EbtDouble: - spvType = builder.makeFloatType(64); - break; - case glslang::EbtFloat16: - spvType = builder.makeFloatType(16); - break; case glslang::EbtBool: // "transparent" bool doesn't exist in SPIR-V. The GLSL convention is // a 32-bit int where non-0 means true. @@ -2991,6 +4013,22 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty else spvType = builder.makeBoolType(); break; + case glslang::EbtInt: + spvType = builder.makeIntType(32); + break; + case glslang::EbtUint: + spvType = builder.makeUintType(32); + break; + case glslang::EbtFloat: + spvType = builder.makeFloatType(32); + break; +#ifndef GLSLANG_WEB + case glslang::EbtDouble: + spvType = builder.makeFloatType(64); + break; + case glslang::EbtFloat16: + spvType = builder.makeFloatType(16); + break; case glslang::EbtInt8: spvType = builder.makeIntType(8); break; @@ -3003,12 +4041,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty case glslang::EbtUint16: spvType = builder.makeUintType(16); break; - case glslang::EbtInt: - spvType = builder.makeIntType(32); - break; - case glslang::EbtUint: - spvType = builder.makeUintType(32); - break; case glslang::EbtInt64: spvType = builder.makeIntType(64); break; @@ -3019,22 +4051,67 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty builder.addCapability(spv::CapabilityAtomicStorage); spvType = builder.makeUintType(32); break; -#ifdef NV_EXTENSIONS - case glslang::EbtAccStructNV: - spvType = builder.makeAccelerationStructureNVType(); + case glslang::EbtAccStruct: + switch (glslangIntermediate->getStage()) { + case EShLangRayGen: + case EShLangIntersect: + case EShLangAnyHit: + case EShLangClosestHit: + case EShLangMiss: + case EShLangCallable: + // these all should have the RayTracingNV/KHR capability already + break; + default: + { + auto& extensions = glslangIntermediate->getRequestedExtensions(); + if (extensions.find("GL_EXT_ray_query") != extensions.end()) { + builder.addExtension(spv::E_SPV_KHR_ray_query); + builder.addCapability(spv::CapabilityRayQueryKHR); + } + } + break; + } + spvType = builder.makeAccelerationStructureType(); + break; + case glslang::EbtRayQuery: + { + auto& extensions = glslangIntermediate->getRequestedExtensions(); + if (extensions.find("GL_EXT_ray_query") != extensions.end()) { + builder.addExtension(spv::E_SPV_KHR_ray_query); + builder.addCapability(spv::CapabilityRayQueryKHR); + } + spvType = builder.makeRayQueryType(); + } + break; + case glslang::EbtReference: + { + // Make the forward pointer, then recurse to convert the structure type, then + // patch up the forward pointer with a real pointer type. + if (forwardPointers.find(type.getReferentType()) == forwardPointers.end()) { + spv::Id forwardId = builder.makeForwardPointer(spv::StorageClassPhysicalStorageBufferEXT); + forwardPointers[type.getReferentType()] = forwardId; + } + spvType = forwardPointers[type.getReferentType()]; + if (!forwardReferenceOnly) { + spv::Id referentType = convertGlslangToSpvType(*type.getReferentType()); + builder.makePointerFromForwardPointer(spv::StorageClassPhysicalStorageBufferEXT, + forwardPointers[type.getReferentType()], + referentType); + } + } break; #endif case glslang::EbtSampler: { const glslang::TSampler& sampler = type.getSampler(); - if (sampler.sampler) { - // pure sampler + if (sampler.isPureSampler()) { spvType = builder.makeSamplerType(); } else { // an image is present, make its type - spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms, - sampler.image ? 2 : 1, TranslateImageFormat(type)); - if (sampler.combined) { + spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), + sampler.isShadow(), sampler.isArrayed(), sampler.isMultiSample(), + sampler.isImageClass() ? 2 : 1, TranslateImageFormat(type)); + if (sampler.isCombined()) { // already has both image and sampler, make the combined type spvType = builder.makeSampledImageType(spvType); } @@ -3056,27 +4133,84 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty // else, we haven't seen it... if (type.getBasicType() == glslang::EbtBlock) - memberRemapper[glslangMembers].resize(glslangMembers->size()); + memberRemapper[glslangTypeToIdMap[glslangMembers]].resize(glslangMembers->size()); spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier); } break; - case glslang::EbtReference: - { - // Make the forward pointer, then recurse to convert the structure type, then - // patch up the forward pointer with a real pointer type. - if (forwardPointers.find(type.getReferentType()) == forwardPointers.end()) { - spv::Id forwardId = builder.makeForwardPointer(spv::StorageClassPhysicalStorageBufferEXT); - forwardPointers[type.getReferentType()] = forwardId; - } - spvType = forwardPointers[type.getReferentType()]; - if (!forwardReferenceOnly) { - spv::Id referentType = convertGlslangToSpvType(*type.getReferentType()); - builder.makePointerFromForwardPointer(spv::StorageClassPhysicalStorageBufferEXT, - forwardPointers[type.getReferentType()], - referentType); + case glslang::EbtString: + // no type used for OpString + return 0; +#ifndef GLSLANG_WEB + case glslang::EbtSpirvType: { + // GL_EXT_spirv_intrinsics + const auto& spirvType = type.getSpirvType(); + const auto& spirvInst = spirvType.spirvInst; + + std::vector operands; + for (const auto& typeParam : spirvType.typeParams) { + if (typeParam.isConstant) { + // Constant expression + if (typeParam.constant->isLiteral()) { + if (typeParam.constant->getBasicType() == glslang::EbtFloat) { + float floatValue = static_cast(typeParam.constant->getConstArray()[0].getDConst()); + unsigned literal = *reinterpret_cast(&floatValue); + operands.push_back(literal); + } else if (typeParam.constant->getBasicType() == glslang::EbtInt) { + unsigned literal = typeParam.constant->getConstArray()[0].getIConst(); + operands.push_back(literal); + } else if (typeParam.constant->getBasicType() == glslang::EbtUint) { + unsigned literal = typeParam.constant->getConstArray()[0].getUConst(); + operands.push_back(literal); + } else if (typeParam.constant->getBasicType() == glslang::EbtBool) { + unsigned literal = typeParam.constant->getConstArray()[0].getBConst(); + operands.push_back(literal); + } else if (typeParam.constant->getBasicType() == glslang::EbtString) { + auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str(); + unsigned literal = 0; + char* literalPtr = reinterpret_cast(&literal); + unsigned charCount = 0; + char ch = 0; + do { + ch = *(str++); + *(literalPtr++) = ch; + ++charCount; + if (charCount == 4) { + operands.push_back(literal); + literalPtr = reinterpret_cast(&literal); + charCount = 0; + } + } while (ch != 0); + + // Partial literal is padded with 0 + if (charCount > 0) { + for (; charCount < 4; ++charCount) + *(literalPtr++) = 0; + operands.push_back(literal); + } + } else + assert(0); // Unexpected type + } else { + int nextConst = 0; + spv::Id constant = createSpvConstantFromConstUnionArray( + typeParam.constant->getType(), typeParam.constant->getConstArray(), nextConst, false); + operands.push_back(constant); + } + } else { + // Type specifier + spv::Id typeId = convertGlslangToSpvType(*typeParam.type); + operands.push_back(typeId); } } + + if (spirvInst.set == "") + spvType = builder.createOp(static_cast(spirvInst.id), spv::NoType, operands); + else { + spvType = builder.createBuiltinCall( + spv::NoType, getExtBuiltins(spirvInst.set.c_str()), spirvInst.id, operands); + } break; + } +#endif default: assert(0); break; @@ -3090,6 +4224,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty spvType = builder.makeVectorType(spvType, type.getVectorSize()); } + if (type.isCoopMat()) { + builder.addCapability(spv::CapabilityCooperativeMatrixNV); + builder.addExtension(spv::E_SPV_NV_cooperative_matrix); + if (type.getBasicType() == glslang::EbtFloat16) + builder.addCapability(spv::CapabilityFloat16); + if (type.getBasicType() == glslang::EbtUint8 || + type.getBasicType() == glslang::EbtInt8) { + builder.addCapability(spv::CapabilityInt8); + } + + spv::Id scope = makeArraySizeId(*type.getTypeParameters(), 1); + spv::Id rows = makeArraySizeId(*type.getTypeParameters(), 2); + spv::Id cols = makeArraySizeId(*type.getTypeParameters(), 3); + + spvType = builder.makeCooperativeMatrixType(spvType, scope, rows, cols); + } + if (type.isArray()) { int stride = 0; // keep this 0 unless doing an explicit layout; 0 will mean no decoration, no stride @@ -3128,10 +4279,12 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty if (type.isSizedArray()) spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride); else { +#ifndef GLSLANG_WEB if (!lastBufferBlockMember) { - builder.addExtension("SPV_EXT_descriptor_indexing"); + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT); } +#endif spvType = builder.makeRuntimeArray(spvType); } if (stride > 0) @@ -3147,7 +4300,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty // bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member) { -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB auto& extensions = glslangIntermediate->getRequestedExtensions(); if (member.getFieldName() == "gl_SecondaryViewportMaskNV" && @@ -3183,19 +4336,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy { // Create a vector of struct types for SPIR-V to consume std::vector spvMembers; - int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks + int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, + // except sometimes for blocks std::vector > deferredForwardPointers; for (int i = 0; i < (int)glslangMembers->size(); i++) { glslang::TType& glslangMember = *(*glslangMembers)[i].type; if (glslangMember.hiddenMember()) { ++memberDelta; if (type.getBasicType() == glslang::EbtBlock) - memberRemapper[glslangMembers][i] = -1; + memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = -1; } else { if (type.getBasicType() == glslang::EbtBlock) { - memberRemapper[glslangMembers][i] = i - memberDelta; - if (filterMember(glslangMember)) + if (filterMember(glslangMember)) { + memberDelta++; + memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = -1; continue; + } + memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = i - memberDelta; } // modify just this child's view of the qualifier glslang::TQualifier memberQualifier = glslangMember.getQualifier(); @@ -3211,15 +4368,17 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy // Make forward pointers for any pointer members, and create a list of members to // convert to spirv types after creating the struct. - if (glslangMember.getBasicType() == glslang::EbtReference) { + if (glslangMember.isReference()) { if (forwardPointers.find(glslangMember.getReferentType()) == forwardPointers.end()) { deferredForwardPointers.push_back(std::make_pair(&glslangMember, memberQualifier)); } spvMembers.push_back( - convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, true)); + convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, + true)); } else { spvMembers.push_back( - convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, false)); + convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, + false)); } } } @@ -3248,12 +4407,13 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, { // Name and decorate the non-hidden members int offset = -1; - int locationOffset = 0; // for use within the members of this struct + bool memberLocationInvalid = type.isArrayOfArrays() || + (type.isArray() && (type.getQualifier().isArrayedIo(glslangIntermediate->getStage()) == false)); for (int i = 0; i < (int)glslangMembers->size(); i++) { glslang::TType& glslangMember = *(*glslangMembers)[i].type; int member = i; if (type.getBasicType() == glslang::EbtBlock) { - member = memberRemapper[glslangMembers][i]; + member = memberRemapper[glslangTypeToIdMap[glslangMembers]][i]; if (filterMember(glslangMember)) continue; } @@ -3278,13 +4438,14 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, glslangIntermediate->getSource() == glslang::EShSourceHlsl) { builder.addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier)); builder.addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier)); -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB addMeshNVDecoration(spvType, member, memberQualifier); #endif } } builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier)); +#ifndef GLSLANG_WEB if (type.getBasicType() == glslang::EbtBlock && qualifier.storage == glslang::EvqBuffer) { // Add memory decorations only to top-level members of shader storage block @@ -3294,17 +4455,15 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, builder.addMemberDecoration(spvType, member, memory[i]); } +#endif + // Location assignment was already completed correctly by the front end, // just track whether a member needs to be decorated. // Ignore member locations if the container is an array, as that's // ill-specified and decisions have been made to not allow this. - if (! type.isArray() && memberQualifier.hasLocation()) + if (!memberLocationInvalid && memberQualifier.hasLocation()) builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation); - if (qualifier.hasLocation()) // track for upcoming inheritance - locationOffset += glslangIntermediate->computeTypeLocationSize( - glslangMember, glslangIntermediate->getStage()); - // component, XFB, others if (glslangMember.getQualifier().hasComponent()) builder.addMemberDecoration(spvType, member, spv::DecorationComponent, @@ -3330,6 +4489,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, if (builtIn != spv::BuiltInMax) builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn); +#ifndef GLSLANG_WEB // nonuniform builder.addMemberDecoration(spvType, member, TranslateNonUniformDecoration(glslangMember.getQualifier())); @@ -3339,7 +4499,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, memberQualifier.semanticName); } -#ifdef NV_EXTENSIONS if (builtIn == spv::BuiltInLayer) { // SPV_NV_viewport_array2 extension if (glslangMember.getQualifier().layoutViewportRelative){ @@ -3360,6 +4519,38 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV); builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough); } + + // + // Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics) + // + if (glslangMember.getQualifier().hasSprivDecorate()) { + const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate(); + + // Add spirv_decorate + for (auto& decorate : spirvDecorate.decorates) { + if (!decorate.second.empty()) { + std::vector literals; + TranslateLiterals(decorate.second, literals); + builder.addMemberDecoration(spvType, member, static_cast(decorate.first), literals); + } + else + builder.addMemberDecoration(spvType, member, static_cast(decorate.first)); + } + + // spirv_decorate_id not applied to members + assert(spirvDecorate.decorateIds.empty()); + + // Add spirv_decorate_string + for (auto& decorateString : spirvDecorate.decorateStrings) { + std::vector strings; + assert(!decorateString.second.empty()); + for (auto extraOperand : decorateString.second) { + const char* string = extraOperand->getConstArray()[0].getSConst()->c_str(); + strings.push_back(string); + } + builder.addDecoration(spvType, static_cast(decorateString.first), strings); + } + } #endif } @@ -3378,6 +4569,8 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim); if (specNode != nullptr) { builder.clearAccessChain(); + SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); + spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); specNode->traverse(this); return accessChainLoad(specNode->getAsTyped()->getType()); } @@ -3401,29 +4594,19 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) coherentFlags |= TranslateCoherent(type); unsigned int alignment = builder.getAccessChain().alignment; - alignment |= getBufferReferenceAlignment(type); + alignment |= type.getBufferReferenceAlignment(); spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type), - TranslateNonUniformDecoration(type.getQualifier()), - nominalTypeId, - spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask), - TranslateMemoryScope(coherentFlags), - alignment); + TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags), + TranslateNonUniformDecoration(type.getQualifier()), + nominalTypeId, + spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask), + TranslateMemoryScope(coherentFlags), + alignment); // Need to convert to abstract types when necessary if (type.getBasicType() == glslang::EbtBool) { - if (builder.isScalarType(nominalTypeId)) { - // Conversion for bool - spv::Id boolType = builder.makeBoolType(); - if (nominalTypeId != boolType) - loadedId = builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0)); - } else if (builder.isVectorType(nominalTypeId)) { - // Conversion for bvec - int vecSize = builder.getNumTypeComponents(nominalTypeId); - spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize); - if (nominalTypeId != bvecType) - loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId, makeSmearedConstant(builder.makeUintConstant(0), vecSize)); - } + loadedId = convertLoadedBoolInUniformToUint(type, nominalTypeId, loadedId); } return loadedId; @@ -3468,10 +4651,11 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I coherentFlags |= TranslateCoherent(type); unsigned int alignment = builder.getAccessChain().alignment; - alignment |= getBufferReferenceAlignment(type); + alignment |= type.getBufferReferenceAlignment(); - builder.accessChainStore(rvalue, - spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask), + builder.accessChainStore(rvalue, TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags), + spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & + ~spv::MemoryAccessMakePointerVisibleKHRMask), TranslateMemoryScope(coherentFlags), alignment); } @@ -3507,6 +4691,20 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id // where the two types were the same type in GLSL. This requires member // by member copy, recursively. + // SPIR-V 1.4 added an instruction to do help do this. + if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) { + // However, bool in uniform space is changed to int, so + // OpCopyLogical does not work for that. + // TODO: It would be more robust to do a full recursive verification of the types satisfying SPIR-V rules. + bool rBool = builder.containsType(builder.getTypeId(rValue), spv::OpTypeBool, 0); + bool lBool = builder.containsType(lType, spv::OpTypeBool, 0); + if (lBool == rBool) { + spv::Id logicalCopy = builder.createUnaryOp(spv::OpCopyLogical, lType, rValue); + accessChainStore(type, logicalCopy); + return; + } + } + // If an array, copy element by element. if (type.isArray()) { glslang::TType glslangElementType(type, 0); @@ -3518,7 +4716,8 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id // set up the target storage builder.clearAccessChain(); builder.setAccessChainLValue(lValue); - builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), getBufferReferenceAlignment(type)); + builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), + type.getBufferReferenceAlignment()); // store the member multiTypeStore(glslangElementType, elementRValue); @@ -3538,7 +4737,8 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id // set up the target storage builder.clearAccessChain(); builder.setAccessChainLValue(lValue); - builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), getBufferReferenceAlignment(type)); + builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), + type.getBufferReferenceAlignment()); // store the member multiTypeStore(glslangMemberType, memberRValue); @@ -3558,6 +4758,7 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang: // has to be a uniform or buffer block or task in/out blocks if (type.getQualifier().storage != glslang::EvqUniform && type.getQualifier().storage != glslang::EvqBuffer && + type.getQualifier().storage != glslang::EvqShared && !type.getQualifier().isTaskMemory()) return glslang::ElpNone; @@ -3573,18 +4774,21 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang: } // Given an array type, returns the integer stride required for that array -int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout) +int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout, + glslang::TLayoutMatrix matrixLayout) { int size; int stride; - glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor); + glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout, + matrixLayout == glslang::ElmRowMajor); return stride; } // Given a matrix type, or array (of array) of matrixes type, returns the integer stride required for that matrix // when used as a member of an interface block -int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout) +int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout, + glslang::TLayoutMatrix matrixLayout) { glslang::TType elementType; elementType.shallowCopy(matrixType); @@ -3592,7 +4796,8 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl int size; int stride; - glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor); + glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout, + matrixLayout == glslang::ElmRowMajor); return stride; } @@ -3603,8 +4808,8 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl // 'currentOffset' should be passed in already initialized, ready to modify, and reflecting // the migration of data from nextOffset -> currentOffset. It should be -1 on the first call. // -1 means a non-forced member offset (no decoration needed). -void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset, - glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout) +void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, + int& currentOffset, int& nextOffset, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout) { // this will get a positive value when deemed necessary nextOffset = -1; @@ -3634,7 +4839,8 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType int memberSize; int dummyStride; - int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, matrixLayout == glslang::ElmRowMajor); + int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, + matrixLayout == glslang::ElmRowMajor); // Adjust alignment for HLSL rules // TODO: make this consistent in early phases of code: @@ -3653,7 +4859,8 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType glslang::RoundToPow2(currentOffset, memberAlignment); // Bump up to vec4 if there is a bad straddle - if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize, currentOffset)) + if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize, + currentOffset)) glslang::RoundToPow2(currentOffset, 16); nextOffset = currentOffset + memberSize; @@ -3664,10 +4871,10 @@ void TGlslangToSpvTraverser::declareUseOfStructMember(const glslang::TTypeList& const glslang::TBuiltInVariable glslangBuiltIn = members[glslangMember].type->getQualifier().builtIn; switch (glslangBuiltIn) { + case glslang::EbvPointSize: +#ifndef GLSLANG_WEB case glslang::EbvClipDistance: case glslang::EbvCullDistance: - case glslang::EbvPointSize: -#ifdef NV_EXTENSIONS case glslang::EbvViewportMaskNV: case glslang::EbvSecondaryPositionNV: case glslang::EbvSecondaryViewportMaskNV: @@ -3706,8 +4913,10 @@ bool TGlslangToSpvTraverser::writableParam(glslang::TStorageQualifier qualifier) assert(qualifier == glslang::EvqIn || qualifier == glslang::EvqOut || qualifier == glslang::EvqInOut || + qualifier == glslang::EvqUniform || qualifier == glslang::EvqConstReadOnly); - return qualifier != glslang::EvqConstReadOnly; + return qualifier != glslang::EvqConstReadOnly && + qualifier != glslang::EvqUniform; } // Is parameter pass-by-original? @@ -3719,26 +4928,32 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier, if (glslangIntermediate->getSource() == glslang::EShSourceHlsl) return paramType.getBasicType() == glslang::EbtBlock; return paramType.containsOpaque() || // sampler, etc. +#ifndef GLSLANG_WEB + paramType.getQualifier().isSpirvByReference() || // spirv_by_reference +#endif (paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO } // Make all the functions, skeletally, without actually visiting their bodies. void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions) { - const auto getParamDecorations = [&](std::vector& decorations, const glslang::TType& type, bool useVulkanMemoryModel) { + const auto getParamDecorations = [&](std::vector& decorations, const glslang::TType& type, + bool useVulkanMemoryModel) { spv::Decoration paramPrecision = TranslatePrecisionDecoration(type); if (paramPrecision != spv::NoPrecision) decorations.push_back(paramPrecision); TranslateMemoryDecoration(type.getQualifier(), decorations, useVulkanMemoryModel); - if (type.getBasicType() == glslang::EbtReference) { + if (type.isReference()) { // Original and non-writable params pass the pointer directly and // use restrict/aliased, others are stored to a pointer in Function // memory and use RestrictPointer/AliasedPointer. if (originalParam(type.getQualifier().storage, type, false) || !writableParam(type.getQualifier().storage)) { - decorations.push_back(type.getQualifier().restrict ? spv::DecorationRestrict : spv::DecorationAliased); + decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrict : + spv::DecorationAliased); } else { - decorations.push_back(type.getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); + decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrictPointerEXT : + spv::DecorationAliasedPointerEXT); } } }; @@ -3766,8 +4981,12 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF std::vector> paramDecorations; // list of decorations per parameter glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence(); +#ifdef ENABLE_HLSL bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() == glslangIntermediate->implicitThisName; +#else + bool implicitThis = false; +#endif paramDecorations.resize(parameters.size()); for (int p = 0; p < (int)parameters.size(); ++p) { @@ -3799,6 +5018,14 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF symbolValues[parameters[p]->getAsSymbolNode()->getId()] = function->getParamId(p); // give a name too builder.addName(function->getParamId(p), parameters[p]->getAsSymbolNode()->getName().c_str()); + + const glslang::TType& paramType = parameters[p]->getAsTyped()->getType(); + if (paramType.contains8BitInt()) + builder.addCapability(spv::CapabilityInt8); + if (paramType.contains16BitInt()) + builder.addCapability(spv::CapabilityInt16); + if (paramType.contains16BitFloat()) + builder.addCapability(spv::CapabilityFloat16); } } } @@ -3809,7 +5036,8 @@ void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequen builder.setBuildPoint(shaderEntry->getLastBlock()); for (int i = 0; i < (int)initializers.size(); ++i) { glslang::TIntermAggregate* initializer = initializers[i]->getAsAggregate(); - if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() != glslang::EOpLinkerObjects) { + if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() != + glslang::EOpLinkerObjects) { // We're on a top-level node that's not a function. Treat as an initializer, whose // code goes into the beginning of the entry point. @@ -3817,7 +5045,39 @@ void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequen } } } +// Walk over all linker objects to create a map for payload and callable data linker objects +// and their location to be used during codegen for OpTraceKHR and OpExecuteCallableKHR +// This is done here since it is possible that these linker objects are not be referenced in the AST +void TGlslangToSpvTraverser::collectRayTracingLinkerObjects() +{ + glslang::TIntermAggregate* linkerObjects = glslangIntermediate->findLinkerObjects(); + for (auto& objSeq : linkerObjects->getSequence()) { + auto objNode = objSeq->getAsSymbolNode(); + if (objNode != nullptr) { + if (objNode->getQualifier().hasLocation()) { + unsigned int location = objNode->getQualifier().layoutLocation; + auto st = objNode->getQualifier().storage; + int set; + switch (st) + { + case glslang::EvqPayload: + case glslang::EvqPayloadIn: + set = 0; + break; + case glslang::EvqCallableData: + case glslang::EvqCallableDataIn: + set = 1; + break; + default: + set = -1; + } + if (set != -1) + locationToSymbol[set].insert(std::make_pair(location, objNode)); + } + } + } +} // Process all the functions, while skipping initializers. void TGlslangToSpvTraverser::visitFunctions(const glslang::TIntermSequence& glslFunctions) { @@ -3837,20 +5097,22 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate builder.setBuildPoint(functionBlock); } -void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments) +void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, + spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { const glslang::TIntermSequence& glslangArguments = node.getSequence(); glslang::TSampler sampler = {}; bool cubeCompare = false; -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB bool f16ShadowCompare = false; #endif if (node.isTexture() || node.isImage()) { sampler = glslangArguments[0]->getAsTyped()->getType().getSampler(); cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow; -#ifdef AMD_EXTENSIONS - f16ShadowCompare = sampler.shadow && glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16; +#ifndef GLSLANG_WEB + f16ShadowCompare = sampler.shadow && + glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16; #endif } @@ -3858,6 +5120,7 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& builder.clearAccessChain(); glslangArguments[i]->traverse(this); +#ifndef GLSLANG_WEB // Special case l-value operands bool lvalue = false; switch (node.getOp()) { @@ -3878,7 +5141,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((sampler.ms && i == 3) || (! sampler.ms && i == 2)) lvalue = true; break; -#ifdef AMD_EXTENSIONS case glslang::EOpSparseTexture: if (((cubeCompare || f16ShadowCompare) && i == 3) || (! (cubeCompare || f16ShadowCompare) && i == 2)) lvalue = true; @@ -3892,21 +5154,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((f16ShadowCompare && i == 4) || (! f16ShadowCompare && i == 3)) lvalue = true; break; -#else - case glslang::EOpSparseTexture: - if ((cubeCompare && i == 3) || (! cubeCompare && i == 2)) - lvalue = true; - break; - case glslang::EOpSparseTextureClamp: - if ((cubeCompare && i == 4) || (! cubeCompare && i == 3)) - lvalue = true; - break; - case glslang::EOpSparseTextureLod: - case glslang::EOpSparseTextureOffset: - if (i == 3) - lvalue = true; - break; -#endif case glslang::EOpSparseTextureFetch: if ((sampler.dim != glslang::EsdRect && i == 3) || (sampler.dim == glslang::EsdRect && i == 2)) lvalue = true; @@ -3915,7 +5162,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((sampler.dim != glslang::EsdRect && i == 4) || (sampler.dim == glslang::EsdRect && i == 3)) lvalue = true; break; -#ifdef AMD_EXTENSIONS case glslang::EOpSparseTextureLodOffset: case glslang::EOpSparseTextureGrad: case glslang::EOpSparseTextureOffsetClamp: @@ -3931,23 +5177,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((f16ShadowCompare && i == 7) || (! f16ShadowCompare && i == 6)) lvalue = true; break; -#else - case glslang::EOpSparseTextureLodOffset: - case glslang::EOpSparseTextureGrad: - case glslang::EOpSparseTextureOffsetClamp: - if (i == 4) - lvalue = true; - break; - case glslang::EOpSparseTextureGradOffset: - case glslang::EOpSparseTextureGradClamp: - if (i == 5) - lvalue = true; - break; - case glslang::EOpSparseTextureGradOffsetClamp: - if (i == 6) - lvalue = true; - break; -#endif case glslang::EOpSparseTextureGather: if ((sampler.shadow && i == 3) || (! sampler.shadow && i == 2)) lvalue = true; @@ -3957,7 +5186,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((sampler.shadow && i == 4) || (! sampler.shadow && i == 3)) lvalue = true; break; -#ifdef AMD_EXTENSIONS case glslang::EOpSparseTextureGatherLod: if (i == 3) lvalue = true; @@ -3971,8 +5199,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if (i == 3) lvalue = true; break; -#endif -#ifdef NV_EXTENSIONS case glslang::EOpImageSampleFootprintNV: if (i == 4) lvalue = true; @@ -3990,14 +5216,18 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if (i == 7) lvalue = true; break; -#endif default: break; } - if (lvalue) - arguments.push_back(builder.accessChainGetLValue()); - else + if (lvalue) { + spv::Id lvalue_id = builder.accessChainGetLValue(); + arguments.push_back(lvalue_id); + lvalueCoherentFlags = builder.getAccessChain().coherentFlags; + builder.addDecoration(lvalue_id, TranslateNonUniformDecoration(lvalueCoherentFlags)); + lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType()); + } else +#endif arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType())); } } @@ -4018,21 +5248,36 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // Process a GLSL texturing op (will be SPV image) - const glslang::TType &imageType = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType() - : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType(); + const glslang::TType &imageType = node->getAsAggregate() + ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType() + : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType(); const glslang::TSampler sampler = imageType.getSampler(); -#ifdef AMD_EXTENSIONS +#ifdef GLSLANG_WEB + const bool f16ShadowCompare = false; +#else bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate()) - ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16 - : false; + ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16 + : false; #endif + const auto signExtensionMask = [&]() { + if (builder.getSpvVersion() >= spv::Spv_1_4) { + if (sampler.type == glslang::EbtUint) + return spv::ImageOperandsZeroExtendMask; + else if (sampler.type == glslang::EbtInt) + return spv::ImageOperandsSignExtendMask; + } + return spv::ImageOperandsMaskNone; + }; + + spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; + std::vector arguments; if (node->getAsAggregate()) - translateArguments(*node->getAsAggregate(), arguments); + translateArguments(*node->getAsAggregate(), arguments, lvalueCoherentFlags); else translateArguments(*node->getAsUnaryNode(), arguments); - spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); + spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); spv::Builder::TextureParameters params = { }; params.sampler = arguments[0]; @@ -4042,12 +5287,15 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO const bool isUnsignedResult = node->getType().getBasicType() == glslang::EbtUint; + if (builder.isSampledImage(params.sampler) && + ((cracked.query && node->getOp() != glslang::EOpTextureQueryLod) || cracked.fragMask || cracked.fetch)) { + params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler); + if (imageType.getQualifier().isNonUniform()) { + builder.addDecoration(params.sampler, spv::DecorationNonUniformEXT); + } + } // Check for queries if (cracked.query) { - // OpImageQueryLod works on a sampled image, for other queries the image has to be extracted first - if (node->getOp() != glslang::EOpTextureQueryLod && builder.isSampledImage(params.sampler)) - params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler); - switch (node->getOp()) { case glslang::EOpImageQuerySize: case glslang::EOpTextureQuerySize: @@ -4056,6 +5304,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO return builder.createTextureQueryCall(spv::OpImageQuerySizeLod, params, isUnsignedResult); } else return builder.createTextureQueryCall(spv::OpImageQuerySize, params, isUnsignedResult); +#ifndef GLSLANG_WEB case glslang::EOpImageQuerySamples: case glslang::EOpTextureQuerySamples: return builder.createTextureQueryCall(spv::OpImageQuerySamples, params, isUnsignedResult); @@ -4066,6 +5315,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO return builder.createTextureQueryCall(spv::OpImageQueryLevels, params, isUnsignedResult); case glslang::EOpSparseTexelsResident: return builder.createUnaryOp(spv::OpImageSparseTexelsResident, builder.makeBoolType(), arguments[0]); +#endif default: assert(0); break; @@ -4074,7 +5324,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO int components = node->getType().getVectorSize(); - if (node->getOp() == glslang::EOpTextureFetch) { + if (node->getOp() == glslang::EOpImageLoad || + node->getOp() == glslang::EOpImageLoadLod || + node->getOp() == glslang::EOpTextureFetch || + node->getOp() == glslang::EOpTextureFetchOffset) { // These must produce 4 components, per SPIR-V spec. We'll add a conversion constructor if needed. // This will only happen through the HLSL path for operator[], so we do not have to handle e.g. // the EOpTexture/Proj/Lod/etc family. It would be harmless to do so, but would need more logic @@ -4105,11 +5358,17 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO spv::IdImmediate coord = { true, builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps) }; operands.push_back(coord); - if (sampler.ms) { - spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask }; + spv::IdImmediate imageOperands = { false, spv::ImageOperandsMaskNone }; + imageOperands.word = imageOperands.word | signExtensionMask(); + if (sampler.isMultiSample()) { + imageOperands.word = imageOperands.word | spv::ImageOperandsSampleMask; + } + if (imageOperands.word != spv::ImageOperandsMaskNone) { operands.push_back(imageOperands); - spv::IdImmediate imageOperand = { true, *(opIt++) }; - operands.push_back(imageOperand); + if (sampler.isMultiSample()) { + spv::IdImmediate imageOperand = { true, *(opIt++) }; + operands.push_back(imageOperand); + } } spv::Id result = builder.createOp(spv::OpImageRead, resultType(), operands); builder.setPrecision(result, precision); @@ -4118,25 +5377,20 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO spv::IdImmediate coord = { true, *(opIt++) }; operands.push_back(coord); -#ifdef AMD_EXTENSIONS if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) { -#else - if (node->getOp() == glslang::EOpImageLoad) { -#endif spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; - if (sampler.ms) { + if (sampler.isMultiSample()) { mask = mask | spv::ImageOperandsSampleMask; } -#ifdef AMD_EXTENSIONS if (cracked.lod) { builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod); builder.addCapability(spv::CapabilityImageReadWriteLodAMD); mask = mask | spv::ImageOperandsLodMask; } -#endif mask = mask | TranslateImageOperands(TranslateCoherent(imageType)); mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask); - if (mask) { + mask = mask | signExtensionMask(); + if (mask != spv::ImageOperandsMaskNone) { spv::IdImmediate imageOperands = { false, (unsigned int)mask }; operands.push_back(imageOperands); } @@ -4144,14 +5398,13 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO spv::IdImmediate imageOperand = { true, *opIt++ }; operands.push_back(imageOperand); } -#ifdef AMD_EXTENSIONS if (mask & spv::ImageOperandsLodMask) { spv::IdImmediate imageOperand = { true, *opIt++ }; operands.push_back(imageOperand); } -#endif if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) { - spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) }; + spv::IdImmediate imageOperand = { true, + builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) }; operands.push_back(imageOperand); } @@ -4166,18 +5419,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO result[0] = builder.createConstructor(precision, result, convertGlslangToSpvType(node->getType())); return result[0]; -#ifdef AMD_EXTENSIONS } else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod) { -#else - } else if (node->getOp() == glslang::EOpImageStore) { -#endif // Push the texel value before the operands -#ifdef AMD_EXTENSIONS - if (sampler.ms || cracked.lod) { -#else - if (sampler.ms) { -#endif + if (sampler.isMultiSample() || cracked.lod) { spv::IdImmediate texel = { true, *(opIt + 1) }; operands.push_back(texel); } else { @@ -4186,19 +5431,18 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; - if (sampler.ms) { + if (sampler.isMultiSample()) { mask = mask | spv::ImageOperandsSampleMask; } -#ifdef AMD_EXTENSIONS if (cracked.lod) { builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod); builder.addCapability(spv::CapabilityImageReadWriteLodAMD); mask = mask | spv::ImageOperandsLodMask; } -#endif mask = mask | TranslateImageOperands(TranslateCoherent(imageType)); mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelVisibleKHRMask); - if (mask) { + mask = mask | signExtensionMask(); + if (mask != spv::ImageOperandsMaskNone) { spv::IdImmediate imageOperands = { false, (unsigned int)mask }; operands.push_back(imageOperands); } @@ -4206,14 +5450,13 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO spv::IdImmediate imageOperand = { true, *opIt++ }; operands.push_back(imageOperand); } -#ifdef AMD_EXTENSIONS if (mask & spv::ImageOperandsLodMask) { spv::IdImmediate imageOperand = { true, *opIt++ }; operands.push_back(imageOperand); } -#endif if (mask & spv::ImageOperandsMakeTexelAvailableKHRMask) { - spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) }; + spv::IdImmediate imageOperand = { true, + builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) }; operands.push_back(imageOperand); } @@ -4221,30 +5464,26 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown) builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat); return spv::NoResult; -#ifdef AMD_EXTENSIONS - } else if (node->getOp() == glslang::EOpSparseImageLoad || node->getOp() == glslang::EOpSparseImageLoadLod) { -#else - } else if (node->getOp() == glslang::EOpSparseImageLoad) { -#endif + } else if (node->getOp() == glslang::EOpSparseImageLoad || + node->getOp() == glslang::EOpSparseImageLoadLod) { builder.addCapability(spv::CapabilitySparseResidency); if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown) builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat); spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; - if (sampler.ms) { + if (sampler.isMultiSample()) { mask = mask | spv::ImageOperandsSampleMask; } -#ifdef AMD_EXTENSIONS if (cracked.lod) { builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod); builder.addCapability(spv::CapabilityImageReadWriteLodAMD); mask = mask | spv::ImageOperandsLodMask; } -#endif mask = mask | TranslateImageOperands(TranslateCoherent(imageType)); mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask); - if (mask) { + mask = mask | signExtensionMask(); + if (mask != spv::ImageOperandsMaskNone) { spv::IdImmediate imageOperands = { false, (unsigned int)mask }; operands.push_back(imageOperands); } @@ -4252,14 +5491,13 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO spv::IdImmediate imageOperand = { true, *opIt++ }; operands.push_back(imageOperand); } -#ifdef AMD_EXTENSIONS if (mask & spv::ImageOperandsLodMask) { spv::IdImmediate imageOperand = { true, *opIt++ }; operands.push_back(imageOperand); } -#endif if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) { - spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) }; + spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope( + TranslateCoherent(imageType))) }; operands.push_back(imageOperand); } @@ -4280,29 +5518,33 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // GLSL "IMAGE_PARAMS" will involve in constructing an image texel pointer and this pointer, // as the first source operand, is required by SPIR-V atomic operations. // For non-MS, the sample value should be 0 - spv::IdImmediate sample = { true, sampler.ms ? *(opIt++) : builder.makeUintConstant(0) }; + spv::IdImmediate sample = { true, sampler.isMultiSample() ? *(opIt++) : builder.makeUintConstant(0) }; operands.push_back(sample); spv::Id resultTypeId; // imageAtomicStore has a void return type so base the pointer type on // the type of the value operand. if (node->getOp() == glslang::EOpImageAtomicStore) { - resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(operands[2].word)); + resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(*opIt)); } else { resultTypeId = builder.makePointer(spv::StorageClassImage, resultType()); } spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands); + if (imageType.getQualifier().nonUniform) { + builder.addDecoration(pointer, spv::DecorationNonUniformEXT); + } std::vector operands; operands.push_back(pointer); for (; opIt != arguments.end(); ++opIt) operands.push_back(*opIt); - return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType()); + return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), + lvalueCoherentFlags); } } -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB // Check for fragment mask functions other than queries if (cracked.fragMask) { assert(sampler.ms); @@ -4310,10 +5552,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO auto opIt = arguments.begin(); std::vector operands; - // Extract the image if necessary - if (builder.isSampledImage(params.sampler)) - params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler); - operands.push_back(params.sampler); ++opIt; @@ -4323,7 +5561,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO std::vector comps; comps.push_back(zero); comps.push_back(zero); - operands.push_back(builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps)); + operands.push_back(builder.makeCompositeConstant( + builder.makeVectorType(builder.makeIntType(32), 2), comps)); } for (; opIt != arguments.end(); ++opIt) @@ -4343,57 +5582,37 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // Check for texture functions other than queries bool sparse = node->isSparseTexture(); -#ifdef NV_EXTENSIONS bool imageFootprint = node->isImageFootprint(); -#endif - - bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow; + bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.isArrayed() && sampler.isShadow(); // check for bias argument bool bias = false; -#ifdef AMD_EXTENSIONS if (! cracked.lod && ! cracked.grad && ! cracked.fetch && ! cubeCompare) { -#else - if (! cracked.lod && ! cracked.gather && ! cracked.grad && ! cracked.fetch && ! cubeCompare) { -#endif int nonBiasArgCount = 2; -#ifdef AMD_EXTENSIONS if (cracked.gather) ++nonBiasArgCount; // comp argument should be present when bias argument is present if (f16ShadowCompare) ++nonBiasArgCount; -#endif if (cracked.offset) ++nonBiasArgCount; -#ifdef AMD_EXTENSIONS else if (cracked.offsets) ++nonBiasArgCount; -#endif if (cracked.grad) nonBiasArgCount += 2; if (cracked.lodClamp) ++nonBiasArgCount; if (sparse) ++nonBiasArgCount; -#ifdef NV_EXTENSIONS if (imageFootprint) //Following three extra arguments // int granularity, bool coarse, out gl_TextureFootprint2DNV footprint nonBiasArgCount += 3; -#endif if ((int)arguments.size() > nonBiasArgCount) bias = true; } - // See if the sampler param should really be just the SPV image part - if (cracked.fetch) { - // a fetch needs to have the image extracted first - if (builder.isSampledImage(params.sampler)) - params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler); - } - -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB if (cracked.gather) { const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions(); if (bias || cracked.lod || @@ -4411,11 +5630,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO bool noImplicitLod = false; // sort out where Dref is coming from -#ifdef AMD_EXTENSIONS if (cubeCompare || f16ShadowCompare) { -#else - if (cubeCompare) { -#endif params.Dref = arguments[2]; ++extraArgs; } else if (sampler.shadow && cracked.gather) { @@ -4429,26 +5644,23 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO else dRefComp = builder.getNumComponents(params.coords) - 1; indexes.push_back(dRefComp); - params.Dref = builder.createCompositeExtract(params.coords, builder.getScalarTypeId(builder.getTypeId(params.coords)), indexes); + params.Dref = builder.createCompositeExtract(params.coords, + builder.getScalarTypeId(builder.getTypeId(params.coords)), indexes); } // lod if (cracked.lod) { params.lod = arguments[2 + extraArgs]; ++extraArgs; - } else if (glslangIntermediate->getStage() != EShLangFragment -#ifdef NV_EXTENSIONS - // NV_compute_shader_derivatives layout qualifiers allow for implicit LODs - && !(glslangIntermediate->getStage() == EShLangCompute && - (glslangIntermediate->getLayoutDerivativeModeNone() != glslang::LayoutDerivativeNone)) -#endif - ) { + } else if (glslangIntermediate->getStage() != EShLangFragment && + !(glslangIntermediate->getStage() == EShLangCompute && + glslangIntermediate->hasLayoutDerivativeModeNone())) { // we need to invent the default lod for an explicit lod instruction for a non-fragment stage noImplicitLod = true; } // multisample - if (sampler.ms) { + if (sampler.isMultiSample()) { params.sample = arguments[2 + extraArgs]; // For MS, "sample" should be specified ++extraArgs; } @@ -4469,6 +5681,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ++extraArgs; } +#ifndef GLSLANG_WEB // lod clamp if (cracked.lodClamp) { params.lodClamp = arguments[2 + extraArgs]; @@ -4479,7 +5692,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO params.texelOut = arguments[2 + extraArgs]; ++extraArgs; } - // gather component if (cracked.gather && ! sampler.shadow) { // default component is 0, if missing, otherwise an argument @@ -4489,7 +5701,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } else params.component = builder.makeIntConstant(0); } -#ifdef NV_EXTENSIONS spv::Id resultStruct = spv::NoResult; if (imageFootprint) { //Following three extra arguments @@ -4506,7 +5717,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ++extraArgs; } -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB if (imageFootprint) { builder.addExtension(spv::E_SPV_NV_shader_image_footprint); builder.addCapability(spv::CapabilityImageFootprintNV); @@ -4546,7 +5757,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO spv::Id resType = builder.makeStructType(members, "ResType"); //call ImageFootprintNV - spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params); + spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj, + cracked.gather, noImplicitLod, params, signExtensionMask()); //copy resType (SPIR-V type) to resultStructType(OpenGL type) for (int i = 0; i < 5; i++) { @@ -4558,7 +5770,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO flags.clear(); builder.accessChainPush(builder.makeIntConstant(i), flags, 0); - builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1)); + builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), + i+1), TranslateNonUniformDecoration(imageType.getQualifier())); } return builder.createCompositeExtract(res, resultType(), 0); } @@ -4581,13 +5794,13 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // copy the projective coordinate if we have to if (projTargetComp != projSourceComp) { spv::Id projComp = builder.createCompositeExtract(params.coords, - builder.getScalarTypeId(builder.getTypeId(params.coords)), - projSourceComp); + builder.getScalarTypeId(builder.getTypeId(params.coords)), projSourceComp); params.coords = builder.createCompositeInsert(projComp, params.coords, - builder.getTypeId(params.coords), projTargetComp); + builder.getTypeId(params.coords), projTargetComp); } } +#ifndef GLSLANG_WEB // nonprivate if (imageType.getQualifier().nonprivate) { params.nonprivate = true; @@ -4597,9 +5810,11 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO if (imageType.getQualifier().volatil) { params.volatil = true; } +#endif std::vector result( 1, - builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params) + builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, + noImplicitLod, params, signExtensionMask()) ); if (components != node->getType().getVectorSize()) @@ -4661,7 +5876,8 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ++lValueCount; } else if (writableParam(qualifiers[a])) { // need space to hold the copy - arg = builder.createVariable(spv::StorageClassFunction, builder.getContainedTypeId(function->getParamType(a)), "param"); + arg = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, + builder.getContainedTypeId(function->getParamType(a)), "param"); if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) { // need to copy the input into output space builder.setAccessChain(lValues[lValueCount]); @@ -4673,12 +5889,14 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ++lValueCount; } else { // process r-value, which involves a copy for a type mismatch - if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a])) { - spv::Id argCopy = builder.createVariable(spv::StorageClassFunction, function->getParamType(a), "arg"); + if (function->getParamType(a) != builder.getTypeId(rValues[rValueCount]) || + TranslatePrecisionDecoration(*argTypes[a]) != function->getParamPrecision(a)) + { + spv::Id argCopy = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, function->getParamType(a), "arg"); builder.clearAccessChain(); builder.setAccessChainLValue(argCopy); multiTypeStore(*argTypes[a], rValues[rValueCount]); - arg = builder.createLoad(argCopy); + arg = builder.createLoad(argCopy, function->getParamPrecision(a)); } else arg = rValues[rValueCount]; ++rValueCount; @@ -4689,6 +5907,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg // 3. Make the call. spv::Id result = builder.createFunctionCall(function, spvArgs); builder.setPrecision(result, TranslatePrecisionDecoration(node->getType())); + builder.addDecoration(result, TranslateNonUniformDecoration(node->getType().getQualifier())); // 4. Copy back out an "out" arguments. lValueCount = 0; @@ -4697,7 +5916,8 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ++lValueCount; else if (writableParam(qualifiers[a])) { if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) { - spv::Id copy = builder.createLoad(spvArgs[a]); + spv::Id copy = builder.createLoad(spvArgs[a], spv::NoPrecision); + builder.addDecoration(copy, TranslateNonUniformDecoration(argTypes[a]->getQualifier())); builder.setAccessChain(lValues[lValueCount]); multiTypeStore(*argTypes[a], copy); } @@ -4830,6 +6050,30 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD binOp = spv::OpLogicalNotEqual; break; + case glslang::EOpAbsDifference: + binOp = isUnsigned ? spv::OpAbsUSubINTEL : spv::OpAbsISubINTEL; + break; + + case glslang::EOpAddSaturate: + binOp = isUnsigned ? spv::OpUAddSatINTEL : spv::OpIAddSatINTEL; + break; + + case glslang::EOpSubSaturate: + binOp = isUnsigned ? spv::OpUSubSatINTEL : spv::OpISubSatINTEL; + break; + + case glslang::EOpAverage: + binOp = isUnsigned ? spv::OpUAverageINTEL : spv::OpIAverageINTEL; + break; + + case glslang::EOpAverageRounded: + binOp = isUnsigned ? spv::OpUAverageRoundedINTEL : spv::OpIAverageRoundedINTEL; + break; + + case glslang::EOpMul32x16: + binOp = isUnsigned ? spv::OpUMul32x16INTEL : spv::OpIMul32x16INTEL; + break; + case glslang::EOpLessThan: case glslang::EOpGreaterThan: case glslang::EOpLessThanEqual: @@ -4847,7 +6091,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD // handle mapped binary operations (should be non-comparison) if (binOp != spv::OpNop) { assert(comparison == false); - if (builder.isMatrix(left) || builder.isMatrix(right)) + if (builder.isMatrix(left) || builder.isMatrix(right) || + builder.isCooperativeMatrix(left) || builder.isCooperativeMatrix(right)) return createBinaryMatrixOperation(binOp, decorations, typeId, left, right); // No matrix involved; make both operands be the same number of components, if needed @@ -4855,8 +6100,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD builder.promoteScalar(decorations.precision, left, right); spv::Id result = builder.createBinOp(binOp, typeId, left, right); - builder.addDecoration(result, decorations.noContraction); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNoContraction(builder, result); + decorations.addNonUniform(builder, result); return builder.setPrecision(result, decorations.precision); } @@ -4868,7 +6113,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD if (reduceComparison && (op == glslang::EOpEqual || op == glslang::EOpNotEqual) && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) { spv::Id result = builder.createCompositeCompare(decorations.precision, left, right, op == glslang::EOpEqual); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); return result; } @@ -4917,7 +6162,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD case glslang::EOpNotEqual: case glslang::EOpVectorNotEqual: if (isFloat) - binOp = spv::OpFOrdNotEqual; + binOp = spv::OpFUnordNotEqual; else if (isBool) binOp = spv::OpLogicalNotEqual; else @@ -4929,8 +6174,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD if (binOp != spv::OpNop) { spv::Id result = builder.createBinOp(binOp, typeId, left, right); - builder.addDecoration(result, decorations.noContraction); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNoContraction(builder, result); + decorations.addNonUniform(builder, result); return builder.setPrecision(result, decorations.precision); } @@ -4968,7 +6213,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora firstClass = false; break; case spv::OpMatrixTimesScalar: - if (builder.isMatrix(right)) + if (builder.isMatrix(right) || builder.isCooperativeMatrix(right)) std::swap(left, right); assert(builder.isScalar(right)); break; @@ -4989,10 +6234,13 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora break; } + if (builder.isCooperativeMatrix(left) || builder.isCooperativeMatrix(right)) + firstClass = true; + if (firstClass) { spv::Id result = builder.createBinOp(op, typeId, left, right); - builder.addDecoration(result, decorations.noContraction); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNoContraction(builder, result); + decorations.addNonUniform(builder, result); return builder.setPrecision(result, decorations.precision); } @@ -5031,14 +6279,14 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora spv::Id leftVec = leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec; spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec; spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec); - builder.addDecoration(result, decorations.noContraction); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNoContraction(builder, result); + decorations.addNonUniform(builder, result); results.push_back(builder.setPrecision(result, decorations.precision)); } // put the pieces together spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); return result; } default: @@ -5048,7 +6296,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora } spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId, - spv::Id operand, glslang::TBasicType typeProxy) + spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { spv::Op unaryOp = spv::OpNop; int extBuiltins = -1; @@ -5216,6 +6464,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpUnpackHalf2x16: libCall = spv::GLSLstd450UnpackHalf2x16; break; +#ifndef GLSLANG_WEB case glslang::EOpPackSnorm4x8: libCall = spv::GLSLstd450PackSnorm4x8; break; @@ -5234,6 +6483,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpUnpackDouble2x32: libCall = spv::GLSLstd450UnpackDouble2x32; break; +#endif case glslang::EOpPackInt2x32: case glslang::EOpUnpackInt2x32: @@ -5267,31 +6517,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpFwidth: unaryOp = spv::OpFwidth; break; - case glslang::EOpDPdxFine: - unaryOp = spv::OpDPdxFine; - break; - case glslang::EOpDPdyFine: - unaryOp = spv::OpDPdyFine; - break; - case glslang::EOpFwidthFine: - unaryOp = spv::OpFwidthFine; - break; - case glslang::EOpDPdxCoarse: - unaryOp = spv::OpDPdxCoarse; - break; - case glslang::EOpDPdyCoarse: - unaryOp = spv::OpDPdyCoarse; - break; - case glslang::EOpFwidthCoarse: - unaryOp = spv::OpFwidthCoarse; - break; - case glslang::EOpInterpolateAtCentroid: -#ifdef AMD_EXTENSIONS - if (typeProxy == glslang::EbtFloat16) - builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); -#endif - libCall = spv::GLSLstd450InterpolateAtCentroid; - break; + case glslang::EOpAny: unaryOp = spv::OpAny; break; @@ -5312,6 +6538,48 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe libCall = spv::GLSLstd450SSign; break; +#ifndef GLSLANG_WEB + case glslang::EOpDPdxFine: + unaryOp = spv::OpDPdxFine; + break; + case glslang::EOpDPdyFine: + unaryOp = spv::OpDPdyFine; + break; + case glslang::EOpFwidthFine: + unaryOp = spv::OpFwidthFine; + break; + case glslang::EOpDPdxCoarse: + unaryOp = spv::OpDPdxCoarse; + break; + case glslang::EOpDPdyCoarse: + unaryOp = spv::OpDPdyCoarse; + break; + case glslang::EOpFwidthCoarse: + unaryOp = spv::OpFwidthCoarse; + break; + case glslang::EOpRayQueryProceed: + unaryOp = spv::OpRayQueryProceedKHR; + break; + case glslang::EOpRayQueryGetRayTMin: + unaryOp = spv::OpRayQueryGetRayTMinKHR; + break; + case glslang::EOpRayQueryGetRayFlags: + unaryOp = spv::OpRayQueryGetRayFlagsKHR; + break; + case glslang::EOpRayQueryGetWorldRayOrigin: + unaryOp = spv::OpRayQueryGetWorldRayOriginKHR; + break; + case glslang::EOpRayQueryGetWorldRayDirection: + unaryOp = spv::OpRayQueryGetWorldRayDirectionKHR; + break; + case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque: + unaryOp = spv::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR; + break; + case glslang::EOpInterpolateAtCentroid: + if (typeProxy == glslang::EbtFloat16) + builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); + libCall = spv::GLSLstd450InterpolateAtCentroid; + break; case glslang::EOpAtomicCounterIncrement: case glslang::EOpAtomicCounterDecrement: case glslang::EOpAtomicCounter: @@ -5319,7 +6587,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe // Handle all of the atomics in one place, in createAtomicOperation() std::vector operands; operands.push_back(operand); - return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy); + return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy, lvalueCoherentFlags); } case glslang::EOpBitFieldReverse: @@ -5338,12 +6606,23 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe libCall = spv::GLSLstd450FindSMsb; break; + case glslang::EOpCountLeadingZeros: + builder.addCapability(spv::CapabilityIntegerFunctions2INTEL); + builder.addExtension("SPV_INTEL_shader_integer_functions2"); + unaryOp = spv::OpUCountLeadingZerosINTEL; + break; + + case glslang::EOpCountTrailingZeros: + builder.addCapability(spv::CapabilityIntegerFunctions2INTEL); + builder.addExtension("SPV_INTEL_shader_integer_functions2"); + unaryOp = spv::OpUCountTrailingZerosINTEL; + break; + case glslang::EOpBallot: case glslang::EOpReadFirstInvocation: case glslang::EOpAnyInvocation: case glslang::EOpAllInvocations: case glslang::EOpAllInvocationsEqual: -#ifdef AMD_EXTENSIONS case glslang::EOpMinInvocations: case glslang::EOpMaxInvocations: case glslang::EOpAddInvocations: @@ -5362,7 +6641,6 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpMinInvocationsExclusiveScanNonUniform: case glslang::EOpMaxInvocationsExclusiveScanNonUniform: case glslang::EOpAddInvocationsExclusiveScanNonUniform: -#endif { std::vector operands; operands.push_back(operand); @@ -5407,7 +6685,6 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe operands.push_back(operand); return createSubgroupOperation(op, typeId, operands, typeProxy); } -#ifdef AMD_EXTENSIONS case glslang::EOpMbcnt: extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot); libCall = spv::MbcntAMD; @@ -5422,15 +6699,23 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe extBuiltins = getExtBuiltins(spv::E_SPV_AMD_gcn_shader); libCall = spv::CubeFaceCoordAMD; break; -#endif -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartition: unaryOp = spv::OpGroupNonUniformPartitionNV; break; -#endif case glslang::EOpConstructReference: unaryOp = spv::OpBitcast; break; + + case glslang::EOpConvUint64ToAccStruct: + case glslang::EOpConvUvec2ToAccStruct: + unaryOp = spv::OpConvertUToAccelerationStructureKHR; + break; +#endif + + case glslang::EOpCopyObject: + unaryOp = spv::OpCopyObject; + break; + default: return 0; } @@ -5444,8 +6729,8 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe id = builder.createUnaryOp(unaryOp, typeId, operand); } - builder.addDecoration(id, decorations.noContraction); - builder.addDecoration(id, decorations.nonUniform); + decorations.addNoContraction(builder, id); + decorations.addNonUniform(builder, id); return builder.setPrecision(id, decorations.precision); } @@ -5473,14 +6758,14 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, OpDecorat indexes.push_back(c); spv::Id srcVec = builder.createCompositeExtract(operand, srcVecType, indexes); spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec); - builder.addDecoration(destVec, decorations.noContraction); - builder.addDecoration(destVec, decorations.nonUniform); + decorations.addNoContraction(builder, destVec); + decorations.addNonUniform(builder, destVec); results.push_back(builder.setPrecision(destVec, decorations.precision)); } // put the pieces together spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); return result; } @@ -5572,110 +6857,49 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora int vectorSize = builder.isVectorType(destType) ? builder.getNumTypeComponents(destType) : 0; switch (op) { - case glslang::EOpConvInt8ToBool: - case glslang::EOpConvUint8ToBool: - zero = builder.makeUint8Constant(0); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); - case glslang::EOpConvInt16ToBool: - case glslang::EOpConvUint16ToBool: - zero = builder.makeUint16Constant(0); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); case glslang::EOpConvIntToBool: case glslang::EOpConvUintToBool: zero = builder.makeUintConstant(0); zero = makeSmearedConstant(zero, vectorSize); return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); - case glslang::EOpConvInt64ToBool: - case glslang::EOpConvUint64ToBool: - zero = builder.makeUint64Constant(0); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); - case glslang::EOpConvFloatToBool: zero = builder.makeFloatConstant(0.0F); zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); - - case glslang::EOpConvDoubleToBool: - zero = builder.makeDoubleConstant(0.0); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); - - case glslang::EOpConvFloat16ToBool: - zero = builder.makeFloat16Constant(0.0F); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); - + return builder.createBinOp(spv::OpFUnordNotEqual, destType, operand, zero); case glslang::EOpConvBoolToFloat: convOp = spv::OpSelect; zero = builder.makeFloatConstant(0.0F); one = builder.makeFloatConstant(1.0F); break; - case glslang::EOpConvBoolToDouble: - convOp = spv::OpSelect; - zero = builder.makeDoubleConstant(0.0); - one = builder.makeDoubleConstant(1.0); - break; - - case glslang::EOpConvBoolToFloat16: - convOp = spv::OpSelect; - zero = builder.makeFloat16Constant(0.0F); - one = builder.makeFloat16Constant(1.0F); - break; - - case glslang::EOpConvBoolToInt8: - zero = builder.makeInt8Constant(0); - one = builder.makeInt8Constant(1); - convOp = spv::OpSelect; - break; - - case glslang::EOpConvBoolToUint8: - zero = builder.makeUint8Constant(0); - one = builder.makeUint8Constant(1); - convOp = spv::OpSelect; - break; - - case glslang::EOpConvBoolToInt16: - zero = builder.makeInt16Constant(0); - one = builder.makeInt16Constant(1); - convOp = spv::OpSelect; - break; - - case glslang::EOpConvBoolToUint16: - zero = builder.makeUint16Constant(0); - one = builder.makeUint16Constant(1); - convOp = spv::OpSelect; - break; - case glslang::EOpConvBoolToInt: case glslang::EOpConvBoolToInt64: - if (op == glslang::EOpConvBoolToInt64) +#ifndef GLSLANG_WEB + if (op == glslang::EOpConvBoolToInt64) { zero = builder.makeInt64Constant(0); - else - zero = builder.makeIntConstant(0); - - if (op == glslang::EOpConvBoolToInt64) one = builder.makeInt64Constant(1); - else + } else +#endif + { + zero = builder.makeIntConstant(0); one = builder.makeIntConstant(1); + } convOp = spv::OpSelect; break; case glslang::EOpConvBoolToUint: case glslang::EOpConvBoolToUint64: - if (op == glslang::EOpConvBoolToUint64) +#ifndef GLSLANG_WEB + if (op == glslang::EOpConvBoolToUint64) { zero = builder.makeUint64Constant(0); - else - zero = builder.makeUintConstant(0); - - if (op == glslang::EOpConvBoolToUint64) one = builder.makeUint64Constant(1); - else + } else +#endif + { + zero = builder.makeUintConstant(0); one = builder.makeUintConstant(1); + } convOp = spv::OpSelect; break; @@ -5710,17 +6934,6 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora convOp = spv::OpConvertUToF; break; - case glslang::EOpConvDoubleToFloat: - case glslang::EOpConvFloatToDouble: - case glslang::EOpConvDoubleToFloat16: - case glslang::EOpConvFloat16ToDouble: - case glslang::EOpConvFloatToFloat16: - case glslang::EOpConvFloat16ToFloat: - convOp = spv::OpFConvert; - if (builder.isMatrixType(destType)) - return createUnaryMatrixOperation(convOp, decorations, destType, operand, typeProxy); - break; - case glslang::EOpConvFloat16ToInt8: case glslang::EOpConvFloatToInt8: case glslang::EOpConvDoubleToInt8: @@ -5746,13 +6959,16 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvInt64ToUint64: if (builder.isInSpecConstCodeGenMode()) { // Build zero scalar or vector for OpIAdd. +#ifndef GLSLANG_WEB if(op == glslang::EOpConvUint8ToInt8 || op == glslang::EOpConvInt8ToUint8) { zero = builder.makeUint8Constant(0); } else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16) { zero = builder.makeUint16Constant(0); } else if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64) { zero = builder.makeUint64Constant(0); - } else { + } else +#endif + { zero = builder.makeUintConstant(0); } zero = makeSmearedConstant(zero, vectorSize); @@ -5779,6 +6995,71 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora convOp = spv::OpConvertFToU; break; +#ifndef GLSLANG_WEB + case glslang::EOpConvInt8ToBool: + case glslang::EOpConvUint8ToBool: + zero = builder.makeUint8Constant(0); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); + case glslang::EOpConvInt16ToBool: + case glslang::EOpConvUint16ToBool: + zero = builder.makeUint16Constant(0); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); + case glslang::EOpConvInt64ToBool: + case glslang::EOpConvUint64ToBool: + zero = builder.makeUint64Constant(0); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); + case glslang::EOpConvDoubleToBool: + zero = builder.makeDoubleConstant(0.0); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpFUnordNotEqual, destType, operand, zero); + case glslang::EOpConvFloat16ToBool: + zero = builder.makeFloat16Constant(0.0F); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpFUnordNotEqual, destType, operand, zero); + case glslang::EOpConvBoolToDouble: + convOp = spv::OpSelect; + zero = builder.makeDoubleConstant(0.0); + one = builder.makeDoubleConstant(1.0); + break; + case glslang::EOpConvBoolToFloat16: + convOp = spv::OpSelect; + zero = builder.makeFloat16Constant(0.0F); + one = builder.makeFloat16Constant(1.0F); + break; + case glslang::EOpConvBoolToInt8: + zero = builder.makeInt8Constant(0); + one = builder.makeInt8Constant(1); + convOp = spv::OpSelect; + break; + case glslang::EOpConvBoolToUint8: + zero = builder.makeUint8Constant(0); + one = builder.makeUint8Constant(1); + convOp = spv::OpSelect; + break; + case glslang::EOpConvBoolToInt16: + zero = builder.makeInt16Constant(0); + one = builder.makeInt16Constant(1); + convOp = spv::OpSelect; + break; + case glslang::EOpConvBoolToUint16: + zero = builder.makeUint16Constant(0); + one = builder.makeUint16Constant(1); + convOp = spv::OpSelect; + break; + case glslang::EOpConvDoubleToFloat: + case glslang::EOpConvFloatToDouble: + case glslang::EOpConvDoubleToFloat16: + case glslang::EOpConvFloat16ToDouble: + case glslang::EOpConvFloatToFloat16: + case glslang::EOpConvFloat16ToFloat: + convOp = spv::OpFConvert; + if (builder.isMatrixType(destType)) + return createUnaryMatrixOperation(convOp, decorations, destType, operand, typeProxy); + break; + case glslang::EOpConvInt8ToInt16: case glslang::EOpConvInt8ToInt: case glslang::EOpConvInt8ToInt64: @@ -5889,6 +7170,12 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvPtrToUint64: convOp = spv::OpConvertPtrToU; break; + case glslang::EOpConvPtrToUvec2: + case glslang::EOpConvUvec2ToPtr: + convOp = spv::OpBitcast; + break; +#endif + default: break; } @@ -5905,7 +7192,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora result = builder.createUnaryOp(convOp, destType, operand); result = builder.setPrecision(result, decorations.precision); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); return result; } @@ -5922,7 +7209,9 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector } // For glslang ops that map to SPV atomic opCodes -spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) +spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, + spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, + const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { spv::Op opCode = spv::OpNop; @@ -5931,19 +7220,58 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv case glslang::EOpImageAtomicAdd: case glslang::EOpAtomicCounterAdd: opCode = spv::OpAtomicIAdd; + if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) { + opCode = spv::OpAtomicFAddEXT; + builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add); + if (typeProxy == glslang::EbtFloat16) { + builder.addExtension(spv::E_SPV_EXT_shader_atomic_float16_add); + builder.addCapability(spv::CapabilityAtomicFloat16AddEXT); + } else if (typeProxy == glslang::EbtFloat) { + builder.addCapability(spv::CapabilityAtomicFloat32AddEXT); + } else { + builder.addCapability(spv::CapabilityAtomicFloat64AddEXT); + } + } break; + case glslang::EOpAtomicSubtract: case glslang::EOpAtomicCounterSubtract: opCode = spv::OpAtomicISub; break; case glslang::EOpAtomicMin: case glslang::EOpImageAtomicMin: case glslang::EOpAtomicCounterMin: - opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? spv::OpAtomicUMin : spv::OpAtomicSMin; + if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) { + opCode = spv::OpAtomicFMinEXT; + builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max); + if (typeProxy == glslang::EbtFloat16) + builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT); + else if (typeProxy == glslang::EbtFloat) + builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT); + else + builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT); + } else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) { + opCode = spv::OpAtomicUMin; + } else { + opCode = spv::OpAtomicSMin; + } break; case glslang::EOpAtomicMax: case glslang::EOpImageAtomicMax: case glslang::EOpAtomicCounterMax: - opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? spv::OpAtomicUMax : spv::OpAtomicSMax; + if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) { + opCode = spv::OpAtomicFMaxEXT; + builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max); + if (typeProxy == glslang::EbtFloat16) + builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT); + else if (typeProxy == glslang::EbtFloat) + builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT); + else + builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT); + } else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) { + opCode = spv::OpAtomicUMax; + } else { + opCode = spv::OpAtomicSMax; + } break; case glslang::EOpAtomicAnd: case glslang::EOpImageAtomicAnd: @@ -6008,7 +7336,10 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv scopeId = builder.makeUintConstant(spv::ScopeDevice); } // semantics default to relaxed - spv::Id semanticsId = builder.makeUintConstant(spv::MemorySemanticsMaskNone); + spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() && + glslangIntermediate->usingVulkanMemoryModel() ? + spv::MemorySemanticsVolatileMask : + spv::MemorySemanticsMaskNone); spv::Id semanticsId2 = semanticsId; pointerId = operands[0]; @@ -6019,26 +7350,37 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv valueId = operands[2]; if (operands.size() > 3) { scopeId = operands[3]; - semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[4]) | builder.getConstantScalar(operands[5])); - semanticsId2 = builder.makeUintConstant(builder.getConstantScalar(operands[6]) | builder.getConstantScalar(operands[7])); + semanticsId = builder.makeUintConstant( + builder.getConstantScalar(operands[4]) | builder.getConstantScalar(operands[5])); + semanticsId2 = builder.makeUintConstant( + builder.getConstantScalar(operands[6]) | builder.getConstantScalar(operands[7])); } } else if (opCode == spv::OpAtomicLoad) { if (operands.size() > 1) { scopeId = operands[1]; - semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3])); + semanticsId = builder.makeUintConstant( + builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3])); } } else { // atomic store or RMW valueId = operands[1]; if (operands.size() > 2) { scopeId = operands[2]; - semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4])); + semanticsId = builder.makeUintConstant + (builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4])); } } // Check for capabilities unsigned semanticsImmediate = builder.getConstantScalar(semanticsId) | builder.getConstantScalar(semanticsId2); - if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) { + if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | + spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsVolatileMask)) { + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + } + + if (builder.getConstantScalar(scopeId) == spv::ScopeQueueFamily) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } @@ -6074,12 +7416,11 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv } // Create group invocation operations. -spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) +spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, + std::vector& operands, glslang::TBasicType typeProxy) { -#ifdef AMD_EXTENSIONS bool isUnsigned = isTypeUnsignedInt(typeProxy); bool isFloat = isTypeFloat(typeProxy); -#endif spv::Op opCode = spv::OpNop; std::vector spvGroupOperands; @@ -6096,7 +7437,6 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op builder.addCapability(spv::CapabilitySubgroupVoteKHR); } else { builder.addCapability(spv::CapabilityGroups); -#ifdef AMD_EXTENSIONS if (op == glslang::EOpMinInvocationsNonUniform || op == glslang::EOpMaxInvocationsNonUniform || op == glslang::EOpAddInvocationsNonUniform || @@ -6107,9 +7447,7 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op op == glslang::EOpMaxInvocationsExclusiveScanNonUniform || op == glslang::EOpAddInvocationsExclusiveScanNonUniform) builder.addExtension(spv::E_SPV_AMD_shader_ballot); -#endif -#ifdef AMD_EXTENSIONS switch (op) { case glslang::EOpMinInvocations: case glslang::EOpMaxInvocations: @@ -6144,7 +7482,6 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op spv::IdImmediate groupOp = { false, (unsigned)groupOperation }; spvGroupOperands.push_back(groupOp); } -#endif } for (auto opIt = operands.begin(); opIt != operands.end(); ++opIt) { @@ -6191,7 +7528,6 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op builder.createCompositeConstruct(uvec2Type, components)); } -#ifdef AMD_EXTENSIONS case glslang::EOpMinInvocations: case glslang::EOpMaxInvocations: case glslang::EOpAddInvocations: @@ -6278,7 +7614,6 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op return CreateInvocationsVectorOperation(opCode, groupOperation, typeId, operands); break; -#endif default: logger->missingFunctionality("invocation operation"); return spv::NoResult; @@ -6292,20 +7627,15 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector& operands) { -#ifdef AMD_EXTENSIONS assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin || op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax || op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast || op == spv::OpSubgroupReadInvocationKHR || - op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD || op == spv::OpGroupSMinNonUniformAMD || - op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD || op == spv::OpGroupSMaxNonUniformAMD || + op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD || + op == spv::OpGroupSMinNonUniformAMD || + op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD || + op == spv::OpGroupSMaxNonUniformAMD || op == spv::OpGroupFAddNonUniformAMD || op == spv::OpGroupIAddNonUniformAMD); -#else - assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin || - op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax || - op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast || - op == spv::OpSubgroupReadInvocationKHR); -#endif // Handle group invocation operations scalar by scalar. // The result type is the same type as the original type. @@ -6429,7 +7759,6 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s builder.addCapability(spv::CapabilityGroupNonUniform); builder.addCapability(spv::CapabilityGroupNonUniformQuad); break; -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAdd: case glslang::EOpSubgroupPartitionedMul: case glslang::EOpSubgroupPartitionedMin: @@ -6454,12 +7783,12 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s builder.addExtension(spv::E_SPV_NV_shader_subgroup_partitioned); builder.addCapability(spv::CapabilityGroupNonUniformPartitionedNV); break; -#endif default: assert(0 && "Unhandled subgroup operation!"); } - const bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64; - const bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble; + + const bool isUnsigned = isTypeUnsignedInt(typeProxy); + const bool isFloat = isTypeFloat(typeProxy); const bool isBool = typeProxy == glslang::EbtBool; spv::Op opCode = spv::OpNop; @@ -6488,11 +7817,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveAdd: case glslang::EOpSubgroupExclusiveAdd: case glslang::EOpSubgroupClusteredAdd: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAdd: case glslang::EOpSubgroupPartitionedInclusiveAdd: case glslang::EOpSubgroupPartitionedExclusiveAdd: -#endif if (isFloat) { opCode = spv::OpGroupNonUniformFAdd; } else { @@ -6503,11 +7830,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveMul: case glslang::EOpSubgroupExclusiveMul: case glslang::EOpSubgroupClusteredMul: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedMul: case glslang::EOpSubgroupPartitionedInclusiveMul: case glslang::EOpSubgroupPartitionedExclusiveMul: -#endif if (isFloat) { opCode = spv::OpGroupNonUniformFMul; } else { @@ -6518,11 +7843,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveMin: case glslang::EOpSubgroupExclusiveMin: case glslang::EOpSubgroupClusteredMin: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedMin: case glslang::EOpSubgroupPartitionedInclusiveMin: case glslang::EOpSubgroupPartitionedExclusiveMin: -#endif if (isFloat) { opCode = spv::OpGroupNonUniformFMin; } else if (isUnsigned) { @@ -6535,11 +7858,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveMax: case glslang::EOpSubgroupExclusiveMax: case glslang::EOpSubgroupClusteredMax: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedMax: case glslang::EOpSubgroupPartitionedInclusiveMax: case glslang::EOpSubgroupPartitionedExclusiveMax: -#endif if (isFloat) { opCode = spv::OpGroupNonUniformFMax; } else if (isUnsigned) { @@ -6552,11 +7873,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveAnd: case glslang::EOpSubgroupExclusiveAnd: case glslang::EOpSubgroupClusteredAnd: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAnd: case glslang::EOpSubgroupPartitionedInclusiveAnd: case glslang::EOpSubgroupPartitionedExclusiveAnd: -#endif if (isBool) { opCode = spv::OpGroupNonUniformLogicalAnd; } else { @@ -6567,11 +7886,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveOr: case glslang::EOpSubgroupExclusiveOr: case glslang::EOpSubgroupClusteredOr: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedOr: case glslang::EOpSubgroupPartitionedInclusiveOr: case glslang::EOpSubgroupPartitionedExclusiveOr: -#endif if (isBool) { opCode = spv::OpGroupNonUniformLogicalOr; } else { @@ -6582,11 +7899,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveXor: case glslang::EOpSubgroupExclusiveXor: case glslang::EOpSubgroupClusteredXor: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedXor: case glslang::EOpSubgroupPartitionedInclusiveXor: case glslang::EOpSubgroupPartitionedExclusiveXor: -#endif if (isBool) { opCode = spv::OpGroupNonUniformLogicalXor; } else { @@ -6644,7 +7959,6 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupClusteredXor: groupOperation = spv::GroupOperationClusteredReduce; break; -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAdd: case glslang::EOpSubgroupPartitionedMul: case glslang::EOpSubgroupPartitionedMin: @@ -6672,7 +7986,6 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupPartitionedExclusiveXor: groupOperation = spv::GroupOperationPartitionedExclusiveScanNV; break; -#endif } // build the instruction @@ -6710,7 +8023,8 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s return builder.createOp(opCode, typeId, spvGroupOperands); } -spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) +spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, + spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) { bool isUnsigned = isTypeUnsignedInt(typeProxy); bool isFloat = isTypeFloat(typeProxy); @@ -6730,7 +8044,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: switch (op) { case glslang::EOpMin: if (isFloat) - libCall = spv::GLSLstd450FMin; + libCall = nanMinMaxClamp ? spv::GLSLstd450NMin : spv::GLSLstd450FMin; else if (isUnsigned) libCall = spv::GLSLstd450UMin; else @@ -6742,7 +8056,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: break; case glslang::EOpMax: if (isFloat) - libCall = spv::GLSLstd450FMax; + libCall = nanMinMaxClamp ? spv::GLSLstd450NMax : spv::GLSLstd450FMax; else if (isUnsigned) libCall = spv::GLSLstd450UMax; else @@ -6761,7 +8075,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpClamp: if (isFloat) - libCall = spv::GLSLstd450FClamp; + libCall = nanMinMaxClamp ? spv::GLSLstd450NClamp : spv::GLSLstd450FClamp; else if (isUnsigned) libCall = spv::GLSLstd450UClamp; else @@ -6804,18 +8118,59 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpRefract: libCall = spv::GLSLstd450Refract; break; + case glslang::EOpBarrier: + { + // This is for the extended controlBarrier function, with four operands. + // The unextended barrier() goes through createNoArgOperation. + assert(operands.size() == 4); + unsigned int executionScope = builder.getConstantScalar(operands[0]); + unsigned int memoryScope = builder.getConstantScalar(operands[1]); + unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]); + builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, + (spv::MemorySemanticsMask)semantics); + if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | + spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsVolatileMask)) { + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + } + if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || + memoryScope == spv::ScopeDevice)) { + builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); + } + return 0; + } + break; + case glslang::EOpMemoryBarrier: + { + // This is for the extended memoryBarrier function, with three operands. + // The unextended memoryBarrier() goes through createNoArgOperation. + assert(operands.size() == 3); + unsigned int memoryScope = builder.getConstantScalar(operands[0]); + unsigned int semantics = builder.getConstantScalar(operands[1]) | builder.getConstantScalar(operands[2]); + builder.createMemoryBarrier((spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics); + if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | + spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsVolatileMask)) { + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + } + if (glslangIntermediate->usingVulkanMemoryModel() && memoryScope == spv::ScopeDevice) { + builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); + } + return 0; + } + break; + +#ifndef GLSLANG_WEB case glslang::EOpInterpolateAtSample: -#ifdef AMD_EXTENSIONS if (typeProxy == glslang::EbtFloat16) builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); -#endif libCall = spv::GLSLstd450InterpolateAtSample; break; case glslang::EOpInterpolateAtOffset: -#ifdef AMD_EXTENSIONS if (typeProxy == glslang::EbtFloat16) builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); -#endif libCall = spv::GLSLstd450InterpolateAtOffset; break; case glslang::EOpAddCarry: @@ -6857,15 +8212,14 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: assert(builder.isPointerType(typeId1)); typeId1 = builder.getContainedTypeId(typeId1); int width = builder.getScalarTypeWidth(typeId1); -#ifdef AMD_EXTENSIONS if (width == 16) // Using 16-bit exp operand, enable extension SPV_AMD_gpu_shader_int16 builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16); -#endif if (builder.getNumComponents(operands[0]) == 1) frexpIntType = builder.makeIntegerType(width, true); else - frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true), builder.getNumComponents(operands[0])); + frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true), + builder.getNumComponents(operands[0])); typeId = builder.makeStructResultType(typeId0, frexpIntType); consumedOperands = 1; } @@ -6891,7 +8245,6 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpSubgroupClusteredOr: case glslang::EOpSubgroupClusteredXor: case glslang::EOpSubgroupQuadBroadcast: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAdd: case glslang::EOpSubgroupPartitionedMul: case glslang::EOpSubgroupPartitionedMin: @@ -6913,10 +8266,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpSubgroupPartitionedExclusiveAnd: case glslang::EOpSubgroupPartitionedExclusiveOr: case glslang::EOpSubgroupPartitionedExclusiveXor: -#endif return createSubgroupOperation(op, typeId, operands, typeProxy); -#ifdef AMD_EXTENSIONS case glslang::EOpSwizzleInvocations: extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot); libCall = spv::SwizzleInvocationsAMD; @@ -6970,66 +8321,124 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_explicit_vertex_parameter); libCall = spv::InterpolateAtVertexAMD; break; -#endif - case glslang::EOpBarrier: - { - // This is for the extended controlBarrier function, with four operands. - // The unextended barrier() goes through createNoArgOperation. - assert(operands.size() == 4); - unsigned int executionScope = builder.getConstantScalar(operands[0]); - unsigned int memoryScope = builder.getConstantScalar(operands[1]); - unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]); - builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics); - if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) { - builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); - } - if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || memoryScope == spv::ScopeDevice)) { - builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); - } - return 0; - } - break; - case glslang::EOpMemoryBarrier: - { - // This is for the extended memoryBarrier function, with three operands. - // The unextended memoryBarrier() goes through createNoArgOperation. - assert(operands.size() == 3); - unsigned int memoryScope = builder.getConstantScalar(operands[0]); - unsigned int semantics = builder.getConstantScalar(operands[1]) | builder.getConstantScalar(operands[2]); - builder.createMemoryBarrier((spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics); - if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) { - builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); - } - if (glslangIntermediate->usingVulkanMemoryModel() && memoryScope == spv::ScopeDevice) { - builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); - } - return 0; - } - break; -#ifdef NV_EXTENSIONS - case glslang::EOpReportIntersectionNV: - { + case glslang::EOpReportIntersection: typeId = builder.makeBoolType(); - opCode = spv::OpReportIntersectionNV; - } - break; + opCode = spv::OpReportIntersectionKHR; + break; case glslang::EOpTraceNV: - { builder.createNoResultOp(spv::OpTraceNV, operands); return 0; - } - break; + case glslang::EOpTraceRayMotionNV: + builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur); + builder.addCapability(spv::CapabilityRayTracingMotionBlurNV); + builder.createNoResultOp(spv::OpTraceRayMotionNV, operands); + return 0; + case glslang::EOpTraceKHR: + builder.createNoResultOp(spv::OpTraceRayKHR, operands); + return 0; case glslang::EOpExecuteCallableNV: - { builder.createNoResultOp(spv::OpExecuteCallableNV, operands); return 0; - } - break; + case glslang::EOpExecuteCallableKHR: + builder.createNoResultOp(spv::OpExecuteCallableKHR, operands); + return 0; + + case glslang::EOpRayQueryInitialize: + builder.createNoResultOp(spv::OpRayQueryInitializeKHR, operands); + return 0; + case glslang::EOpRayQueryTerminate: + builder.createNoResultOp(spv::OpRayQueryTerminateKHR, operands); + return 0; + case glslang::EOpRayQueryGenerateIntersection: + builder.createNoResultOp(spv::OpRayQueryGenerateIntersectionKHR, operands); + return 0; + case glslang::EOpRayQueryConfirmIntersection: + builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR, operands); + return 0; + case glslang::EOpRayQueryProceed: + typeId = builder.makeBoolType(); + opCode = spv::OpRayQueryProceedKHR; + break; + case glslang::EOpRayQueryGetIntersectionType: + typeId = builder.makeUintType(32); + opCode = spv::OpRayQueryGetIntersectionTypeKHR; + break; + case glslang::EOpRayQueryGetRayTMin: + typeId = builder.makeFloatType(32); + opCode = spv::OpRayQueryGetRayTMinKHR; + break; + case glslang::EOpRayQueryGetRayFlags: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetRayFlagsKHR; + break; + case glslang::EOpRayQueryGetIntersectionT: + typeId = builder.makeFloatType(32); + opCode = spv::OpRayQueryGetIntersectionTKHR; + break; + case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetIntersectionInstanceCustomIndexKHR; + break; + case glslang::EOpRayQueryGetIntersectionInstanceId: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR; + break; + case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: + typeId = builder.makeUintType(32); + opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR; + break; + case glslang::EOpRayQueryGetIntersectionGeometryIndex: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetIntersectionGeometryIndexKHR; + break; + case glslang::EOpRayQueryGetIntersectionPrimitiveIndex: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetIntersectionPrimitiveIndexKHR; + break; + case glslang::EOpRayQueryGetIntersectionBarycentrics: + typeId = builder.makeVectorType(builder.makeFloatType(32), 2); + opCode = spv::OpRayQueryGetIntersectionBarycentricsKHR; + break; + case glslang::EOpRayQueryGetIntersectionFrontFace: + typeId = builder.makeBoolType(); + opCode = spv::OpRayQueryGetIntersectionFrontFaceKHR; + break; + case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque: + typeId = builder.makeBoolType(); + opCode = spv::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR; + break; + case glslang::EOpRayQueryGetIntersectionObjectRayDirection: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpRayQueryGetIntersectionObjectRayDirectionKHR; + break; + case glslang::EOpRayQueryGetIntersectionObjectRayOrigin: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpRayQueryGetIntersectionObjectRayOriginKHR; + break; + case glslang::EOpRayQueryGetWorldRayDirection: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpRayQueryGetWorldRayDirectionKHR; + break; + case glslang::EOpRayQueryGetWorldRayOrigin: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpRayQueryGetWorldRayOriginKHR; + break; + case glslang::EOpRayQueryGetIntersectionObjectToWorld: + typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3); + opCode = spv::OpRayQueryGetIntersectionObjectToWorldKHR; + break; + case glslang::EOpRayQueryGetIntersectionWorldToObject: + typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3); + opCode = spv::OpRayQueryGetIntersectionWorldToObjectKHR; + break; case glslang::EOpWritePackedPrimitiveIndices4x8NV: builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands); return 0; -#endif + case glslang::EOpCooperativeMatrixMulAdd: + opCode = spv::OpCooperativeMatrixMulAddNV; + break; +#endif // GLSLANG_WEB default: return 0; } @@ -7050,7 +8459,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: id = builder.createCompositeExtract(mulOp, typeId, 0); for (int i = 1; i < componentCount; ++i) { builder.setPrecision(id, precision); - id = builder.createBinOp(spv::OpIAdd, typeId, id, builder.createCompositeExtract(operands[0], typeId, i)); + id = builder.createBinOp(spv::OpIAdd, typeId, id, builder.createCompositeExtract(mulOp, typeId, i)); } } else { switch (consumedOperands) { @@ -7073,6 +8482,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: } } +#ifndef GLSLANG_WEB // Decode the return types that were structures switch (op) { case glslang::EOpAddCarry: @@ -7102,6 +8512,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: default: break; } +#endif return builder.setPrecision(id, precision); } @@ -7110,15 +8521,10 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId) { // GLSL memory barriers use queuefamily scope in new model, device scope in old model - spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice; + spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? + spv::ScopeQueueFamilyKHR : spv::ScopeDevice; switch (op) { - case glslang::EOpEmitVertex: - builder.createNoResultOp(spv::OpEmitVertex); - return 0; - case glslang::EOpEndPrimitive: - builder.createNoResultOp(spv::OpEndPrimitive); - return 0; case glslang::EOpBarrier: if (glslangIntermediate->getStage() == EShLangTessControl) { if (glslangIntermediate->usingVulkanMemoryModel()) { @@ -7139,18 +8545,10 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAllMemory | spv::MemorySemanticsAcquireReleaseMask); return 0; - case glslang::EOpMemoryBarrierAtomicCounter: - builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAtomicCounterMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); - return 0; case glslang::EOpMemoryBarrierBuffer: builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsUniformMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return 0; - case glslang::EOpMemoryBarrierImage: - builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsImageMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); - return 0; case glslang::EOpMemoryBarrierShared: builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask); @@ -7159,6 +8557,15 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsAllMemory | spv::MemorySemanticsAcquireReleaseMask); return 0; +#ifndef GLSLANG_WEB + case glslang::EOpMemoryBarrierAtomicCounter: + builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAtomicCounterMemoryMask | + spv::MemorySemanticsAcquireReleaseMask); + return 0; + case glslang::EOpMemoryBarrierImage: + builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsImageMemoryMask | + spv::MemorySemanticsAcquireReleaseMask); + return 0; case glslang::EOpAllMemoryBarrierWithGroupSync: builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeDevice, spv::MemorySemanticsAllMemory | @@ -7203,30 +8610,80 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return spv::NoResult; + + case glslang::EOpEmitVertex: + builder.createNoResultOp(spv::OpEmitVertex); + return 0; + case glslang::EOpEndPrimitive: + builder.createNoResultOp(spv::OpEndPrimitive); + return 0; + case glslang::EOpSubgroupElect: { std::vector operands; return createSubgroupOperation(op, typeId, operands, glslang::EbtVoid); } -#ifdef AMD_EXTENSIONS case glslang::EOpTime: { std::vector args; // Dummy arguments spv::Id id = builder.createBuiltinCall(typeId, getExtBuiltins(spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args); return builder.setPrecision(id, precision); } -#endif -#ifdef NV_EXTENSIONS case glslang::EOpIgnoreIntersectionNV: builder.createNoResultOp(spv::OpIgnoreIntersectionNV); return 0; case glslang::EOpTerminateRayNV: builder.createNoResultOp(spv::OpTerminateRayNV); return 0; + case glslang::EOpRayQueryInitialize: + builder.createNoResultOp(spv::OpRayQueryInitializeKHR); + return 0; + case glslang::EOpRayQueryTerminate: + builder.createNoResultOp(spv::OpRayQueryTerminateKHR); + return 0; + case glslang::EOpRayQueryGenerateIntersection: + builder.createNoResultOp(spv::OpRayQueryGenerateIntersectionKHR); + return 0; + case glslang::EOpRayQueryConfirmIntersection: + builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR); + return 0; + case glslang::EOpBeginInvocationInterlock: + builder.createNoResultOp(spv::OpBeginInvocationInterlockEXT); + return 0; + case glslang::EOpEndInvocationInterlock: + builder.createNoResultOp(spv::OpEndInvocationInterlockEXT); + return 0; + + case glslang::EOpIsHelperInvocation: + { + std::vector args; // Dummy arguments + builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation); + builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT); + return builder.createOp(spv::OpIsHelperInvocationEXT, typeId, args); + } + + case glslang::EOpReadClockSubgroupKHR: { + std::vector args; + args.push_back(builder.makeUintConstant(spv::ScopeSubgroup)); + builder.addExtension(spv::E_SPV_KHR_shader_clock); + builder.addCapability(spv::CapabilityShaderClockKHR); + return builder.createOp(spv::OpReadClockKHR, typeId, args); + } + + case glslang::EOpReadClockDeviceKHR: { + std::vector args; + args.push_back(builder.makeUintConstant(spv::ScopeDevice)); + builder.addExtension(spv::E_SPV_KHR_shader_clock); + builder.addCapability(spv::CapabilityShaderClockKHR); + return builder.createOp(spv::OpReadClockKHR, typeId, args); + } #endif default: - logger->missingFunctionality("unknown operation with no arguments"); - return 0; + break; } + + logger->missingFunctionality("unknown operation with no arguments"); + + return 0; } spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol) @@ -7239,22 +8696,26 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol } // it was not found, create it - id = createSpvVariable(symbol); + spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false); + auto forcedType = getForcedType(symbol->getQualifier().builtIn, symbol->getType()); + id = createSpvVariable(symbol, forcedType.first); symbolValues[symbol->getId()] = id; + if (forcedType.second != spv::NoType) + forceType[id] = forcedType.second; if (symbol->getBasicType() != glslang::EbtBlock) { builder.addDecoration(id, TranslatePrecisionDecoration(symbol->getType())); builder.addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier())); builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier())); -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB addMeshNVDecoration(id, /*member*/ -1, symbol->getType().getQualifier()); + if (symbol->getQualifier().hasComponent()) + builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent); + if (symbol->getQualifier().hasIndex()) + builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex); #endif if (symbol->getType().getQualifier().hasSpecConstantId()) builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId); - if (symbol->getQualifier().hasIndex()) - builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex); - if (symbol->getQualifier().hasComponent()) - builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent); // atomic counters use this: if (symbol->getQualifier().hasOffset()) builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset); @@ -7293,22 +8754,21 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset); } - if (symbol->getType().isImage()) { + // add built-in variable decoration + if (builtIn != spv::BuiltInMax) { + builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn); + } + +#ifndef GLSLANG_WEB + // Subgroup builtins which have input storage class are volatile for ray tracing stages. + if (symbol->getType().isImage() || symbol->getQualifier().isPipeInput()) { std::vector memory; - TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel()); + TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, + glslangIntermediate->usingVulkanMemoryModel()); for (unsigned int i = 0; i < memory.size(); ++i) builder.addDecoration(id, memory[i]); } - // built-in variable decorations - spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false); - if (builtIn != spv::BuiltInMax) - builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn); - - // nonuniform - builder.addDecoration(id, TranslateNonUniformDecoration(symbol->getType().getQualifier())); - -#ifdef NV_EXTENSIONS if (builtIn == spv::BuiltInSampleMask) { spv::Decoration decoration; // GL_NV_sample_mask_override_coverage extension @@ -7318,6 +8778,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol decoration = (spv::Decoration)spv::DecorationMax; builder.addDecoration(id, decoration); if (decoration != spv::DecorationMax) { + builder.addCapability(spv::CapabilitySampleMaskOverrideCoverageNV); builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage); } } @@ -7346,7 +8807,6 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol builder.addCapability(spv::CapabilityFragmentBarycentricNV); builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric); } -#endif if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) { builder.addExtension("SPV_GOOGLE_hlsl_functionality1"); @@ -7354,14 +8814,58 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol symbol->getType().getQualifier().semanticName); } - if (symbol->getBasicType() == glslang::EbtReference) { - builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); + if (symbol->isReference()) { + builder.addDecoration(id, symbol->getType().getQualifier().restrict ? + spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); } + // + // Add SPIR-V decorations for structure (GL_EXT_spirv_intrinsics) + // + if (symbol->getType().getQualifier().hasSprivDecorate()) { + const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate(); + + // Add spirv_decorate + for (auto& decorate : spirvDecorate.decorates) { + if (!decorate.second.empty()) { + std::vector literals; + TranslateLiterals(decorate.second, literals); + builder.addDecoration(id, static_cast(decorate.first), literals); + } + else + builder.addDecoration(id, static_cast(decorate.first)); + } + + // Add spirv_decorate_id + for (auto& decorateId : spirvDecorate.decorateIds) { + std::vector operandIds; + assert(!decorateId.second.empty()); + for (auto extraOperand : decorateId.second) { + int nextConst = 0; + spv::Id operandId = createSpvConstantFromConstUnionArray( + extraOperand->getType(), extraOperand->getConstArray(), nextConst, false); + operandIds.push_back(operandId); + } + builder.addDecoration(id, static_cast(decorateId.first), operandIds); + } + + // Add spirv_decorate_string + for (auto& decorateString : spirvDecorate.decorateStrings) { + std::vector strings; + assert(!decorateString.second.empty()); + for (auto extraOperand : decorateString.second) { + const char* string = extraOperand->getConstArray()[0].getSConst()->c_str(); + strings.push_back(string); + } + builder.addDecoration(id, static_cast(decorateString.first), strings); + } + } +#endif + return id; } -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB // add per-primitive, per-view. per-task decorations to a struct member (member >= 0) or an object void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier& qualifier) { @@ -7416,12 +8920,25 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n // hand off to the non-spec-constant path assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr); int nextConst = 0; - return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), - nextConst, false); + return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? + node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), + nextConst, false); } // We now know we have a specialization constant to build + // Extra capabilities may be needed. + if (node.getType().contains8BitInt()) + builder.addCapability(spv::CapabilityInt8); + if (node.getType().contains16BitFloat()) + builder.addCapability(spv::CapabilityFloat16); + if (node.getType().contains16BitInt()) + builder.addCapability(spv::CapabilityInt16); + if (node.getType().contains64BitInt()) + builder.addCapability(spv::CapabilityInt64); + if (node.getType().containsDouble()) + builder.addCapability(spv::CapabilityFloat64); + // gl_WorkGroupSize is a special case until the front-end handles hierarchical specialization constants, // even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ... if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) { @@ -7470,7 +8987,8 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n // If there are not enough elements present in 'consts', 0 will be substituted; // an empty 'consts' can be used to create a fully zeroed SPIR-V constant. // -spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant) +spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glslang::TType& glslangType, + const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant) { // vector of constants for SPIR-V std::vector spvConsts; @@ -7486,6 +9004,9 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla glslang::TType vectorType(glslangType, 0); for (int col = 0; col < glslangType.getMatrixCols(); ++col) spvConsts.push_back(createSpvConstantFromConstUnionArray(vectorType, consts, nextConst, false)); + } else if (glslangType.isCoopMat()) { + glslang::TType componentType(glslangType.getBasicType()); + spvConsts.push_back(createSpvConstantFromConstUnionArray(componentType, consts, nextConst, false)); } else if (glslangType.isStruct()) { glslang::TVector::const_iterator iter; for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter) @@ -7494,6 +9015,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla for (unsigned int i = 0; i < (unsigned int)glslangType.getVectorSize(); ++i) { bool zero = nextConst >= consts.size(); switch (glslangType.getBasicType()) { + case glslang::EbtInt: + spvConsts.push_back(builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst())); + break; + case glslang::EbtUint: + spvConsts.push_back(builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst())); + break; + case glslang::EbtFloat: + spvConsts.push_back(builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst())); + break; + case glslang::EbtBool: + spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst())); + break; +#ifndef GLSLANG_WEB case glslang::EbtInt8: spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const())); break; @@ -7506,30 +9040,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla case glslang::EbtUint16: spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const())); break; - case glslang::EbtInt: - spvConsts.push_back(builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst())); - break; - case glslang::EbtUint: - spvConsts.push_back(builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst())); - break; case glslang::EbtInt64: spvConsts.push_back(builder.makeInt64Constant(zero ? 0 : consts[nextConst].getI64Const())); break; case glslang::EbtUint64: spvConsts.push_back(builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const())); break; - case glslang::EbtFloat: - spvConsts.push_back(builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst())); - break; case glslang::EbtDouble: spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst())); break; case glslang::EbtFloat16: spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst())); break; - case glslang::EbtBool: - spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst())); - break; +#endif default: assert(0); break; @@ -7541,6 +9064,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla bool zero = nextConst >= consts.size(); spv::Id scalar = 0; switch (glslangType.getBasicType()) { + case glslang::EbtInt: + scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst(), specConstant); + break; + case glslang::EbtUint: + scalar = builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst(), specConstant); + break; + case glslang::EbtFloat: + scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant); + break; + case glslang::EbtBool: + scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant); + break; +#ifndef GLSLANG_WEB case glslang::EbtInt8: scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant); break; @@ -7553,29 +9089,25 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla case glslang::EbtUint16: scalar = builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const(), specConstant); break; - case glslang::EbtInt: - scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst(), specConstant); - break; - case glslang::EbtUint: - scalar = builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst(), specConstant); - break; case glslang::EbtInt64: scalar = builder.makeInt64Constant(zero ? 0 : consts[nextConst].getI64Const(), specConstant); break; case glslang::EbtUint64: scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant); break; - case glslang::EbtFloat: - scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant); - break; case glslang::EbtDouble: scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant); break; case glslang::EbtFloat16: scalar = builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant); break; - case glslang::EbtBool: - scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant); + case glslang::EbtReference: + scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant); + scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar); + break; +#endif + case glslang::EbtString: + scalar = builder.getStringId(consts[nextConst].getSConst()->c_str()); break; default: assert(0); @@ -7677,7 +9209,8 @@ bool TGlslangToSpvTraverser::isTrivial(const glslang::TIntermTyped* node) // Emit short-circuiting code, where 'right' is never evaluated unless // the left side is true (for &&) or false (for ||). -spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslang::TIntermTyped& left, glslang::TIntermTyped& right) +spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslang::TIntermTyped& left, + glslang::TIntermTyped& right) { spv::Id boolTypeId = builder.makeBoolType(); @@ -7720,7 +9253,7 @@ spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslan return builder.createOp(spv::OpPhi, boolTypeId, phiOperands); } -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB // Return type Id of the imported set of extended instructions corresponds to the name. // Import this set if it has not been imported yet. spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name) @@ -7760,7 +9293,10 @@ int GetSpirvGeneratorVersion() // return 5; // make OpArrayLength result type be an int with signedness of 0 // return 6; // revert version 5 change, which makes a different (new) kind of incorrect code, // versions 4 and 6 each generate OpArrayLength as it has long been done - return 7; // GLSL volatile keyword maps to both SPIR-V decorations Volatile and Coherent + // return 7; // GLSL volatile keyword maps to both SPIR-V decorations Volatile and Coherent + // return 8; // switch to new dead block eliminator; use OpUnreachable + // return 9; // don't include opaque function parameters in OpEntryPoint global's operand list + return 10; // Generate OpFUnordNotEqual for != comparisons } // Write SPIR-V out to a binary file @@ -7780,13 +9316,15 @@ void OutputSpvBin(const std::vector& spirv, const char* baseName) // Write SPIR-V out to a text file with 32-bit hexadecimal words void OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName) { +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) std::ofstream out; out.open(baseName, std::ios::binary | std::ios::out); if (out.fail()) printf("ERROR: Failed to open file: %s\n", baseName); - out << "\t// " << - GetSpirvGeneratorVersion() << "." << GLSLANG_MINOR_VERSION << "." << GLSLANG_PATCH_LEVEL << - std::endl; + out << "\t// " << + GetSpirvGeneratorVersion() << + GLSLANG_VERSION_MAJOR << "." << GLSLANG_VERSION_MINOR << "." << GLSLANG_VERSION_PATCH << + GLSLANG_VERSION_FLAVOR << std::endl; if (varName != nullptr) { out << "\t #pragma once" << std::endl; out << "const uint32_t " << varName << "[] = {" << std::endl; @@ -7805,8 +9343,10 @@ void OutputSpvHex(const std::vector& spirv, const char* baseName, } if (varName != nullptr) { out << "};"; + out << std::endl; } out.close(); +#endif } // @@ -7840,11 +9380,18 @@ void GlslangToSpv(const TIntermediate& intermediate, std::vector& #if ENABLE_OPT // If from HLSL, run spirv-opt to "legalize" the SPIR-V for Vulkan // eg. forward and remove memory writes of opaque types. - if ((intermediate.getSource() == EShSourceHlsl || options->optimizeSize) && !options->disableOptimizer) - SpirvToolsLegalize(intermediate, spirv, logger, options); + bool prelegalization = intermediate.getSource() == EShSourceHlsl; + if ((prelegalization || options->optimizeSize) && !options->disableOptimizer) { + SpirvToolsTransform(intermediate, spirv, logger, options); + prelegalization = false; + } + else if (options->stripDebugInfo) { + // Strip debug info even if optimization is disabled. + SpirvToolsStripDebugInfo(intermediate, spirv, logger); + } if (options->validate) - SpirvToolsValidate(intermediate, spirv, logger); + SpirvToolsValidate(intermediate, spirv, logger, prelegalization); if (options->disassemble) SpirvToolsDisassemble(std::cout, spirv); diff --git a/thirdparty/ShaderCompiler/spirv/InReadableOrder.cpp b/thirdparty/ShaderCompiler/spirv/InReadableOrder.cpp index 52b2961..9d9410b 100644 --- a/thirdparty/ShaderCompiler/spirv/InReadableOrder.cpp +++ b/thirdparty/ShaderCompiler/spirv/InReadableOrder.cpp @@ -61,17 +61,22 @@ namespace { // Use by calling visit() on the root block. class ReadableOrderTraverser { public: - explicit ReadableOrderTraverser(std::function callback) : callback_(callback) {} + ReadableOrderTraverser(std::function callback) + : callback_(callback) {} // Visits the block if it hasn't been visited already and isn't currently - // being delayed. Invokes callback(block), then descends into its + // being delayed. Invokes callback(block, why, header), then descends into its // successors. Delays merge-block and continue-block processing until all - // the branches have been completed. - void visit(Block* block) + // the branches have been completed. If |block| is an unreachable merge block or + // an unreachable continue target, then |header| is the corresponding header block. + void visit(Block* block, spv::ReachReason why, Block* header) { assert(block); + if (why == spv::ReachViaControlFlow) { + reachableViaControlFlow_.insert(block); + } if (visited_.count(block) || delayed_.count(block)) return; - callback_(block); + callback_(block, why, header); visited_.insert(block); Block* mergeBlock = nullptr; Block* continueBlock = nullptr; @@ -87,27 +92,40 @@ public: delayed_.insert(continueBlock); } } - const auto successors = block->getSuccessors(); - for (auto it = successors.cbegin(); it != successors.cend(); ++it) - visit(*it); + if (why == spv::ReachViaControlFlow) { + const auto& successors = block->getSuccessors(); + for (auto it = successors.cbegin(); it != successors.cend(); ++it) + visit(*it, why, nullptr); + } if (continueBlock) { + const spv::ReachReason continueWhy = + (reachableViaControlFlow_.count(continueBlock) > 0) + ? spv::ReachViaControlFlow + : spv::ReachDeadContinue; delayed_.erase(continueBlock); - visit(continueBlock); + visit(continueBlock, continueWhy, block); } if (mergeBlock) { + const spv::ReachReason mergeWhy = + (reachableViaControlFlow_.count(mergeBlock) > 0) + ? spv::ReachViaControlFlow + : spv::ReachDeadMerge; delayed_.erase(mergeBlock); - visit(mergeBlock); + visit(mergeBlock, mergeWhy, block); } } private: - std::function callback_; + std::function callback_; // Whether a block has already been visited or is being delayed. std::unordered_set visited_, delayed_; + + // The set of blocks that actually are reached via control flow. + std::unordered_set reachableViaControlFlow_; }; } -void spv::inReadableOrder(Block* root, std::function callback) +void spv::inReadableOrder(Block* root, std::function callback) { - ReadableOrderTraverser(callback).visit(root); + ReadableOrderTraverser(callback).visit(root, spv::ReachViaControlFlow, nullptr); } diff --git a/thirdparty/ShaderCompiler/spirv/Logger.cpp b/thirdparty/ShaderCompiler/spirv/Logger.cpp index 48bd4e3..cdc8469 100644 --- a/thirdparty/ShaderCompiler/spirv/Logger.cpp +++ b/thirdparty/ShaderCompiler/spirv/Logger.cpp @@ -32,6 +32,8 @@ // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +#ifndef GLSLANG_WEB + #include "Logger.h" #include @@ -66,3 +68,5 @@ std::string SpvBuildLogger::getAllMessages() const { } } // end spv namespace + +#endif diff --git a/thirdparty/ShaderCompiler/spirv/Logger.h b/thirdparty/ShaderCompiler/spirv/Logger.h index 2e4ddaf..411367c 100644 --- a/thirdparty/ShaderCompiler/spirv/Logger.h +++ b/thirdparty/ShaderCompiler/spirv/Logger.h @@ -46,6 +46,14 @@ class SpvBuildLogger { public: SpvBuildLogger() {} +#ifdef GLSLANG_WEB + void tbdFunctionality(const std::string& f) { } + void missingFunctionality(const std::string& f) { } + void warning(const std::string& w) { } + void error(const std::string& e) { errors.push_back(e); } + std::string getAllMessages() { return ""; } +#else + // Registers a TBD functionality. void tbdFunctionality(const std::string& f); // Registers a missing functionality. @@ -59,6 +67,7 @@ public: // Returns all messages accumulated in the order of: // TBD functionalities, missing functionalities, warnings, errors. std::string getAllMessages() const; +#endif private: SpvBuildLogger(const SpvBuildLogger&); diff --git a/thirdparty/ShaderCompiler/spirv/NonSemanticDebugPrintf.h b/thirdparty/ShaderCompiler/spirv/NonSemanticDebugPrintf.h new file mode 100644 index 0000000..83796d7 --- /dev/null +++ b/thirdparty/ShaderCompiler/spirv/NonSemanticDebugPrintf.h @@ -0,0 +1,50 @@ +// Copyright (c) 2020 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ +#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticDebugPrintfRevision = 1, + NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticDebugPrintfInstructions { + NonSemanticDebugPrintfDebugPrintf = 1, + NonSemanticDebugPrintfInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ diff --git a/thirdparty/ShaderCompiler/spirv/SPVRemapper.cpp b/thirdparty/ShaderCompiler/spirv/SPVRemapper.cpp index fd0bb89..56d6d5d 100644 --- a/thirdparty/ShaderCompiler/spirv/SPVRemapper.cpp +++ b/thirdparty/ShaderCompiler/spirv/SPVRemapper.cpp @@ -544,6 +544,9 @@ namespace spv { // Extended instructions: currently, assume everything is an ID. // TODO: add whatever data we need for exceptions to that if (opCode == spv::OpExtInst) { + + idFn(asId(word)); // Instruction set is an ID that also needs to be mapped + word += 2; // instruction set, and instruction from set numOperands -= 2; @@ -625,6 +628,9 @@ namespace spv { break; } + case spv::OperandVariableLiteralStrings: + return nextInst; + // Execution mode might have extra literal operands. Skip them. case spv::OperandExecutionMode: return nextInst; @@ -827,7 +833,15 @@ namespace spv { [&](spv::Id& id) { if (thisOpCode != spv::OpNop) { ++idCounter; - const std::uint32_t hashval = opCounter[thisOpCode] * thisOpCode * 50047 + idCounter + fnId * 117; + const std::uint32_t hashval = + // Explicitly cast operands to unsigned int to avoid integer + // promotion to signed int followed by integer overflow, + // which would result in undefined behavior. + static_cast(opCounter[thisOpCode]) + * thisOpCode + * 50047 + + idCounter + + static_cast(fnId) * 117; if (isOldIdUnmapped(id)) localId(id, nextUnusedId(hashval % softTypeIdLimit + firstMappedID)); diff --git a/thirdparty/ShaderCompiler/spirv/SPVRemapper.h b/thirdparty/ShaderCompiler/spirv/SPVRemapper.h index 97e3f31..d6b9c34 100644 --- a/thirdparty/ShaderCompiler/spirv/SPVRemapper.h +++ b/thirdparty/ShaderCompiler/spirv/SPVRemapper.h @@ -45,7 +45,7 @@ namespace spv { // MSVC defines __cplusplus as an older value, even when it supports almost all of 11. // We handle that here by making our own symbol. -#if __cplusplus >= 201103L || _MSC_VER >= 1700 +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1700) # define use_cpp11 1 #endif @@ -195,7 +195,7 @@ private: // Header access & set methods spirword_t magic() const { return spv[0]; } // return magic number spirword_t bound() const { return spv[3]; } // return Id bound from header - spirword_t bound(spirword_t b) { return spv[3] = b; }; + spirword_t bound(spirword_t b) { return spv[3] = b; } spirword_t genmagic() const { return spv[2]; } // generator magic spirword_t genmagic(spirword_t m) { return spv[2] = m; } spirword_t schemaNum() const { return spv[4]; } // schema number from header diff --git a/thirdparty/ShaderCompiler/spirv/SpvBuilder.cpp b/thirdparty/ShaderCompiler/spirv/SpvBuilder.cpp index 8355d83..e83306e 100644 --- a/thirdparty/ShaderCompiler/spirv/SpvBuilder.cpp +++ b/thirdparty/ShaderCompiler/spirv/SpvBuilder.cpp @@ -1,6 +1,7 @@ // // Copyright (C) 2014-2015 LunarG, Inc. // Copyright (C) 2015-2018 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -46,7 +47,9 @@ #include "SpvBuilder.h" +#ifndef GLSLANG_WEB #include "hex_float.h" +#endif #ifndef _WIN32 #include @@ -230,6 +233,11 @@ Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardP Id Builder::makeIntegerType(int width, bool hasSign) { +#ifdef GLSLANG_WEB + assert(width == 32); + width = 32; +#endif + // try to find it Instruction* type; for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) { @@ -265,6 +273,11 @@ Id Builder::makeIntegerType(int width, bool hasSign) Id Builder::makeFloatType(int width) { +#ifdef GLSLANG_WEB + assert(width == 32); + width = 32; +#endif + // try to find it Instruction* type; for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) { @@ -388,6 +401,33 @@ Id Builder::makeMatrixType(Id component, int cols, int rows) return type->getResultId(); } +Id Builder::makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols) +{ + // try to find it + Instruction* type; + for (int t = 0; t < (int)groupedTypes[OpTypeCooperativeMatrixNV].size(); ++t) { + type = groupedTypes[OpTypeCooperativeMatrixNV][t]; + if (type->getIdOperand(0) == component && + type->getIdOperand(1) == scope && + type->getIdOperand(2) == rows && + type->getIdOperand(3) == cols) + return type->getResultId(); + } + + // not found, make it + type = new Instruction(getUniqueId(), NoType, OpTypeCooperativeMatrixNV); + type->addIdOperand(component); + type->addIdOperand(scope); + type->addIdOperand(rows); + type->addIdOperand(cols); + groupedTypes[OpTypeCooperativeMatrixNV].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + + // TODO: performance: track arrays per stride // If a stride is supplied (non-zero) make an array. // If no stride (0), reuse previous array types. @@ -457,7 +497,8 @@ Id Builder::makeFunctionType(Id returnType, const std::vector& paramTypes) return type->getResultId(); } -Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format) +Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, + ImageFormat format) { assert(sampled == 1 || sampled == 2); @@ -489,6 +530,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); +#ifndef GLSLANG_WEB // deal with capabilities switch (dim) { case DimBuffer: @@ -534,6 +576,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo addCapability(CapabilityImageMSArray); } } +#endif return type->getResultId(); } @@ -559,22 +602,38 @@ Id Builder::makeSampledImageType(Id imageType) return type->getResultId(); } -#ifdef NV_EXTENSIONS -Id Builder::makeAccelerationStructureNVType() +#ifndef GLSLANG_WEB +Id Builder::makeAccelerationStructureType() { Instruction *type; - if (groupedTypes[OpTypeAccelerationStructureNV].size() == 0) { - type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureNV); - groupedTypes[OpTypeAccelerationStructureNV].push_back(type); + if (groupedTypes[OpTypeAccelerationStructureKHR].size() == 0) { + type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureKHR); + groupedTypes[OpTypeAccelerationStructureKHR].push_back(type); constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); } else { - type = groupedTypes[OpTypeAccelerationStructureNV].back(); + type = groupedTypes[OpTypeAccelerationStructureKHR].back(); + } + + return type->getResultId(); +} + +Id Builder::makeRayQueryType() +{ + Instruction *type; + if (groupedTypes[OpTypeRayQueryKHR].size() == 0) { + type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryKHR); + groupedTypes[OpTypeRayQueryKHR].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + } else { + type = groupedTypes[OpTypeRayQueryKHR].back(); } return type->getResultId(); } #endif + Id Builder::getDerefTypeId(Id resultId) const { Id typeId = getTypeId(resultId); @@ -623,6 +682,9 @@ int Builder::getNumTypeConstituents(Id typeId) const } case OpTypeStruct: return instr->getNumOperands(); + case OpTypeCooperativeMatrixNV: + // has only one constituent when used with OpCompositeConstruct. + return 1; default: assert(0); return 1; @@ -669,6 +731,7 @@ Id Builder::getContainedTypeId(Id typeId, int member) const case OpTypeMatrix: case OpTypeArray: case OpTypeRuntimeArray: + case OpTypeCooperativeMatrixNV: return instr->getIdOperand(0); case OpTypePointer: return instr->getIdOperand(1); @@ -680,6 +743,26 @@ Id Builder::getContainedTypeId(Id typeId, int member) const } } +// Figure out the final resulting type of the access chain. +Id Builder::getResultingAccessChainType() const +{ + assert(accessChain.base != NoResult); + Id typeId = getTypeId(accessChain.base); + + assert(isPointerType(typeId)); + typeId = getContainedTypeId(typeId); + + for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) { + if (isStructType(typeId)) { + assert(isConstantScalar(accessChain.indexChain[i])); + typeId = getContainedTypeId(typeId, getConstantScalar(accessChain.indexChain[i])); + } else + typeId = getContainedTypeId(typeId, accessChain.indexChain[i]); + } + + return typeId; +} + // Return the immediately contained type of a given composite type. Id Builder::getContainedTypeId(Id typeId) const { @@ -806,6 +889,30 @@ bool Builder::isSpecConstantOpCode(Op opcode) const } } +Id Builder::makeNullConstant(Id typeId) +{ + Instruction* constant; + + // See if we already made it. + Id existing = NoResult; + for (int i = 0; i < (int)nullConstants.size(); ++i) { + constant = nullConstants[i]; + if (constant->getTypeId() == typeId) + existing = constant->getResultId(); + } + + if (existing != NoResult) + return existing; + + // Make it + Instruction* c = new Instruction(getUniqueId(), typeId, OpConstantNull); + constantsTypesGlobals.push_back(std::unique_ptr(c)); + nullConstants.push_back(c); + module.mapInstruction(c); + + return c->getResultId(); +} + Id Builder::makeBoolConstant(bool b, bool specConstant) { Id typeId = makeBoolType(); @@ -908,6 +1015,10 @@ Id Builder::makeFloatConstant(float f, bool specConstant) Id Builder::makeDoubleConstant(double d, bool specConstant) { +#ifdef GLSLANG_WEB + assert(0); + return NoResult; +#else Op opcode = specConstant ? OpSpecConstant : OpConstant; Id typeId = makeFloatType(64); union { double db; unsigned long long ull; } u; @@ -932,10 +1043,15 @@ Id Builder::makeDoubleConstant(double d, bool specConstant) module.mapInstruction(c); return c->getResultId(); +#endif } Id Builder::makeFloat16Constant(float f16, bool specConstant) { +#ifdef GLSLANG_WEB + assert(0); + return NoResult; +#else Op opcode = specConstant ? OpSpecConstant : OpConstant; Id typeId = makeFloatType(16); @@ -960,36 +1076,43 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant) module.mapInstruction(c); return c->getResultId(); +#endif } Id Builder::makeFpConstant(Id type, double d, bool specConstant) { - assert(isFloatType(type)); +#ifdef GLSLANG_WEB + const int width = 32; + assert(width == getScalarTypeWidth(type)); +#else + const int width = getScalarTypeWidth(type); +#endif - switch (getScalarTypeWidth(type)) { - case 16: - return makeFloat16Constant((float)d, specConstant); - case 32: - return makeFloatConstant((float)d, specConstant); - case 64: - return makeDoubleConstant(d, specConstant); - default: - break; - } + assert(isFloatType(type)); - assert(false); - return NoResult; + switch (width) { + case 16: + return makeFloat16Constant((float)d, specConstant); + case 32: + return makeFloatConstant((float)d, specConstant); + case 64: + return makeDoubleConstant(d, specConstant); + default: + break; + } + + assert(false); + return NoResult; } -Id Builder::findCompositeConstant(Op typeClass, const std::vector& comps) +Id Builder::findCompositeConstant(Op typeClass, Id typeId, const std::vector& comps) { Instruction* constant = 0; bool found = false; for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) { constant = groupedConstants[typeClass][i]; - // same shape? - if (constant->getNumOperands() != (int)comps.size()) + if (constant->getTypeId() != typeId) continue; // same contents? @@ -1044,8 +1167,9 @@ Id Builder::makeCompositeConstant(Id typeId, const std::vector& members, boo case OpTypeVector: case OpTypeArray: case OpTypeMatrix: + case OpTypeCooperativeMatrixNV: if (! specConstant) { - Id existing = findCompositeConstant(typeClass, members); + Id existing = findCompositeConstant(typeClass, typeId, members); if (existing) return existing; } @@ -1103,6 +1227,28 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int val executionModes.push_back(std::unique_ptr(instr)); } +void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const std::vector& literals) +{ + Instruction* instr = new Instruction(OpExecutionMode); + instr->addIdOperand(entryPoint->getId()); + instr->addImmediateOperand(mode); + for (auto literal : literals) + instr->addImmediateOperand(literal); + + executionModes.push_back(std::unique_ptr(instr)); +} + +void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const std::vector& operandIds) +{ + Instruction* instr = new Instruction(OpExecutionModeId); + instr->addIdOperand(entryPoint->getId()); + instr->addImmediateOperand(mode); + for (auto operandId : operandIds) + instr->addIdOperand(operandId); + + executionModes.push_back(std::unique_ptr(instr)); +} + void Builder::addName(Id id, const char* string) { Instruction* name = new Instruction(OpName); @@ -1141,7 +1287,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s) if (decoration == spv::DecorationMax) return; - Instruction* dec = new Instruction(OpDecorateStringGOOGLE); + Instruction* dec = new Instruction(OpDecorateString); dec->addIdOperand(id); dec->addImmediateOperand(decoration); dec->addStringOperand(s); @@ -1149,6 +1295,34 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s) decorations.push_back(std::unique_ptr(dec)); } +void Builder::addDecoration(Id id, Decoration decoration, const std::vector& literals) +{ + if (decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpDecorate); + dec->addIdOperand(id); + dec->addImmediateOperand(decoration); + for (auto literal : literals) + dec->addImmediateOperand(literal); + + decorations.push_back(std::unique_ptr(dec)); +} + +void Builder::addDecoration(Id id, Decoration decoration, const std::vector& strings) +{ + if (decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpDecorateString); + dec->addIdOperand(id); + dec->addImmediateOperand(decoration); + for (auto string : strings) + dec->addStringOperand(string); + + decorations.push_back(std::unique_ptr(dec)); +} + void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration) { if (decoration == spv::DecorationMax) @@ -1162,6 +1336,21 @@ void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration) decorations.push_back(std::unique_ptr(dec)); } +void Builder::addDecorationId(Id id, Decoration decoration, const std::vector& operandIds) +{ + if(decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpDecorateId); + dec->addIdOperand(id); + dec->addImmediateOperand(decoration); + + for (auto operandId : operandIds) + dec->addIdOperand(operandId); + + decorations.push_back(std::unique_ptr(dec)); +} + void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num) { if (decoration == spv::DecorationMax) @@ -1191,6 +1380,36 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat decorations.push_back(std::unique_ptr(dec)); } +void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector& literals) +{ + if (decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpMemberDecorate); + dec->addIdOperand(id); + dec->addImmediateOperand(member); + dec->addImmediateOperand(decoration); + for (auto literal : literals) + dec->addImmediateOperand(literal); + + decorations.push_back(std::unique_ptr(dec)); +} + +void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector& strings) +{ + if (decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpMemberDecorateString); + dec->addIdOperand(id); + dec->addImmediateOperand(member); + dec->addImmediateOperand(decoration); + for (auto string : strings) + dec->addStringOperand(string); + + decorations.push_back(std::unique_ptr(dec)); +} + // Comments in header Function* Builder::makeEntryPoint(const char* entryPoint) { @@ -1207,7 +1426,8 @@ Function* Builder::makeEntryPoint(const char* entryPoint) // Comments in header Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, - const std::vector& paramTypes, const std::vector>& decorations, Block **entry) + const std::vector& paramTypes, + const std::vector>& decorations, Block **entry) { // Make the function and initial instructions in it Id typeId = makeFunctionType(returnType, paramTypes); @@ -1216,9 +1436,12 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const // Set up the precisions setPrecision(function->getId(), precision); + function->setReturnPrecision(precision); for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) { - for (int d = 0; d < (int)decorations[p].size(); ++d) + for (int d = 0; d < (int)decorations[p].size(); ++d) { addDecoration(firstParamId + p, decorations[p][d]); + function->addParamPrecision(p, decorations[p][d]); + } } // CFG @@ -1268,18 +1491,20 @@ void Builder::leaveFunction() } // Comments in header -void Builder::makeDiscard() +void Builder::makeStatementTerminator(spv::Op opcode, const char *name) { - buildPoint->addInstruction(std::unique_ptr(new Instruction(OpKill))); - createAndSetNoPredecessorBlock("post-discard"); + buildPoint->addInstruction(std::unique_ptr(new Instruction(opcode))); + createAndSetNoPredecessorBlock(name); } // Comments in header -Id Builder::createVariable(StorageClass storageClass, Id type, const char* name) +Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer) { Id pointerType = makePointer(storageClass, type); Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable); inst->addImmediateOperand(storageClass); + if (initializer != NoResult) + inst->addIdOperand(initializer); switch (storageClass) { case StorageClassFunction: @@ -1295,6 +1520,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name) if (name) addName(inst->getResultId(), name); + setPrecision(inst->getResultId(), precision); return inst->getResultId(); } @@ -1308,7 +1534,8 @@ Id Builder::createUndefined(Id type) } // av/vis/nonprivate are unnecessary and illegal for some storage classes. -spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const +spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) + const { switch (sc) { case spv::StorageClassUniform: @@ -1327,7 +1554,8 @@ spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAc } // Comments in header -void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) +void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, + unsigned int alignment) { Instruction* store = new Instruction(OpStore); store->addIdOperand(lValue); @@ -1349,7 +1577,8 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce } // Comments in header -Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) +Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMask memoryAccess, + spv::Scope scope, unsigned int alignment) { Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad); load->addIdOperand(lValue); @@ -1367,6 +1596,7 @@ Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope } buildPoint->addInstruction(std::unique_ptr(load)); + setPrecision(load->getResultId(), precision); return load->getResultId(); } @@ -1375,16 +1605,7 @@ Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vector& offsets) { // Figure out the final resulting type. - spv::Id typeId = getTypeId(base); - assert(isPointerType(typeId) && offsets.size() > 0); - typeId = getContainedTypeId(typeId); - for (int i = 0; i < (int)offsets.size(); ++i) { - if (isStructType(typeId)) { - assert(isConstantScalar(offsets[i])); - typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i])); - } else - typeId = getContainedTypeId(typeId, offsets[i]); - } + Id typeId = getResultingAccessChainType(); typeId = makePointer(storageClass, typeId); // Make the instruction @@ -1408,12 +1629,30 @@ Id Builder::createArrayLength(Id base, unsigned int member) return length->getResultId(); } +Id Builder::createCooperativeMatrixLength(Id type) +{ + spv::Id intType = makeUintType(32); + + // Generate code for spec constants if in spec constant operation + // generation mode. + if (generatingOpCodeForSpecConst) { + return createSpecConstantOp(OpCooperativeMatrixLengthNV, intType, std::vector(1, type), std::vector()); + } + + Instruction* length = new Instruction(getUniqueId(), intType, OpCooperativeMatrixLengthNV); + length->addIdOperand(type); + buildPoint->addInstruction(std::unique_ptr(length)); + + return length->getResultId(); +} + Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index) { // Generate code for spec constants if in spec constant operation // generation mode. if (generatingOpCodeForSpecConst) { - return createSpecConstantOp(OpCompositeExtract, typeId, std::vector(1, composite), std::vector(1, index)); + return createSpecConstantOp(OpCompositeExtract, typeId, std::vector(1, composite), + std::vector(1, index)); } Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract); extract->addIdOperand(composite); @@ -1615,7 +1854,8 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector& opera return op->getResultId(); } -Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector& operands, const std::vector& literals) +Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector& operands, + const std::vector& literals) { Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp); op->addImmediateOperand((unsigned) opCode); @@ -1758,7 +1998,7 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const // Accept all parameters needed to create a texture instruction. // Create the correct instruction based on the inputs, and make the call. Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, - bool noImplicitLod, const TextureParameters& parameters) + bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask) { static const int maxTextureArgs = 10; Id texArgs[maxTextureArgs] = {}; @@ -1775,7 +2015,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, if (parameters.component != NoResult) texArgs[numArgs++] = parameters.component; -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB if (parameters.granularity != NoResult) texArgs[numArgs++] = parameters.granularity; if (parameters.coarse != NoResult) @@ -1785,8 +2025,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, // // Set up the optional arguments // - int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments - ++numArgs; // speculatively make room for the mask operand + int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments + ++numArgs; // speculatively make room for the mask operand ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand if (parameters.bias) { mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask); @@ -1822,6 +2062,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask); texArgs[numArgs++] = parameters.offsets; } +#ifndef GLSLANG_WEB if (parameters.sample) { mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask); texArgs[numArgs++] = parameters.sample; @@ -1839,6 +2080,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, if (parameters.volatil) { mask = mask | ImageOperandsVolatileTexelKHRMask; } +#endif + mask = mask | signExtensionMask; if (mask == ImageOperandsMaskNone) --numArgs; // undo speculative reservation for the mask argument else @@ -1853,10 +2096,9 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, opCode = OpImageSparseFetch; else opCode = OpImageFetch; -#ifdef NV_EXTENSIONS +#ifndef GLSLANG_WEB } else if (parameters.granularity && parameters.coarse) { opCode = OpImageSampleFootprintNV; -#endif } else if (gather) { if (parameters.Dref) if (sparse) @@ -1868,6 +2110,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, opCode = OpImageSparseGather; else opCode = OpImageGather; +#endif } else if (explicitLod) { if (parameters.Dref) { if (proj) @@ -2016,11 +2259,7 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter break; } case OpImageQueryLod: -#ifdef AMD_EXTENSIONS resultType = makeVectorType(getScalarTypeId(getTypeId(parameters.coords)), 2); -#else - resultType = makeVectorType(makeFloatType(32), 2); -#endif break; case OpImageQueryLevels: case OpImageQuerySamples: @@ -2038,6 +2277,7 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter if (parameters.lod) query->addIdOperand(parameters.lod); buildPoint->addInstruction(std::unique_ptr(query)); + addCapability(CapabilityImageQuery); return query->getResultId(); } @@ -2062,7 +2302,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b Op op; switch (getMostBasicTypeClass(valueType)) { case OpTypeFloat: - op = equal ? OpFOrdEqual : OpFOrdNotEqual; + op = equal ? OpFOrdEqual : OpFUnordNotEqual; break; case OpTypeInt: default: @@ -2105,7 +2345,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b if (constituent == 0) resultId = subResultId; else - resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision); + resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), + precision); } return resultId; @@ -2114,7 +2355,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b // OpCompositeConstruct Id Builder::createCompositeConstruct(Id typeId, const std::vector& constituents) { - assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && getNumTypeConstituents(typeId) == (int)constituents.size())); + assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && + getNumTypeConstituents(typeId) == (int)constituents.size())); if (generatingOpCodeForSpecConst) { // Sometime, even in spec-constant-op mode, the constant composite to be @@ -2231,7 +2473,12 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& int numRows = getTypeNumRows(resultTypeId); Instruction* instr = module.getInstruction(componentTypeId); - unsigned bitCount = instr->getImmediateOperand(0); +#ifdef GLSLANG_WEB + const unsigned bitCount = 32; + assert(bitCount == instr->getImmediateOperand(0)); +#else + const unsigned bitCount = instr->getImmediateOperand(0); +#endif // Optimize matrix constructed from a bigger matrix if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) { @@ -2307,7 +2554,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& int row = 0; int col = 0; - for (int arg = 0; arg < (int)sources.size(); ++arg) { + for (int arg = 0; arg < (int)sources.size() && col < numCols; ++arg) { Id argComp = sources[arg]; for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) { if (getNumComponents(sources[arg]) > 1) { @@ -2319,6 +2566,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& row = 0; col++; } + if (col == numCols) { + // If more components are provided than fit the matrix, discard the rest. + break; + } } } } @@ -2522,7 +2773,8 @@ void Builder::clearAccessChain() } // Comments in header -void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment) +void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, + AccessChain::CoherentFlags coherentFlags, unsigned int alignment) { accessChain.coherentFlags |= coherentFlags; accessChain.alignment |= alignment; @@ -2548,35 +2800,70 @@ void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizz } // Comments in header -void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) +void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) { assert(accessChain.isRValue == false); transferAccessChainSwizzle(true); - Id base = collapseAccessChain(); - Id source = rvalue; - // dynamic component should be gone - assert(accessChain.component == NoResult); + // If a swizzle exists and is not full and is not dynamic, then the swizzle will be broken into individual stores. + if (accessChain.swizzle.size() > 0 && + getNumTypeComponents(getResultingAccessChainType()) != (int)accessChain.swizzle.size() && + accessChain.component == NoResult) { + for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) { + accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle[i])); + accessChain.instr = NoResult; - // If swizzle still exists, it is out-of-order or not full, we must load the target vector, - // extract and insert elements to perform writeMask and/or swizzle. - if (accessChain.swizzle.size() > 0) { - Id tempBaseId = createLoad(base); - source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle); + Id base = collapseAccessChain(); + addDecoration(base, nonUniform); + + accessChain.indexChain.pop_back(); + accessChain.instr = NoResult; + + // dynamic component should be gone + assert(accessChain.component == NoResult); + + Id source = createCompositeExtract(rvalue, getContainedTypeId(getTypeId(rvalue)), i); + + // take LSB of alignment + alignment = alignment & ~(alignment & (alignment-1)); + if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) { + memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask); + } + + createStore(source, base, memoryAccess, scope, alignment); + } } + else { + Id base = collapseAccessChain(); + addDecoration(base, nonUniform); - // take LSB of alignment - alignment = alignment & ~(alignment & (alignment-1)); - if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) { - memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask); + Id source = rvalue; + + // dynamic component should be gone + assert(accessChain.component == NoResult); + + // If swizzle still exists, it may be out-of-order, we must load the target vector, + // extract and insert elements to perform writeMask and/or swizzle. + if (accessChain.swizzle.size() > 0) { + Id tempBaseId = createLoad(base, spv::NoPrecision); + source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle); + } + + // take LSB of alignment + alignment = alignment & ~(alignment & (alignment-1)); + if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) { + memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask); + } + + createStore(source, base, memoryAccess, scope, alignment); } - - createStore(source, base, memoryAccess, scope, alignment); } // Comments in header -Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) +Id Builder::accessChainLoad(Decoration precision, Decoration l_nonUniform, + Decoration r_nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, + spv::Scope scope, unsigned int alignment) { Id id; @@ -2598,23 +2885,31 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu } } - if (constant) + if (constant) { id = createCompositeExtract(accessChain.base, swizzleBase, indexes); - else { - // make a new function variable for this r-value - Id lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable"); - - // store into it - createStore(accessChain.base, lValue); - + setPrecision(id, precision); + } else { + Id lValue = NoResult; + if (spvVersion >= Spv_1_4 && isValidInitializer(accessChain.base)) { + // make a new function variable for this r-value, using an initializer, + // and mark it as NonWritable so that downstream it can be detected as a lookup + // table + lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base), + "indexable", accessChain.base); + addDecoration(lValue, DecorationNonWritable); + } else { + lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base), + "indexable"); + // store into it + createStore(accessChain.base, lValue); + } // move base to the new variable accessChain.base = lValue; accessChain.isRValue = false; // load through the access chain - id = createLoad(collapseAccessChain()); + id = createLoad(collapseAccessChain(), precision); } - setPrecision(id, precision); } else id = accessChain.base; // no precision, it was set when this was defined } else { @@ -2627,9 +2922,14 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu } // load through the access chain - id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment); - setPrecision(id, precision); - addDecoration(id, nonUniform); + id = collapseAccessChain(); + // Apply nonuniform both to the access chain and the loaded value. + // Buffer accesses need the access chain decorated, and this is where + // loaded image types get decorated. TODO: This should maybe move to + // createImageTextureFunctionCall. + addDecoration(id, l_nonUniform); + id = createLoad(id, precision, memoryAccess, scope, alignment); + addDecoration(id, r_nonUniform); } // Done, unless there are swizzles to do @@ -2650,7 +2950,7 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu if (accessChain.component != NoResult) id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision); - addDecoration(id, nonUniform); + addDecoration(id, r_nonUniform); return id; } @@ -2908,14 +3208,14 @@ void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control) } void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, - unsigned int dependencyLength) + const std::vector& operands) { Instruction* merge = new Instruction(OpLoopMerge); merge->addIdOperand(mergeBlock->getId()); merge->addIdOperand(continueBlock->getId()); merge->addImmediateOperand(control); - if ((control & LoopControlDependencyLengthMask) != 0) - merge->addImmediateOperand(dependencyLength); + for (int op = 0; op < (int)operands.size(); ++op) + merge->addImmediateOperand(operands[op]); buildPoint->addInstruction(std::unique_ptr(merge)); } @@ -2981,7 +3281,8 @@ void Builder::dumpSourceInstructions(std::vector& out) const dumpSourceInstructions(iItr->first, *iItr->second, out); } -void Builder::dumpInstructions(std::vector& out, const std::vector >& instructions) const +void Builder::dumpInstructions(std::vector& out, + const std::vector >& instructions) const { for (int i = 0; i < (int)instructions.size(); ++i) { instructions[i]->dump(out); diff --git a/thirdparty/ShaderCompiler/spirv/SpvBuilder.h b/thirdparty/ShaderCompiler/spirv/SpvBuilder.h index edeac1b..251b9ee 100644 --- a/thirdparty/ShaderCompiler/spirv/SpvBuilder.h +++ b/thirdparty/ShaderCompiler/spirv/SpvBuilder.h @@ -1,7 +1,8 @@ // // Copyright (C) 2014-2015 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -61,6 +62,15 @@ namespace spv { +typedef enum { + Spv_1_0 = (1 << 16), + Spv_1_1 = (1 << 16) | (1 << 8), + Spv_1_2 = (1 << 16) | (2 << 8), + Spv_1_3 = (1 << 16) | (3 << 8), + Spv_1_4 = (1 << 16) | (4 << 8), + Spv_1_5 = (1 << 16) | (5 << 8), +} SpvVersion; + class Builder { public: Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger); @@ -85,6 +95,7 @@ public: const char* file_c_str = str.c_str(); fileString->addStringOperand(file_c_str); strings.push_back(std::unique_ptr(fileString)); + module.mapInstruction(fileString); stringIds[file_c_str] = strId; return strId; } @@ -97,6 +108,20 @@ public: void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); } void setEmitOpLines() { emitOpLines = true; } void addExtension(const char* ext) { extensions.insert(ext); } + void removeExtension(const char* ext) + { + extensions.erase(ext); + } + void addIncorporatedExtension(const char* ext, SpvVersion incorporatedVersion) + { + if (getSpvVersion() < static_cast(incorporatedVersion)) + addExtension(ext); + } + void promoteIncorporatedExtension(const char* baseExt, const char* promoExt, SpvVersion incorporatedVersion) + { + removeExtension(baseExt); + addIncorporatedExtension(promoExt, incorporatedVersion); + } void addInclude(const std::string& name, const std::string& text) { spv::Id incId = getStringId(name); @@ -155,9 +180,12 @@ public: Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format); Id makeSamplerType(); Id makeSampledImageType(Id imageType); + Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols); // accelerationStructureNV type - Id makeAccelerationStructureNVType(); + Id makeAccelerationStructureType(); + // rayQueryEXT type + Id makeRayQueryType(); // For querying about types. Id getTypeId(Id resultId) const { return module.getTypeId(resultId); } @@ -172,26 +200,40 @@ public: Id getContainedTypeId(Id typeId) const; Id getContainedTypeId(Id typeId, int) const; StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); } - ImageFormat getImageTypeFormat(Id typeId) const { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); } + ImageFormat getImageTypeFormat(Id typeId) const + { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); } + Id getResultingAccessChainType() const; bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); } bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); } bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); } bool isMatrix(Id resultId) const { return isMatrixType(getTypeId(resultId)); } + bool isCooperativeMatrix(Id resultId)const { return isCooperativeMatrixType(getTypeId(resultId)); } bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); } bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); } - bool isBoolType(Id typeId) { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); } - bool isIntType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; } - bool isUintType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; } + bool isBoolType(Id typeId) + { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); } + bool isIntType(Id typeId) const + { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; } + bool isUintType(Id typeId) const + { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; } bool isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; } bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; } - bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; } + bool isScalarType(Id typeId) const + { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || + getTypeClass(typeId) == OpTypeBool; } bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; } bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; } bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; } bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; } - bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId); } +#ifdef GLSLANG_WEB + bool isCooperativeMatrixType(Id typeId)const { return false; } +#else + bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; } +#endif + bool isAggregateType(Id typeId) const + { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); } bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; } bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; } bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; } @@ -203,9 +245,17 @@ public: bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); } bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; } bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); } - unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); } + unsigned int getConstantScalar(Id resultId) const + { return module.getInstruction(resultId)->getImmediateOperand(0); } StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); } + bool isVariableOpCode(Op opcode) const { return opcode == OpVariable; } + bool isVariable(Id resultId) const { return isVariableOpCode(getOpCode(resultId)); } + bool isGlobalStorage(Id resultId) const { return getStorageClass(resultId) != StorageClassFunction; } + bool isGlobalVariable(Id resultId) const { return isVariable(resultId) && isGlobalStorage(resultId); } + // See if a resultId is valid for use as an initializer. + bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); } + int getScalarTypeWidth(Id typeId) const { Id scalarTypeId = getScalarTypeId(typeId); @@ -244,15 +294,24 @@ public: } // For making new constants (will return old constant if the requested one was already made). + Id makeNullConstant(Id typeId); Id makeBoolConstant(bool b, bool specConstant = false); - Id makeInt8Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); } - Id makeUint8Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(8), u, specConstant); } - Id makeInt16Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); } - Id makeUint16Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(16), u, specConstant); } - Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); } - Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); } - Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); } - Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); } + Id makeInt8Constant(int i, bool specConstant = false) + { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); } + Id makeUint8Constant(unsigned u, bool specConstant = false) + { return makeIntConstant(makeUintType(8), u, specConstant); } + Id makeInt16Constant(int i, bool specConstant = false) + { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); } + Id makeUint16Constant(unsigned u, bool specConstant = false) + { return makeIntConstant(makeUintType(16), u, specConstant); } + Id makeIntConstant(int i, bool specConstant = false) + { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); } + Id makeUintConstant(unsigned u, bool specConstant = false) + { return makeIntConstant(makeUintType(32), u, specConstant); } + Id makeInt64Constant(long long i, bool specConstant = false) + { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); } + Id makeUint64Constant(unsigned long long u, bool specConstant = false) + { return makeInt64Constant(makeUintType(64), u, specConstant); } Id makeFloatConstant(float f, bool specConstant = false); Id makeDoubleConstant(double d, bool specConstant = false); Id makeFloat16Constant(float f16, bool specConstant = false); @@ -264,13 +323,20 @@ public: // Methods for adding information outside the CFG. Instruction* addEntryPoint(ExecutionModel, Function*, const char* name); void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1); + void addExecutionMode(Function*, ExecutionMode mode, const std::vector& literals); + void addExecutionModeId(Function*, ExecutionMode mode, const std::vector& operandIds); void addName(Id, const char* name); void addMemberName(Id, int member, const char* name); void addDecoration(Id, Decoration, int num = -1); void addDecoration(Id, Decoration, const char*); + void addDecoration(Id, Decoration, const std::vector& literals); + void addDecoration(Id, Decoration, const std::vector& strings); void addDecorationId(Id id, Decoration, Id idDecoration); + void addDecorationId(Id id, Decoration, const std::vector& operandIds); void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1); void addMemberDecoration(Id, unsigned int member, Decoration, const char*); + void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector& literals); + void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector& strings); // At the end of what block do the next create*() instructions go? void setBuildPoint(Block* bp) { buildPoint = bp; } @@ -283,8 +349,8 @@ public: // Make a shader-style function, and create its entry block if entry is non-zero. // Return the function, pass back the entry. // The returned pointer is only valid for the lifetime of this builder. - Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector& paramTypes, - const std::vector>& precisions, Block **entry = 0); + Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, + const std::vector& paramTypes, const std::vector>& precisions, Block **entry = 0); // Create a return. An 'implicit' return is one not appearing in the source // code. In the case of an implicit return, no post-return block is inserted. @@ -293,20 +359,25 @@ public: // Generate all the code needed to finish up a function. void leaveFunction(); - // Create a discard. - void makeDiscard(); + // Create block terminator instruction for certain statements like + // discard, terminate-invocation, terminateRayEXT, or ignoreIntersectionEXT + void makeStatementTerminator(spv::Op opcode, const char *name); // Create a global or function local or IO variable. - Id createVariable(StorageClass, Id type, const char* name = 0); + Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr, + Id initializer = NoResult); // Create an intermediate with an undefined value. Id createUndefined(Id type); // Store into an Id and return the l-value - void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); + void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, + spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // Load from an Id and return it - Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); + Id createLoad(Id lValue, spv::Decoration precision, + spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, + spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // Create an OpAccessChain instruction Id createAccessChain(StorageClass, Id base, const std::vector& offsets); @@ -314,6 +385,9 @@ public: // Create an OpArrayLength instruction Id createArrayLength(Id base, unsigned int member); + // Create an OpCooperativeMatrixLengthNV instruction + Id createCooperativeMatrixLength(Id type); + // Create an OpCompositeExtract instruction Id createCompositeExtract(Id composite, Id typeId, unsigned index); Id createCompositeExtract(Id composite, Id typeId, const std::vector& indexes); @@ -402,7 +476,8 @@ public: }; // Select the correct texture operation based on all inputs, and emit the correct instruction - Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicit, const TextureParameters&); + Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, + bool noImplicit, const TextureParameters&, ImageOperandsMask); // Emit the OpTextureQuery* instruction that was passed in. // Figure out the right return value and type, and return it. @@ -461,7 +536,7 @@ public: // recursion stack can hold the memory for it. // void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector& caseValues, - const std::vector& valueToSegment, int defaultSegment, std::vector& segmentBB); // return argument + const std::vector& valueToSegment, int defaultSegment, std::vector& segmentBB); // Add a branch to the innermost switch's merge block. void addSwitchBreak(); @@ -478,7 +553,7 @@ public: Block &head, &body, &merge, &continue_target; private: LoopBlocks(); - LoopBlocks& operator=(const LoopBlocks&); + LoopBlocks& operator=(const LoopBlocks&) = delete; }; // Start a new loop and prepare the builder to generate code for it. Until @@ -535,21 +610,39 @@ public: std::vector indexChain; Id instr; // cache the instruction that generates this access chain std::vector swizzle; // each std::vector element selects the next GLSL component number - Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present - Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present + Id component; // a dynamic component index, can coexist with a swizzle, + // done after the swizzle, NoResult if not present + Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; + // NoType unless a swizzle or component is present bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value - unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. Only tracks base and (optional) component selection alignment. + unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. + // Only tracks base and (optional) component selection alignment. // Accumulate whether anything in the chain of structures has coherent decorations. struct CoherentFlags { + CoherentFlags() { clear(); } +#ifdef GLSLANG_WEB + void clear() { } + bool isVolatile() const { return false; } + CoherentFlags operator |=(const CoherentFlags &other) { return *this; } +#else + bool isVolatile() const { return volatil; } + bool isNonUniform() const { return nonUniform; } + bool anyCoherent() const { + return coherent || devicecoherent || queuefamilycoherent || workgroupcoherent || + subgroupcoherent || shadercallcoherent; + } + unsigned coherent : 1; unsigned devicecoherent : 1; unsigned queuefamilycoherent : 1; unsigned workgroupcoherent : 1; unsigned subgroupcoherent : 1; + unsigned shadercallcoherent : 1; unsigned nonprivate : 1; unsigned volatil : 1; unsigned isImage : 1; + unsigned nonUniform : 1; void clear() { coherent = 0; @@ -557,23 +650,27 @@ public: queuefamilycoherent = 0; workgroupcoherent = 0; subgroupcoherent = 0; + shadercallcoherent = 0; nonprivate = 0; volatil = 0; isImage = 0; + nonUniform = 0; } - CoherentFlags() { clear(); } CoherentFlags operator |=(const CoherentFlags &other) { coherent |= other.coherent; devicecoherent |= other.devicecoherent; queuefamilycoherent |= other.queuefamilycoherent; workgroupcoherent |= other.workgroupcoherent; subgroupcoherent |= other.subgroupcoherent; + shadercallcoherent |= other.shadercallcoherent; nonprivate |= other.nonprivate; volatil |= other.volatil; isImage |= other.isImage; + nonUniform |= other.nonUniform; return *this; } +#endif }; CoherentFlags coherentFlags; }; @@ -613,11 +710,13 @@ public: } // push new swizzle onto the end of any existing swizzle, merging into a single swizzle - void accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment); + void accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, + AccessChain::CoherentFlags coherentFlags, unsigned int alignment); // push a dynamic component selection onto the access chain, only applicable with a // non-trivial swizzle or no swizzle - void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment) + void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, + unsigned int alignment) { if (accessChain.swizzle.size() != 1) { accessChain.component = component; @@ -629,10 +728,19 @@ public: } // use accessChain and swizzle to store value - void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); + void accessChainStore(Id rvalue, Decoration nonUniform, + spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, + spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // use accessChain and swizzle to load an r-value - Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); + Id accessChainLoad(Decoration precision, Decoration l_nonUniform, Decoration r_nonUniform, Id ResultType, + spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, + unsigned int alignment = 0); + + // Return whether or not the access chain can be represented in SPIR-V + // as an l-value. + // E.g., a[3].yx cannot be, while a[3].y and a[3].y[x] can be. + bool isSpvLvalue() const { return accessChain.swizzle.size() <= 1; } // get the direct pointer for an l-value Id accessChainGetLValue(); @@ -641,22 +749,28 @@ public: // based on the type of the base and the chain of dereferences. Id accessChainGetInferredType(); - // Add capabilities, extensions, remove unneeded decorations, etc., + // Add capabilities, extensions, remove unneeded decorations, etc., // based on the resulting SPIR-V. void postProcess(); + // Prune unreachable blocks in the CFG and remove unneeded decorations. + void postProcessCFG(); + +#ifndef GLSLANG_WEB + // Add capabilities, extensions based on instructions in the module. + void postProcessFeatures(); // Hook to visit each instruction in a block in a function void postProcess(Instruction&); - // Hook to visit each instruction in a reachable block in a function. - void postProcessReachable(const Instruction&); // Hook to visit each non-32-bit sized float/int operation in a block. void postProcessType(const Instruction&, spv::Id typeId); +#endif void dump(std::vector&) const; void createBranch(Block* block); void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock); - void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, unsigned int dependencyLength); + void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, + const std::vector& operands); // Sets to generate opcode for specialization constants. void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; } @@ -670,7 +784,7 @@ public: Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant); Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value); Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2); - Id findCompositeConstant(Op typeClass, const std::vector& comps); + Id findCompositeConstant(Op typeClass, Id typeId, const std::vector& comps); Id findStructConstant(Id typeId, const std::vector& comps); Id collapseAccessChain(); void remapDynamicSwizzle(); @@ -682,7 +796,8 @@ public: void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector&) const; void dumpInstructions(std::vector&, const std::vector >&) const; void dumpModuleProcesses(std::vector&) const; - spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const; + spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) + const; unsigned int spvVersion; // the version of SPIR-V to emit in the header SourceLanguage source; @@ -717,10 +832,16 @@ public: std::vector > externals; std::vector > functions; - // not output, internally used for quick & dirty canonical (unique) creation - std::unordered_map> groupedConstants; // map type opcodes to constant inst. - std::unordered_map> groupedStructConstants; // map struct-id to constant instructions - std::unordered_map> groupedTypes; // map type opcodes to type instructions + // not output, internally used for quick & dirty canonical (unique) creation + + // map type opcodes to constant inst. + std::unordered_map> groupedConstants; + // map struct-id to constant instructions + std::unordered_map> groupedStructConstants; + // map type opcodes to type instructions + std::unordered_map> groupedTypes; + // list of OpConstantNull instructions + std::vector nullConstants; // stack of switches std::stack switchMerges; diff --git a/thirdparty/ShaderCompiler/spirv/SpvPostProcess.cpp b/thirdparty/ShaderCompiler/spirv/SpvPostProcess.cpp index d4924f6..23d7b5a 100644 --- a/thirdparty/ShaderCompiler/spirv/SpvPostProcess.cpp +++ b/thirdparty/ShaderCompiler/spirv/SpvPostProcess.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -51,16 +52,13 @@ namespace spv { #include "GLSL.std.450.h" #include "GLSL.ext.KHR.h" #include "GLSL.ext.EXT.h" -#ifdef AMD_EXTENSIONS #include "GLSL.ext.AMD.h" -#endif -#ifdef NV_EXTENSIONS #include "GLSL.ext.NV.h" -#endif } namespace spv { +#ifndef GLSLANG_WEB // Hook to visit each operand type and result type of an instruction. // Will be called multiple times for one instruction, once for each typed // operand and the result. @@ -118,12 +116,48 @@ void Builder::postProcessType(const Instruction& inst, Id typeId) case OpAccessChain: case OpPtrAccessChain: case OpCopyObject: + break; case OpFConvert: case OpSConvert: case OpUConvert: + // Look for any 8/16-bit storage capabilities. If there are none, assume that + // the convert instruction requires the Float16/Int8/16 capability. + if (containsType(typeId, OpTypeFloat, 16) || containsType(typeId, OpTypeInt, 16)) { + bool foundStorage = false; + for (auto it = capabilities.begin(); it != capabilities.end(); ++it) { + spv::Capability cap = *it; + if (cap == spv::CapabilityStorageInputOutput16 || + cap == spv::CapabilityStoragePushConstant16 || + cap == spv::CapabilityStorageUniformBufferBlock16 || + cap == spv::CapabilityStorageUniform16) { + foundStorage = true; + break; + } + } + if (!foundStorage) { + if (containsType(typeId, OpTypeFloat, 16)) + addCapability(CapabilityFloat16); + if (containsType(typeId, OpTypeInt, 16)) + addCapability(CapabilityInt16); + } + } + if (containsType(typeId, OpTypeInt, 8)) { + bool foundStorage = false; + for (auto it = capabilities.begin(); it != capabilities.end(); ++it) { + spv::Capability cap = *it; + if (cap == spv::CapabilityStoragePushConstant8 || + cap == spv::CapabilityUniformAndStorageBuffer8BitAccess || + cap == spv::CapabilityStorageBuffer8BitAccess) { + foundStorage = true; + break; + } + } + if (!foundStorage) { + addCapability(CapabilityInt8); + } + } break; case OpExtInst: -#if AMD_EXTENSIONS switch (inst.getImmediateOperand(1)) { case GLSLstd450Frexp: case GLSLstd450FrexpStruct: @@ -139,7 +173,6 @@ void Builder::postProcessType(const Instruction& inst, Id typeId) default: break; } -#endif break; default: if (basicTypeOp == OpTypeFloat && width == 16) @@ -185,12 +218,10 @@ void Builder::postProcess(Instruction& inst) addCapability(CapabilityImageQuery); break; -#ifdef NV_EXTENSIONS case OpGroupNonUniformPartitionNV: addExtension(E_SPV_NV_shader_subgroup_partitioned); addCapability(CapabilityGroupNonUniformPartitionedNV); break; -#endif case OpLoad: case OpStore: @@ -258,10 +289,9 @@ void Builder::postProcess(Instruction& inst) assert(inst.getNumOperands() >= 3); unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1); assert(memoryAccess & MemoryAccessAlignedMask); + static_cast(memoryAccess); // Compute the index of the alignment operand. int alignmentIdx = 2; - if (memoryAccess & MemoryAccessVolatileMask) - alignmentIdx++; if (inst.getOpCode() == OpStore) alignmentIdx++; // Merge new and old (mis)alignment @@ -290,17 +320,16 @@ void Builder::postProcess(Instruction& inst) } } } - -// Called for each instruction in a reachable block. -void Builder::postProcessReachable(const Instruction&) -{ - // did have code here, but questionable to do so without deleting the instructions -} +#endif // comment in header -void Builder::postProcess() +void Builder::postProcessCFG() { + // reachableBlocks is the set of blockss reached via control flow, or which are + // unreachable continue targert or unreachable merge. std::unordered_set reachableBlocks; + std::unordered_map headerForUnreachableContinue; + std::unordered_set unreachableMerges; std::unordered_set unreachableDefinitions; // Collect IDs defined in unreachable blocks. For each function, label the // reachable blocks first. Then for each unreachable block, collect the @@ -308,16 +337,41 @@ void Builder::postProcess() for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) { Function* f = *fi; Block* entry = f->getEntryBlock(); - inReadableOrder(entry, [&reachableBlocks](const Block* b) { reachableBlocks.insert(b); }); + inReadableOrder(entry, + [&reachableBlocks, &unreachableMerges, &headerForUnreachableContinue] + (Block* b, ReachReason why, Block* header) { + reachableBlocks.insert(b); + if (why == ReachDeadContinue) headerForUnreachableContinue[b] = header; + if (why == ReachDeadMerge) unreachableMerges.insert(b); + }); for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) { Block* b = *bi; - if (reachableBlocks.count(b) == 0) { - for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++) + if (unreachableMerges.count(b) != 0 || headerForUnreachableContinue.count(b) != 0) { + auto ii = b->getInstructions().cbegin(); + ++ii; // Keep potential decorations on the label. + for (; ii != b->getInstructions().cend(); ++ii) + unreachableDefinitions.insert(ii->get()->getResultId()); + } else if (reachableBlocks.count(b) == 0) { + // The normal case for unreachable code. All definitions are considered dead. + for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ++ii) unreachableDefinitions.insert(ii->get()->getResultId()); } } } + // Modify unreachable merge blocks and unreachable continue targets. + // Delete their contents. + for (auto mergeIter = unreachableMerges.begin(); mergeIter != unreachableMerges.end(); ++mergeIter) { + (*mergeIter)->rewriteAsCanonicalUnreachableMerge(); + } + for (auto continueIter = headerForUnreachableContinue.begin(); + continueIter != headerForUnreachableContinue.end(); + ++continueIter) { + Block* continue_target = continueIter->first; + Block* header = continueIter->second; + continue_target->rewriteAsCanonicalUnreachableContinue(header); + } + // Remove unneeded decorations, for unreachable instructions decorations.erase(std::remove_if(decorations.begin(), decorations.end(), [&unreachableDefinitions](std::unique_ptr& I) -> bool { @@ -325,14 +379,29 @@ void Builder::postProcess() return unreachableDefinitions.count(decoration_id) != 0; }), decorations.end()); +} +#ifndef GLSLANG_WEB +// comment in header +void Builder::postProcessFeatures() { // Add per-instruction capabilities, extensions, etc., - // process all reachable instructions... - for (auto bi = reachableBlocks.cbegin(); bi != reachableBlocks.cend(); ++bi) { - const Block* block = *bi; - const auto function = [this](const std::unique_ptr& inst) { postProcessReachable(*inst.get()); }; - std::for_each(block->getInstructions().begin(), block->getInstructions().end(), function); + // Look for any 8/16 bit type in physical storage buffer class, and set the + // appropriate capability. This happens in createSpvVariable for other storage + // classes, but there isn't always a variable for physical storage buffer. + for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) { + Instruction* type = groupedTypes[OpTypePointer][t]; + if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) { + if (containsType(type->getIdOperand(1), OpTypeInt, 8)) { + addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5); + addCapability(spv::CapabilityStorageBuffer8BitAccess); + } + if (containsType(type->getIdOperand(1), OpTypeInt, 16) || + containsType(type->getIdOperand(1), OpTypeFloat, 16)) { + addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); + addCapability(spv::CapabilityStorageBuffer16BitAccess); + } + } } // process all block-contained instructions @@ -368,23 +437,46 @@ void Builder::postProcess() } } - // Look for any 8/16 bit type in physical storage buffer class, and set the - // appropriate capability. This happens in createSpvVariable for other storage - // classes, but there isn't always a variable for physical storage buffer. - for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) { - Instruction* type = groupedTypes[OpTypePointer][t]; - if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) { - if (containsType(type->getIdOperand(1), OpTypeInt, 8)) { - addExtension(spv::E_SPV_KHR_8bit_storage); - addCapability(spv::CapabilityStorageBuffer8BitAccess); - } - if (containsType(type->getIdOperand(1), OpTypeInt, 16) || - containsType(type->getIdOperand(1), OpTypeFloat, 16)) { - addExtension(spv::E_SPV_KHR_16bit_storage); - addCapability(spv::CapabilityStorageBuffer16BitAccess); - } + // If any Vulkan memory model-specific functionality is used, update the + // OpMemoryModel to match. + if (capabilities.find(spv::CapabilityVulkanMemoryModelKHR) != capabilities.end()) { + memoryModel = spv::MemoryModelVulkanKHR; + addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5); + } + + // Add Aliased decoration if there's more than one Workgroup Block variable. + if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) { + assert(entryPoints.size() == 1); + auto &ep = entryPoints[0]; + + std::vector workgroup_variables; + for (int i = 0; i < (int)ep->getNumOperands(); i++) { + if (!ep->isIdOperand(i)) + continue; + + const Id id = ep->getIdOperand(i); + const Instruction *instr = module.getInstruction(id); + if (instr->getOpCode() != spv::OpVariable) + continue; + + if (instr->getImmediateOperand(0) == spv::StorageClassWorkgroup) + workgroup_variables.push_back(id); + } + + if (workgroup_variables.size() > 1) { + for (size_t i = 0; i < workgroup_variables.size(); i++) + addDecoration(workgroup_variables[i], spv::DecorationAliased); } } } +#endif + +// comment in header +void Builder::postProcess() { + postProcessCFG(); +#ifndef GLSLANG_WEB + postProcessFeatures(); +#endif +} }; // end spv namespace diff --git a/thirdparty/ShaderCompiler/spirv/SpvTools.cpp b/thirdparty/ShaderCompiler/spirv/SpvTools.cpp index eec06e0..8acf9b1 100644 --- a/thirdparty/ShaderCompiler/spirv/SpvTools.cpp +++ b/thirdparty/ShaderCompiler/spirv/SpvTools.cpp @@ -1,6 +1,6 @@ // // Copyright (C) 2014-2016 LunarG, Inc. -// Copyright (C) 2018 Google, Inc. +// Copyright (C) 2018-2020 Google, Inc. // // All rights reserved. // @@ -44,7 +44,6 @@ #include "SpvTools.h" #include "spirv-tools/optimizer.hpp" -#include "spirv-tools/libspirv.h" namespace glslang { @@ -52,8 +51,23 @@ namespace glslang { spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger) { switch (spvVersion.vulkan) { - case glslang::EShTargetVulkan_1_0: return spv_target_env::SPV_ENV_VULKAN_1_0; - case glslang::EShTargetVulkan_1_1: return spv_target_env::SPV_ENV_VULKAN_1_1; + case glslang::EShTargetVulkan_1_0: + return spv_target_env::SPV_ENV_VULKAN_1_0; + case glslang::EShTargetVulkan_1_1: + switch (spvVersion.spv) { + case EShTargetSpv_1_0: + case EShTargetSpv_1_1: + case EShTargetSpv_1_2: + case EShTargetSpv_1_3: + return spv_target_env::SPV_ENV_VULKAN_1_1; + case EShTargetSpv_1_4: + return spv_target_env::SPV_ENV_VULKAN_1_1_SPIRV_1_4; + default: + logger->missingFunctionality("Target version for SPIRV-Tools validator"); + return spv_target_env::SPV_ENV_VULKAN_1_1; + } + case glslang::EShTargetVulkan_1_2: + return spv_target_env::SPV_ENV_VULKAN_1_2; default: break; } @@ -65,12 +79,52 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog return spv_target_env::SPV_ENV_UNIVERSAL_1_0; } +// Callback passed to spvtools::Optimizer::SetMessageConsumer +void OptimizerMesssageConsumer(spv_message_level_t level, const char *source, + const spv_position_t &position, const char *message) +{ + auto &out = std::cerr; + switch (level) + { + case SPV_MSG_FATAL: + case SPV_MSG_INTERNAL_ERROR: + case SPV_MSG_ERROR: + out << "error: "; + break; + case SPV_MSG_WARNING: + out << "warning: "; + break; + case SPV_MSG_INFO: + case SPV_MSG_DEBUG: + out << "info: "; + break; + default: + break; + } + if (source) + { + out << source << ":"; + } + out << position.line << ":" << position.column << ":" << position.index << ":"; + if (message) + { + out << " " << message; + } + out << std::endl; +} -// Use the SPIRV-Tools disassembler to print SPIR-V. +// Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment. void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv) +{ + SpirvToolsDisassemble(out, spirv, spv_target_env::SPV_ENV_UNIVERSAL_1_3); +} + +// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment. +void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv, + spv_target_env requested_context) { // disassemble - spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3); + spv_context context = spvContextCreate(requested_context); spv_text text; spv_diagnostic diagnostic = nullptr; spvBinaryToText(context, spirv.data(), spirv.size(), @@ -90,7 +144,7 @@ void SpirvToolsDisassemble(std::ostream& out, const std::vector& s // Apply the SPIRV-Tools validator to generated SPIR-V. void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector& spirv, - spv::SpvBuildLogger* logger) + spv::SpvBuildLogger* logger, bool prelegalization) { // validate spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); @@ -98,6 +152,9 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector< spv_diagnostic diagnostic = nullptr; spv_validator_options options = spvValidatorOptionsCreate(); spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets()); + spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization); + spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout()); + spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout()); spvValidateWithOptions(context, options, &binary, &diagnostic); // report @@ -112,53 +169,23 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector< spvContextDestroy(context); } -// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of -// legalizing HLSL SPIR-V. -void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector& spirv, - spv::SpvBuildLogger*, const SpvOptions* options) +// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process. +void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger* logger, const SpvOptions* options) { - spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2; + spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger); spvtools::Optimizer optimizer(target_env); - optimizer.SetMessageConsumer( - [](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) { - auto &out = std::cerr; - switch (level) - { - case SPV_MSG_FATAL: - case SPV_MSG_INTERNAL_ERROR: - case SPV_MSG_ERROR: - out << "error: "; - break; - case SPV_MSG_WARNING: - out << "warning: "; - break; - case SPV_MSG_INFO: - case SPV_MSG_DEBUG: - out << "info: "; - break; - default: - break; - } - if (source) - { - out << source << ":"; - } - out << position.line << ":" << position.column << ":" << position.index << ":"; - if (message) - { - out << " " << message; - } - out << std::endl; - }); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); // If debug (specifically source line info) is being generated, propagate // line information into all SPIR-V instructions. This avoids loss of // information when instructions are deleted or moved. Later, remove // redundant information to minimize final SPRIR-V size. - if (options->generateDebugInfo) { - optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass()); + if (options->stripDebugInfo) { + optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass()); } + optimizer.RegisterPass(spvtools::CreateWrapOpKillPass()); optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass()); optimizer.RegisterPass(spvtools::CreateMergeReturnPass()); optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass()); @@ -180,18 +207,36 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); optimizer.RegisterPass(spvtools::CreateVectorDCEPass()); optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass()); + optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass()); if (options->optimizeSize) { optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass()); - // TODO(greg-lunarg): Add this when AMD driver issues are resolved - // optimizer.RegisterPass(CreateCommonUniformElimPass()); } optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); optimizer.RegisterPass(spvtools::CreateCFGCleanupPass()); - if (options->generateDebugInfo) { - optimizer.RegisterPass(spvtools::CreateRedundantLineInfoElimPass()); - } - optimizer.Run(spirv.data(), spirv.size(), &spirv); + spvtools::OptimizerOptions spvOptOptions; + optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); + spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on + optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); +} + +// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by +// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if +// optimization is disabled. +void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate, + std::vector& spirv, spv::SpvBuildLogger* logger) +{ + spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger); + + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); + + optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass()); + + spvtools::OptimizerOptions spvOptOptions; + optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); + spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on + optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); } }; // end namespace glslang diff --git a/thirdparty/ShaderCompiler/spirv/SpvTools.h b/thirdparty/ShaderCompiler/spirv/SpvTools.h index 08bcf3a..d856c52 100644 --- a/thirdparty/ShaderCompiler/spirv/SpvTools.h +++ b/thirdparty/ShaderCompiler/spirv/SpvTools.h @@ -41,8 +41,11 @@ #ifndef GLSLANG_SPV_TOOLS_H #define GLSLANG_SPV_TOOLS_H +#if ENABLE_OPT #include #include +#include "spirv-tools/libspirv.h" +#endif #include "../glslang/MachineIndependent/localintermediate.h" #include "Logger.h" @@ -50,9 +53,10 @@ namespace glslang { struct SpvOptions { - SpvOptions() : generateDebugInfo(false), disableOptimizer(true), + SpvOptions() : generateDebugInfo(false), stripDebugInfo(false), disableOptimizer(true), optimizeSize(false), disassemble(false), validate(false) { } bool generateDebugInfo; + bool stripDebugInfo; bool disableOptimizer; bool optimizeSize; bool disassemble; @@ -61,20 +65,29 @@ struct SpvOptions { #if ENABLE_OPT -// Use the SPIRV-Tools disassembler to print SPIR-V. +// Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment. void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv); +// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment. +void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv, + spv_target_env requested_context); + // Apply the SPIRV-Tools validator to generated SPIR-V. void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector& spirv, - spv::SpvBuildLogger*); + spv::SpvBuildLogger*, bool prelegalization); -// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of -// legalizing HLSL SPIR-V. -void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector& spirv, - spv::SpvBuildLogger*, const SpvOptions*); +// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process. +void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger*, const SpvOptions*); + +// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by +// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if +// optimization is disabled. +void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate, + std::vector& spirv, spv::SpvBuildLogger*); #endif -}; // end namespace glslang +} // end namespace glslang -#endif // GLSLANG_SPV_TOOLS_H \ No newline at end of file +#endif // GLSLANG_SPV_TOOLS_H diff --git a/thirdparty/ShaderCompiler/spirv/disassemble.cpp b/thirdparty/ShaderCompiler/spirv/disassemble.cpp index 631173c..73c988c 100644 --- a/thirdparty/ShaderCompiler/spirv/disassemble.cpp +++ b/thirdparty/ShaderCompiler/spirv/disassemble.cpp @@ -46,32 +46,21 @@ #include "disassemble.h" #include "doc.h" -#include "SpvTools.h" namespace spv { extern "C" { // Include C-based headers that don't have a namespace #include "GLSL.std.450.h" -#ifdef AMD_EXTENSIONS #include "GLSL.ext.AMD.h" -#endif - -#ifdef NV_EXTENSIONS #include "GLSL.ext.NV.h" -#endif } } const char* GlslStd450DebugNames[spv::GLSLstd450Count]; namespace spv { -#ifdef AMD_EXTENSIONS static const char* GLSLextAMDGetDebugNames(const char*, unsigned); -#endif - -#ifdef NV_EXTENSIONS static const char* GLSLextNVGetDebugNames(const char*, unsigned); -#endif static void Kill(std::ostream& out, const char* message) { @@ -82,16 +71,10 @@ static void Kill(std::ostream& out, const char* message) // used to identify the extended instruction library imported when printing enum ExtInstSet { GLSL450Inst, - -#ifdef AMD_EXTENSIONS GLSLextAMDInst, -#endif - -#ifdef NV_EXTENSIONS GLSLextNVInst, -#endif - OpenCLExtInst, + NonSemanticDebugPrintfExtInst, }; // Container class for a single instance of a SPIR-V stream, with methods for disassembly. @@ -497,39 +480,37 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, if (opCode == OpExtInst) { ExtInstSet extInstSet = GLSL450Inst; const char* name = idDescriptor[stream[word - 2]].c_str(); - if (0 == memcmp("OpenCL", name, 6)) { + if (strcmp("OpenCL.std", name) == 0) { extInstSet = OpenCLExtInst; -#ifdef AMD_EXTENSIONS + } else if (strcmp("OpenCL.DebugInfo.100", name) == 0) { + extInstSet = OpenCLExtInst; + } else if (strcmp("NonSemantic.DebugPrintf", name) == 0) { + extInstSet = NonSemanticDebugPrintfExtInst; } else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 || strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 || strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 || strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) { extInstSet = GLSLextAMDInst; -#endif -#ifdef NV_EXTENSIONS - }else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 || + } else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 || strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 || strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 || strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 || strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 || strcmp(spv::E_SPV_NV_mesh_shader, name) == 0) { extInstSet = GLSLextNVInst; -#endif } unsigned entrypoint = stream[word - 1]; if (extInstSet == GLSL450Inst) { if (entrypoint < GLSLstd450Count) { out << "(" << GlslStd450DebugNames[entrypoint] << ")"; } -#ifdef AMD_EXTENSIONS } else if (extInstSet == GLSLextAMDInst) { out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")"; -#endif -#ifdef NV_EXTENSIONS } else if (extInstSet == GLSLextNVInst) { out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")"; -#endif + } else if (extInstSet == NonSemanticDebugPrintfExtInst) { + out << "(DebugPrintf)"; } } break; @@ -537,6 +518,10 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, case OperandLiteralString: numOperands -= disassembleString(); break; + case OperandVariableLiteralStrings: + while (numOperands > 0) + numOperands -= disassembleString(); + return; case OperandMemoryAccess: outputMask(OperandMemoryAccess, stream[word++]); --numOperands; @@ -648,9 +633,11 @@ static void GLSLstd450GetDebugNames(const char** names) names[GLSLstd450InterpolateAtCentroid] = "InterpolateAtCentroid"; names[GLSLstd450InterpolateAtSample] = "InterpolateAtSample"; names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset"; + names[GLSLstd450NMin] = "NMin"; + names[GLSLstd450NMax] = "NMax"; + names[GLSLstd450NClamp] = "NClamp"; } -#ifdef AMD_EXTENSIONS static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint) { if (strcmp(name, spv::E_SPV_AMD_shader_ballot) == 0) { @@ -692,18 +679,17 @@ static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint return "Bad"; } -#endif -#ifdef NV_EXTENSIONS static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint) { if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 || strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0 || strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 || strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 || - strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 || - strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 || - strcmp(name, spv::E_SPV_NV_mesh_shader) == 0) { + strcmp(name, spv::E_SPV_NVX_multiview_per_view_attributes) == 0 || + strcmp(name, spv::E_SPV_NV_fragment_shader_barycentric) == 0 || + strcmp(name, spv::E_SPV_NV_mesh_shader) == 0 || + strcmp(name, spv::E_SPV_NV_shader_image_footprint) == 0) { switch (entrypoint) { // NV builtins case BuiltInViewportMaskNV: return "ViewportMaskNV"; @@ -729,6 +715,8 @@ static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint) case CapabilityPerViewAttributesNV: return "PerViewAttributesNV"; case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV"; case CapabilityMeshShadingNV: return "MeshShadingNV"; + case CapabilityImageFootprintNV: return "ImageFootprintNV"; + case CapabilitySampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV"; // NV Decorations case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; @@ -745,7 +733,6 @@ static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint) } return "Bad"; } -#endif void Disassemble(std::ostream& out, const std::vector& stream) { diff --git a/thirdparty/ShaderCompiler/spirv/disassemble.h b/thirdparty/ShaderCompiler/spirv/disassemble.h index 2a9a89b..b6a4635 100644 --- a/thirdparty/ShaderCompiler/spirv/disassemble.h +++ b/thirdparty/ShaderCompiler/spirv/disassemble.h @@ -48,6 +48,6 @@ namespace spv { // disassemble with glslang custom disassembler void Disassemble(std::ostream& out, const std::vector&); -}; // end namespace spv +} // end namespace spv #endif // disassembler_H diff --git a/thirdparty/ShaderCompiler/spirv/doc.cpp b/thirdparty/ShaderCompiler/spirv/doc.cpp index bd6df10..dbdf707 100644 --- a/thirdparty/ShaderCompiler/spirv/doc.cpp +++ b/thirdparty/ShaderCompiler/spirv/doc.cpp @@ -1,5 +1,6 @@ // // Copyright (C) 2014-2015 LunarG, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -50,12 +51,8 @@ namespace spv { // Include C-based headers that don't have a namespace #include "GLSL.ext.KHR.h" #include "GLSL.ext.EXT.h" -#ifdef AMD_EXTENSIONS #include "GLSL.ext.AMD.h" -#endif -#ifdef NV_EXTENSIONS #include "GLSL.ext.NV.h" -#endif } } @@ -98,22 +95,17 @@ const char* ExecutionModelString(int model) case 4: return "Fragment"; case 5: return "GLCompute"; case 6: return "Kernel"; -#ifdef NV_EXTENSIONS case ExecutionModelTaskNV: return "TaskNV"; case ExecutionModelMeshNV: return "MeshNV"; -#endif default: return "Bad"; -#ifdef NV_EXTENSIONS - case ExecutionModelRayGenerationNV: return "RayGenerationNV"; - case ExecutionModelIntersectionNV: return "IntersectionNV"; - case ExecutionModelAnyHitNV: return "AnyHitNV"; - case ExecutionModelClosestHitNV: return "ClosestHitNV"; - case ExecutionModelMissNV: return "MissNV"; - case ExecutionModelCallableNV: return "CallableNV"; -#endif - + case ExecutionModelRayGenerationKHR: return "RayGenerationKHR"; + case ExecutionModelIntersectionKHR: return "IntersectionKHR"; + case ExecutionModelAnyHitKHR: return "AnyHitKHR"; + case ExecutionModelClosestHitKHR: return "ClosestHitKHR"; + case ExecutionModelMissKHR: return "MissKHR"; + case ExecutionModelCallableKHR: return "CallableKHR"; } } @@ -142,7 +134,7 @@ const char* MemoryString(int mem) } } -const int ExecutionModeCeiling = 33; +const int ExecutionModeCeiling = 40; const char* ExecutionModeString(int mode) { @@ -181,15 +173,40 @@ const char* ExecutionModeString(int mode) case 31: return "ContractionOff"; case 32: return "Bad"; - case 4446: return "PostDepthCoverage"; + case ExecutionModeInitializer: return "Initializer"; + case ExecutionModeFinalizer: return "Finalizer"; + case ExecutionModeSubgroupSize: return "SubgroupSize"; + case ExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; + case ExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; + case ExecutionModeLocalSizeId: return "LocalSizeId"; + case ExecutionModeLocalSizeHintId: return "LocalSizeHintId"; + + case ExecutionModePostDepthCoverage: return "PostDepthCoverage"; + case ExecutionModeDenormPreserve: return "DenormPreserve"; + case ExecutionModeDenormFlushToZero: return "DenormFlushToZero"; + case ExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case ExecutionModeRoundingModeRTE: return "RoundingModeRTE"; + case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; + case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; + case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlow"; -#ifdef NV_EXTENSIONS case ExecutionModeOutputLinesNV: return "OutputLinesNV"; case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV"; case ExecutionModeOutputTrianglesNV: return "OutputTrianglesNV"; case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV"; case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV"; -#endif + + case ExecutionModePixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT"; + case ExecutionModePixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT"; + case ExecutionModeSampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT"; + case ExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT"; + case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT"; + case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT"; + + case ExecutionModeMaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL"; + case ExecutionModeMaxWorkDimINTEL: return "MaxWorkDimINTEL"; + case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL"; + case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL"; case ExecutionModeCeiling: default: return "Bad"; @@ -213,14 +230,12 @@ const char* StorageClassString(int StorageClass) case 11: return "Image"; case 12: return "StorageBuffer"; -#ifdef NV_EXTENSIONS - case StorageClassRayPayloadNV: return "RayPayloadNV"; - case StorageClassHitAttributeNV: return "HitAttributeNV"; - case StorageClassIncomingRayPayloadNV: return "IncomingRayPayloadNV"; - case StorageClassShaderRecordBufferNV: return "ShaderRecordBufferNV"; - case StorageClassCallableDataNV: return "CallableDataNV"; - case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV"; -#endif + case StorageClassRayPayloadKHR: return "RayPayloadKHR"; + case StorageClassHitAttributeKHR: return "HitAttributeKHR"; + case StorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR"; + case StorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR"; + case StorageClassCallableDataKHR: return "CallableDataKHR"; + case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR"; case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT"; @@ -282,10 +297,7 @@ const char* DecorationString(int decoration) case DecorationCeiling: default: return "Bad"; -#ifdef AMD_EXTENSIONS case DecorationExplicitInterpAMD: return "ExplicitInterpAMD"; -#endif -#ifdef NV_EXTENSIONS case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; case DecorationPassthroughNV: return "PassthroughNV"; case DecorationViewportRelativeNV: return "ViewportRelativeNV"; @@ -294,7 +306,6 @@ const char* DecorationString(int decoration) case DecorationPerViewNV: return "PerViewNV"; case DecorationPerTaskNV: return "PerTaskNV"; case DecorationPerVertexNV: return "PerVertexNV"; -#endif case DecorationNonUniformEXT: return "DecorationNonUniformEXT"; case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE"; @@ -362,9 +373,10 @@ const char* BuiltInString(int builtIn) case 4424: return "BaseVertex"; case 4425: return "BaseInstance"; case 4426: return "DrawIndex"; + case 4432: return "PrimitiveShadingRateKHR"; + case 4444: return "ShadingRateKHR"; case 5014: return "FragStencilRefEXT"; -#ifdef AMD_EXTENSIONS case 4992: return "BaryCoordNoPerspAMD"; case 4993: return "BaryCoordNoPerspCentroidAMD"; case 4994: return "BaryCoordNoPerspSampleAMD"; @@ -372,41 +384,36 @@ const char* BuiltInString(int builtIn) case 4996: return "BaryCoordSmoothCentroidAMD"; case 4997: return "BaryCoordSmoothSampleAMD"; case 4998: return "BaryCoordPullModelAMD"; -#endif - -#ifdef NV_EXTENSIONS - case BuiltInLaunchIdNV: return "LaunchIdNV"; - case BuiltInLaunchSizeNV: return "LaunchSizeNV"; - case BuiltInWorldRayOriginNV: return "WorldRayOriginNV"; - case BuiltInWorldRayDirectionNV: return "WorldRayDirectionNV"; - case BuiltInObjectRayOriginNV: return "ObjectRayOriginNV"; - case BuiltInObjectRayDirectionNV: return "ObjectRayDirectionNV"; - case BuiltInRayTminNV: return "RayTminNV"; - case BuiltInRayTmaxNV: return "RayTmaxNV"; - case BuiltInInstanceCustomIndexNV: return "InstanceCustomIndexNV"; - case BuiltInObjectToWorldNV: return "ObjectToWorldNV"; - case BuiltInWorldToObjectNV: return "WorldToObjectNV"; - case BuiltInHitTNV: return "HitTNV"; - case BuiltInHitKindNV: return "HitKindNV"; - case BuiltInIncomingRayFlagsNV: return "IncomingRayFlagsNV"; - case BuiltInViewportMaskNV: return "ViewportMaskNV"; - case BuiltInSecondaryPositionNV: return "SecondaryPositionNV"; - case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; - case BuiltInPositionPerViewNV: return "PositionPerViewNV"; - case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case BuiltInLaunchIdKHR: return "LaunchIdKHR"; + case BuiltInLaunchSizeKHR: return "LaunchSizeKHR"; + case BuiltInWorldRayOriginKHR: return "WorldRayOriginKHR"; + case BuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR"; + case BuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR"; + case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR"; + case BuiltInRayTminKHR: return "RayTminKHR"; + case BuiltInRayTmaxKHR: return "RayTmaxKHR"; + case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR"; + case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR"; + case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR"; + case BuiltInWorldToObjectKHR: return "WorldToObjectKHR"; + case BuiltInHitTNV: return "HitTNV"; + case BuiltInHitKindKHR: return "HitKindKHR"; + case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR"; + case BuiltInViewportMaskNV: return "ViewportMaskNV"; + case BuiltInSecondaryPositionNV: return "SecondaryPositionNV"; + case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case BuiltInPositionPerViewNV: return "PositionPerViewNV"; + case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; // case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT // case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT - case BuiltInBaryCoordNV: return "BaryCoordNV"; - case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; -#endif + case BuiltInBaryCoordNV: return "BaryCoordNV"; + case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; - case BuiltInFragSizeEXT: return "FragSizeEXT"; - case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; + case BuiltInFragSizeEXT: return "FragSizeEXT"; + case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; case 5264: return "FullyCoveredEXT"; - -#ifdef NV_EXTENSIONS case BuiltInTaskCountNV: return "TaskCountNV"; case BuiltInPrimitiveCountNV: return "PrimitiveCountNV"; case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV"; @@ -415,7 +422,11 @@ const char* BuiltInString(int builtIn) case BuiltInLayerPerViewNV: return "LayerPerViewNV"; case BuiltInMeshViewCountNV: return "MeshViewCountNV"; case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV"; -#endif + case BuiltInWarpsPerSMNV: return "WarpsPerSMNV"; + case BuiltInSMCountNV: return "SMCountNV"; + case BuiltInWarpIDNV: return "WarpIDNV"; + case BuiltInSMIDNV: return "SMIDNV"; + case BuiltInCurrentRayTimeNV: return "CurrentRayTimeNV"; default: return "Bad"; } @@ -514,6 +525,8 @@ const char* ImageFormatString(int format) case 37: return "Rg8ui"; case 38: return "R16ui"; case 39: return "R8ui"; + case 40: return "R64ui"; + case 41: return "R64i"; default: return "Bad"; @@ -575,7 +588,7 @@ const char* ImageChannelDataTypeString(int type) } } -const int ImageOperandsCeiling = 12; +const int ImageOperandsCeiling = 14; const char* ImageOperandsString(int format) { @@ -592,6 +605,8 @@ const char* ImageOperandsString(int format) case ImageOperandsMakeTexelVisibleKHRShift: return "MakeTexelVisibleKHR"; case ImageOperandsNonPrivateTexelKHRShift: return "NonPrivateTexelKHR"; case ImageOperandsVolatileTexelKHRShift: return "VolatileTexelKHR"; + case ImageOperandsSignExtendShift: return "SignExtend"; + case ImageOperandsZeroExtendShift: return "ZeroExtend"; case ImageOperandsCeiling: default: @@ -674,15 +689,20 @@ const char* SelectControlString(int cont) } } -const int LoopControlCeiling = 4; +const int LoopControlCeiling = LoopControlPartialCountShift + 1; const char* LoopControlString(int cont) { switch (cont) { - case 0: return "Unroll"; - case 1: return "DontUnroll"; - case 2: return "DependencyInfinite"; - case 3: return "DependencyLength"; + case LoopControlUnrollShift: return "Unroll"; + case LoopControlDontUnrollShift: return "DontUnroll"; + case LoopControlDependencyInfiniteShift: return "DependencyInfinite"; + case LoopControlDependencyLengthShift: return "DependencyLength"; + case LoopControlMinIterationsShift: return "MinIterations"; + case LoopControlMaxIterationsShift: return "MaxIterations"; + case LoopControlIterationMultipleShift: return "IterationMultiple"; + case LoopControlPeelCountShift: return "PeelCount"; + case LoopControlPartialCountShift: return "PartialCount"; case LoopControlCeiling: default: return "Bad"; @@ -763,11 +783,9 @@ const char* GroupOperationString(int gop) case GroupOperationInclusiveScan: return "InclusiveScan"; case GroupOperationExclusiveScan: return "ExclusiveScan"; case GroupOperationClusteredReduce: return "ClusteredReduce"; -#ifdef NV_EXTENSIONS case GroupOperationPartitionedReduceNV: return "PartitionedReduceNV"; case GroupOperationPartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV"; case GroupOperationPartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV"; -#endif default: return "Bad"; } @@ -875,26 +893,23 @@ const char* CapabilityString(int info) case CapabilityStoragePushConstant16: return "StoragePushConstant16"; case CapabilityStorageInputOutput16: return "StorageInputOutput16"; - case CapabilityStorageBuffer8BitAccess: return "CapabilityStorageBuffer8BitAccess"; - case CapabilityUniformAndStorageBuffer8BitAccess: return "CapabilityUniformAndStorageBuffer8BitAccess"; - case CapabilityStoragePushConstant8: return "CapabilityStoragePushConstant8"; + case CapabilityStorageBuffer8BitAccess: return "StorageBuffer8BitAccess"; + case CapabilityUniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess"; + case CapabilityStoragePushConstant8: return "StoragePushConstant8"; case CapabilityDeviceGroup: return "DeviceGroup"; case CapabilityMultiView: return "MultiView"; case CapabilityStencilExportEXT: return "StencilExportEXT"; -#ifdef AMD_EXTENSIONS case CapabilityFloat16ImageAMD: return "Float16ImageAMD"; case CapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD"; case CapabilityFragmentMaskAMD: return "FragmentMaskAMD"; case CapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; -#endif case CapabilityAtomicStorageOps: return "AtomicStorageOps"; case CapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage"; -#ifdef NV_EXTENSIONS case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; case CapabilityShaderViewportIndexLayerNV: return "ShaderViewportIndexLayerNV"; case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; @@ -902,33 +917,67 @@ const char* CapabilityString(int info) case CapabilityPerViewAttributesNV: return "PerViewAttributesNV"; case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; case CapabilityRayTracingNV: return "RayTracingNV"; + case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV"; + case CapabilityRayTracingKHR: return "RayTracingKHR"; + case CapabilityRayQueryKHR: return "RayQueryKHR"; + case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; + case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV"; case CapabilityMeshShadingNV: return "MeshShadingNV"; -// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by CapabilityFragmentDensityEXT -#endif + case CapabilityImageFootprintNV: return "ImageFootprintNV"; +// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by FragmentDensityEXT + case CapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; case CapabilityFragmentDensityEXT: return "FragmentDensityEXT"; case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; - case CapabilityShaderNonUniformEXT: return "CapabilityShaderNonUniformEXT"; - case CapabilityRuntimeDescriptorArrayEXT: return "CapabilityRuntimeDescriptorArrayEXT"; - case CapabilityInputAttachmentArrayDynamicIndexingEXT: return "CapabilityInputAttachmentArrayDynamicIndexingEXT"; - case CapabilityUniformTexelBufferArrayDynamicIndexingEXT: return "CapabilityUniformTexelBufferArrayDynamicIndexingEXT"; - case CapabilityStorageTexelBufferArrayDynamicIndexingEXT: return "CapabilityStorageTexelBufferArrayDynamicIndexingEXT"; - case CapabilityUniformBufferArrayNonUniformIndexingEXT: return "CapabilityUniformBufferArrayNonUniformIndexingEXT"; - case CapabilitySampledImageArrayNonUniformIndexingEXT: return "CapabilitySampledImageArrayNonUniformIndexingEXT"; - case CapabilityStorageBufferArrayNonUniformIndexingEXT: return "CapabilityStorageBufferArrayNonUniformIndexingEXT"; - case CapabilityStorageImageArrayNonUniformIndexingEXT: return "CapabilityStorageImageArrayNonUniformIndexingEXT"; - case CapabilityInputAttachmentArrayNonUniformIndexingEXT: return "CapabilityInputAttachmentArrayNonUniformIndexingEXT"; - case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT"; - case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT"; + case CapabilityShaderNonUniformEXT: return "ShaderNonUniformEXT"; + case CapabilityRuntimeDescriptorArrayEXT: return "RuntimeDescriptorArrayEXT"; + case CapabilityInputAttachmentArrayDynamicIndexingEXT: return "InputAttachmentArrayDynamicIndexingEXT"; + case CapabilityUniformTexelBufferArrayDynamicIndexingEXT: return "UniformTexelBufferArrayDynamicIndexingEXT"; + case CapabilityStorageTexelBufferArrayDynamicIndexingEXT: return "StorageTexelBufferArrayDynamicIndexingEXT"; + case CapabilityUniformBufferArrayNonUniformIndexingEXT: return "UniformBufferArrayNonUniformIndexingEXT"; + case CapabilitySampledImageArrayNonUniformIndexingEXT: return "SampledImageArrayNonUniformIndexingEXT"; + case CapabilityStorageBufferArrayNonUniformIndexingEXT: return "StorageBufferArrayNonUniformIndexingEXT"; + case CapabilityStorageImageArrayNonUniformIndexingEXT: return "StorageImageArrayNonUniformIndexingEXT"; + case CapabilityInputAttachmentArrayNonUniformIndexingEXT: return "InputAttachmentArrayNonUniformIndexingEXT"; + case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "UniformTexelBufferArrayNonUniformIndexingEXT"; + case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "StorageTexelBufferArrayNonUniformIndexingEXT"; - case CapabilityVulkanMemoryModelKHR: return "CapabilityVulkanMemoryModelKHR"; - case CapabilityVulkanMemoryModelDeviceScopeKHR: return "CapabilityVulkanMemoryModelDeviceScopeKHR"; + case CapabilityVulkanMemoryModelKHR: return "VulkanMemoryModelKHR"; + case CapabilityVulkanMemoryModelDeviceScopeKHR: return "VulkanMemoryModelDeviceScopeKHR"; - case CapabilityPhysicalStorageBufferAddressesEXT: return "CapabilityPhysicalStorageBufferAddressesEXT"; + case CapabilityPhysicalStorageBufferAddressesEXT: return "PhysicalStorageBufferAddressesEXT"; + + case CapabilityVariablePointers: return "VariablePointers"; + + case CapabilityCooperativeMatrixNV: return "CooperativeMatrixNV"; + case CapabilityShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; + + case CapabilityFragmentShaderSampleInterlockEXT: return "CapabilityFragmentShaderSampleInterlockEXT"; + case CapabilityFragmentShaderPixelInterlockEXT: return "CapabilityFragmentShaderPixelInterlockEXT"; + case CapabilityFragmentShaderShadingRateInterlockEXT: return "CapabilityFragmentShaderShadingRateInterlockEXT"; + + case CapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR"; + + case CapabilityDemoteToHelperInvocationEXT: return "DemoteToHelperInvocationEXT"; + case CapabilityShaderClockKHR: return "ShaderClockKHR"; + case CapabilityInt64ImageEXT: return "Int64ImageEXT"; + + case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL"; + + case CapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT"; + case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; + case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; + case CapabilityAtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT"; + case CapabilityAtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT"; + case CapabilityAtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT"; + + case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "CapabilityWorkgroupMemoryExplicitLayoutKHR"; + case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR"; + case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR"; default: return "Bad"; } @@ -1022,6 +1071,7 @@ const char* OpcodeString(int op) case 82: return "OpCompositeInsert"; case 83: return "OpCopyObject"; case 84: return "OpTranspose"; + case OpCopyLogical: return "OpCopyLogical"; case 85: return "Bad"; case 86: return "OpSampledImage"; case 87: return "OpImageSampleImplicitLod"; @@ -1260,6 +1310,7 @@ const char* OpcodeString(int op) case 320: return "OpImageSparseRead"; case OpModuleProcessed: return "OpModuleProcessed"; + case OpExecutionModeId: return "OpExecutionModeId"; case OpDecorateId: return "OpDecorateId"; case 333: return "OpGroupNonUniformElect"; @@ -1297,6 +1348,8 @@ const char* OpcodeString(int op) case 365: return "OpGroupNonUniformQuadBroadcast"; case 366: return "OpGroupNonUniformQuadSwap"; + case OpTerminateInvocation: return "OpTerminateInvocation"; + case 4421: return "OpSubgroupBallotKHR"; case 4422: return "OpSubgroupFirstInvocationKHR"; case 4428: return "OpSubgroupAllKHR"; @@ -1304,7 +1357,10 @@ const char* OpcodeString(int op) case 4430: return "OpSubgroupAllEqualKHR"; case 4432: return "OpSubgroupReadInvocationKHR"; -#ifdef AMD_EXTENSIONS + case OpAtomicFAddEXT: return "OpAtomicFAddEXT"; + case OpAtomicFMinEXT: return "OpAtomicFMinEXT"; + case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT"; + case 5000: return "OpGroupIAddNonUniformAMD"; case 5001: return "OpGroupFAddNonUniformAMD"; case 5002: return "OpGroupFMinNonUniformAMD"; @@ -1316,22 +1372,64 @@ const char* OpcodeString(int op) case 5011: return "OpFragmentMaskFetchAMD"; case 5012: return "OpFragmentFetchAMD"; -#endif + + case OpReadClockKHR: return "OpReadClockKHR"; case OpDecorateStringGOOGLE: return "OpDecorateStringGOOGLE"; case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE"; -#ifdef NV_EXTENSIONS + case OpReportIntersectionKHR: return "OpReportIntersectionKHR"; + case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; + case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR"; + case OpTerminateRayNV: return "OpTerminateRayNV"; + case OpTerminateRayKHR: return "OpTerminateRayKHR"; + case OpTraceNV: return "OpTraceNV"; + case OpTraceRayMotionNV: return "OpTraceRayMotionNV"; + case OpTraceRayKHR: return "OpTraceRayKHR"; + case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR"; + case OpExecuteCallableNV: return "OpExecuteCallableNV"; + case OpExecuteCallableKHR: return "OpExecuteCallableKHR"; + case OpConvertUToAccelerationStructureKHR: return "OpConvertUToAccelerationStructureKHR"; + case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; - case OpReportIntersectionNV: return "OpReportIntersectionNV"; - case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; - case OpTerminateRayNV: return "OpTerminateRayNV"; - case OpTraceNV: return "OpTraceNV"; - case OpTypeAccelerationStructureNV: return "OpTypeAccelerationStructureNV"; - case OpExecuteCallableNV: return "OpExecuteCallableNV"; case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; -#endif + + case OpTypeRayQueryKHR: return "OpTypeRayQueryKHR"; + case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR"; + case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR"; + case OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR"; + case OpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR"; + case OpRayQueryProceedKHR: return "OpRayQueryProceedKHR"; + case OpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR"; + case OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR"; + case OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR"; + case OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR"; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR"; + case OpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR"; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR"; + case OpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR"; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR"; + case OpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR"; + case OpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR"; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR"; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR"; + case OpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR"; + case OpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR"; + case OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR"; + case OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR"; + case OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR"; + + case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; + case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; + case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; + case OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV"; + case OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV"; + case OpDemoteToHelperInvocationEXT: return "OpDemoteToHelperInvocationEXT"; + case OpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT"; + + case OpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT"; + case OpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT"; default: return "Bad"; @@ -1375,6 +1473,7 @@ void Parameterize() InstructionDesc[OpMemoryModel].setResultAndType(false, false); InstructionDesc[OpEntryPoint].setResultAndType(false, false); InstructionDesc[OpExecutionMode].setResultAndType(false, false); + InstructionDesc[OpExecutionModeId].setResultAndType(false, false); InstructionDesc[OpTypeVoid].setResultAndType(true, false); InstructionDesc[OpTypeBool].setResultAndType(true, false); InstructionDesc[OpTypeInt].setResultAndType(true, false); @@ -1428,6 +1527,7 @@ void Parameterize() InstructionDesc[OpBranchConditional].setResultAndType(false, false); InstructionDesc[OpSwitch].setResultAndType(false, false); InstructionDesc[OpKill].setResultAndType(false, false); + InstructionDesc[OpTerminateInvocation].setResultAndType(false, false); InstructionDesc[OpReturn].setResultAndType(false, false); InstructionDesc[OpReturnValue].setResultAndType(false, false); InstructionDesc[OpUnreachable].setResultAndType(false, false); @@ -1444,6 +1544,10 @@ void Parameterize() InstructionDesc[OpGroupWaitEvents].setResultAndType(false, false); InstructionDesc[OpAtomicFlagClear].setResultAndType(false, false); InstructionDesc[OpModuleProcessed].setResultAndType(false, false); + InstructionDesc[OpTypeCooperativeMatrixNV].setResultAndType(true, false); + InstructionDesc[OpCooperativeMatrixStoreNV].setResultAndType(false, false); + InstructionDesc[OpBeginInvocationInterlockEXT].setResultAndType(false, false); + InstructionDesc[OpEndInvocationInterlockEXT].setResultAndType(false, false); // Specific additional context-dependent operands @@ -1557,6 +1661,10 @@ void Parameterize() InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'"); InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <>"); + InstructionDesc[OpExecutionModeId].operands.push(OperandId, "'Entry Point'"); + InstructionDesc[OpExecutionModeId].operands.push(OperandExecutionMode, "'Mode'"); + InstructionDesc[OpExecutionModeId].operands.push(OperandVariableIds, "See <>"); + InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'"); InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'"); @@ -1650,7 +1758,7 @@ void Parameterize() InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'"); InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, ""); - InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'"); + InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'"); InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'"); InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'"); @@ -1660,7 +1768,7 @@ void Parameterize() InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'"); InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'"); InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, ""); - InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'"); + InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'"); InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'"); InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'"); @@ -1921,6 +2029,8 @@ void Parameterize() InstructionDesc[OpTranspose].operands.push(OperandId, "'Matrix'"); + InstructionDesc[OpCopyLogical].operands.push(OperandId, "'Operand'"); + InstructionDesc[OpIsNan].operands.push(OperandId, "'x'"); InstructionDesc[OpIsInf].operands.push(OperandId, "'x'"); @@ -2211,6 +2321,11 @@ void Parameterize() InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'"); InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'"); InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'"); InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'"); @@ -2236,6 +2351,16 @@ void Parameterize() InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'"); InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicFMinEXT].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicFMinEXT].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Value'"); + + InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Pointer'"); InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'"); InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'"); @@ -2614,7 +2739,7 @@ void Parameterize() InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'"); InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandLiteralNumber, "'Direction'"); + InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "'Direction'"); InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'"); @@ -2634,7 +2759,6 @@ void Parameterize() InstructionDesc[OpModuleProcessed].operands.push(OperandLiteralString, "'process'"); -#ifdef AMD_EXTENSIONS InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandScope, "'Execution'"); InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandId, "'X'"); @@ -2673,14 +2797,12 @@ void Parameterize() InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Image'"); InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Coordinate'"); InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Fragment Index'"); -#endif -#ifdef NV_EXTENSIONS InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X"); - InstructionDesc[OpTypeAccelerationStructureNV].setResultAndType(true, false); + InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'NV Acceleration Structure'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Acceleration Structure'"); InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Flags'"); InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'"); InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'"); @@ -2693,17 +2815,149 @@ void Parameterize() InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'"); InstructionDesc[OpTraceNV].setResultAndType(false, false); - InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Parameter'"); - InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Kind'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Flags'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Cull Mask'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Miss Index'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Origin'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Direction'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Time'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpTraceRayMotionNV].setResultAndType(false, false); + + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Miss Index'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Origin'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Direction'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpTraceRayKHR].setResultAndType(false, false); + + InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Parameter'"); + InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Kind'"); InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false); + InstructionDesc[OpIgnoreIntersectionKHR].setResultAndType(false, false); + InstructionDesc[OpTerminateRayNV].setResultAndType(false, false); + + InstructionDesc[OpTerminateRayKHR].setResultAndType(false, false); InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index"); InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID"); InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false); + InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "SBT Record Index"); + InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "CallableData"); + InstructionDesc[OpExecuteCallableKHR].setResultAndType(false, false); + + InstructionDesc[OpConvertUToAccelerationStructureKHR].operands.push(OperandId, "Value"); + InstructionDesc[OpConvertUToAccelerationStructureKHR].setResultAndType(true, true); + + // Ray Query + InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false); + InstructionDesc[OpTypeRayQueryKHR].setResultAndType(true, false); + + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'AccelerationS'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayFlags'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'CullMask'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmin'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmax'"); + InstructionDesc[OpRayQueryInitializeKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryTerminateKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryTerminateKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'THit'"); + InstructionDesc[OpRayQueryGenerateIntersectionKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryConfirmIntersectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryConfirmIntersectionKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryProceedKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryProceedKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionTypeKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetRayTMinKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetRayTMinKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetRayFlagsKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetRayFlagsKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionTKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetWorldRayOriginKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetWorldRayOriginKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].setResultAndType(true, true); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'"); InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'"); InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Granularity'"); @@ -2713,7 +2967,36 @@ void Parameterize() InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Index Offset'"); InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Packed Indices'"); -#endif + + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Component Type'"); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Scope'"); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Rows'"); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Columns'"); + + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Stride'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Column Major'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandMemoryAccess, "'Memory Access'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "", true); + + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Object'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Stride'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Column Major'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandMemoryAccess, "'Memory Access'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "", true); + + InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'A'"); + InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'B'"); + InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'C'"); + + InstructionDesc[OpCooperativeMatrixLengthNV].operands.push(OperandId, "'Type'"); + + InstructionDesc[OpDemoteToHelperInvocationEXT].setResultAndType(false, false); + + InstructionDesc[OpReadClockKHR].operands.push(OperandScope, "'Scope'"); } }; // end spv namespace diff --git a/thirdparty/ShaderCompiler/spirv/doc.h b/thirdparty/ShaderCompiler/spirv/doc.h index 7d0475d..2a0b28c 100644 --- a/thirdparty/ShaderCompiler/spirv/doc.h +++ b/thirdparty/ShaderCompiler/spirv/doc.h @@ -125,6 +125,7 @@ enum OperandClass { OperandVariableLiteralId, OperandLiteralNumber, OperandLiteralString, + OperandVariableLiteralStrings, OperandSource, OperandExecutionModel, OperandAddressing, @@ -255,4 +256,4 @@ const char* AccessQualifierString(int attr); void PrintOperands(const OperandParameters& operands, int reservedOperands); -}; // end namespace spv +} // end namespace spv diff --git a/thirdparty/ShaderCompiler/spirv/hex_float.h b/thirdparty/ShaderCompiler/spirv/hex_float.h index 905b21a..8be8e9f 100644 --- a/thirdparty/ShaderCompiler/spirv/hex_float.h +++ b/thirdparty/ShaderCompiler/spirv/hex_float.h @@ -784,8 +784,8 @@ inline std::istream& ParseNormalFloat(std::istream& is, bool negate_value, if (val.isInfinity()) { // Fail the parse. Emulate standard behaviour by setting the value to // the closest normal value, and set the fail bit on the stream. - value.set_value((value.isNegative() | negate_value) ? T::lowest() - : T::max()); + value.set_value((value.isNegative() || negate_value) ? T::lowest() + : T::max()); is.setstate(std::ios_base::failbit); } return is; diff --git a/thirdparty/ShaderCompiler/spirv/spirv.hpp b/thirdparty/ShaderCompiler/spirv/spirv.hpp index 44d0616..e0fe249 100644 --- a/thirdparty/ShaderCompiler/spirv/spirv.hpp +++ b/thirdparty/ShaderCompiler/spirv/spirv.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2019 The Khronos Group Inc. +// Copyright (c) 2014-2020 The Khronos Group Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and/or associated documentation files (the "Materials"), @@ -49,12 +49,12 @@ namespace spv { typedef unsigned int Id; -#define SPV_VERSION 0x10300 -#define SPV_REVISION 6 +#define SPV_VERSION 0x10500 +#define SPV_REVISION 4 static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010300; -static const unsigned int Revision = 6; +static const unsigned int Version = 0x00010500; +static const unsigned int Revision = 4; static const unsigned int OpCodeMask = 0xffff; static const unsigned int WordCountShift = 16; @@ -78,11 +78,17 @@ enum ExecutionModel { ExecutionModelKernel = 6, ExecutionModelTaskNV = 5267, ExecutionModelMeshNV = 5268, + ExecutionModelRayGenerationKHR = 5313, ExecutionModelRayGenerationNV = 5313, + ExecutionModelIntersectionKHR = 5314, ExecutionModelIntersectionNV = 5314, + ExecutionModelAnyHitKHR = 5315, ExecutionModelAnyHitNV = 5315, + ExecutionModelClosestHitKHR = 5316, ExecutionModelClosestHitNV = 5316, + ExecutionModelMissKHR = 5317, ExecutionModelMissNV = 5317, + ExecutionModelCallableKHR = 5318, ExecutionModelCallableNV = 5318, ExecutionModelMax = 0x7fffffff, }; @@ -91,6 +97,7 @@ enum AddressingModel { AddressingModelLogical = 0, AddressingModelPhysical32 = 1, AddressingModelPhysical64 = 2, + AddressingModelPhysicalStorageBuffer64 = 5348, AddressingModelPhysicalStorageBuffer64EXT = 5348, AddressingModelMax = 0x7fffffff, }; @@ -99,6 +106,7 @@ enum MemoryModel { MemoryModelSimple = 0, MemoryModelGLSL450 = 1, MemoryModelOpenCL = 2, + MemoryModelVulkan = 3, MemoryModelVulkanKHR = 3, MemoryModelMax = 0x7fffffff, }; @@ -142,6 +150,7 @@ enum ExecutionMode { ExecutionModeSubgroupsPerWorkgroupId = 37, ExecutionModeLocalSizeId = 38, ExecutionModeLocalSizeHintId = 39, + ExecutionModeSubgroupUniformControlFlowKHR = 4421, ExecutionModePostDepthCoverage = 4446, ExecutionModeDenormPreserve = 4459, ExecutionModeDenormFlushToZero = 4460, @@ -154,6 +163,22 @@ enum ExecutionMode { ExecutionModeDerivativeGroupQuadsNV = 5289, ExecutionModeDerivativeGroupLinearNV = 5290, ExecutionModeOutputTrianglesNV = 5298, + ExecutionModePixelInterlockOrderedEXT = 5366, + ExecutionModePixelInterlockUnorderedEXT = 5367, + ExecutionModeSampleInterlockOrderedEXT = 5368, + ExecutionModeSampleInterlockUnorderedEXT = 5369, + ExecutionModeShadingRateInterlockOrderedEXT = 5370, + ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeSharedLocalMemorySizeINTEL = 5618, + ExecutionModeRoundingModeRTPINTEL = 5620, + ExecutionModeRoundingModeRTNINTEL = 5621, + ExecutionModeFloatingPointModeALTINTEL = 5622, + ExecutionModeFloatingPointModeIEEEINTEL = 5623, + ExecutionModeMaxWorkgroupSizeINTEL = 5893, + ExecutionModeMaxWorkDimINTEL = 5894, + ExecutionModeNoGlobalOffsetINTEL = 5895, + ExecutionModeNumSIMDWorkitemsINTEL = 5896, + ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, ExecutionModeMax = 0x7fffffff, }; @@ -171,13 +196,23 @@ enum StorageClass { StorageClassAtomicCounter = 10, StorageClassImage = 11, StorageClassStorageBuffer = 12, + StorageClassCallableDataKHR = 5328, StorageClassCallableDataNV = 5328, + StorageClassIncomingCallableDataKHR = 5329, StorageClassIncomingCallableDataNV = 5329, + StorageClassRayPayloadKHR = 5338, StorageClassRayPayloadNV = 5338, + StorageClassHitAttributeKHR = 5339, StorageClassHitAttributeNV = 5339, + StorageClassIncomingRayPayloadKHR = 5342, StorageClassIncomingRayPayloadNV = 5342, + StorageClassShaderRecordBufferKHR = 5343, StorageClassShaderRecordBufferNV = 5343, + StorageClassPhysicalStorageBuffer = 5349, StorageClassPhysicalStorageBufferEXT = 5349, + StorageClassCodeSectionINTEL = 5605, + StorageClassDeviceOnlyINTEL = 5936, + StorageClassHostOnlyINTEL = 5937, StorageClassMax = 0x7fffffff, }; @@ -248,6 +283,8 @@ enum ImageFormat { ImageFormatRg8ui = 37, ImageFormatR16ui = 38, ImageFormatR8ui = 39, + ImageFormatR64ui = 40, + ImageFormatR64i = 41, ImageFormatMax = 0x7fffffff, }; @@ -305,10 +342,16 @@ enum ImageOperandsShift { ImageOperandsConstOffsetsShift = 5, ImageOperandsSampleShift = 6, ImageOperandsMinLodShift = 7, + ImageOperandsMakeTexelAvailableShift = 8, ImageOperandsMakeTexelAvailableKHRShift = 8, + ImageOperandsMakeTexelVisibleShift = 9, ImageOperandsMakeTexelVisibleKHRShift = 9, + ImageOperandsNonPrivateTexelShift = 10, ImageOperandsNonPrivateTexelKHRShift = 10, + ImageOperandsVolatileTexelShift = 11, ImageOperandsVolatileTexelKHRShift = 11, + ImageOperandsSignExtendShift = 12, + ImageOperandsZeroExtendShift = 13, ImageOperandsMax = 0x7fffffff, }; @@ -322,10 +365,16 @@ enum ImageOperandsMask { ImageOperandsConstOffsetsMask = 0x00000020, ImageOperandsSampleMask = 0x00000040, ImageOperandsMinLodMask = 0x00000080, + ImageOperandsMakeTexelAvailableMask = 0x00000100, ImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + ImageOperandsMakeTexelVisibleMask = 0x00000200, ImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + ImageOperandsNonPrivateTexelMask = 0x00000400, ImageOperandsNonPrivateTexelKHRMask = 0x00000400, + ImageOperandsVolatileTexelMask = 0x00000800, ImageOperandsVolatileTexelKHRMask = 0x00000800, + ImageOperandsSignExtendMask = 0x00001000, + ImageOperandsZeroExtendMask = 0x00002000, }; enum FPFastMathModeShift { @@ -334,6 +383,8 @@ enum FPFastMathModeShift { FPFastMathModeNSZShift = 2, FPFastMathModeAllowRecipShift = 3, FPFastMathModeFastShift = 4, + FPFastMathModeAllowContractFastINTELShift = 16, + FPFastMathModeAllowReassocINTELShift = 17, FPFastMathModeMax = 0x7fffffff, }; @@ -344,6 +395,8 @@ enum FPFastMathModeMask { FPFastMathModeNSZMask = 0x00000004, FPFastMathModeAllowRecipMask = 0x00000008, FPFastMathModeFastMask = 0x00000010, + FPFastMathModeAllowContractFastINTELMask = 0x00010000, + FPFastMathModeAllowReassocINTELMask = 0x00020000, }; enum FPRoundingMode { @@ -357,6 +410,7 @@ enum FPRoundingMode { enum LinkageType { LinkageTypeExport = 0, LinkageTypeImport = 1, + LinkageTypeLinkOnceODR = 2, LinkageTypeMax = 0x7fffffff, }; @@ -406,6 +460,7 @@ enum Decoration { DecorationNonWritable = 24, DecorationNonReadable = 25, DecorationUniform = 26, + DecorationUniformId = 27, DecorationSaturatedConversion = 28, DecorationStream = 29, DecorationLocation = 30, @@ -437,11 +492,51 @@ enum Decoration { DecorationPerViewNV = 5272, DecorationPerTaskNV = 5273, DecorationPerVertexNV = 5285, + DecorationNonUniform = 5300, DecorationNonUniformEXT = 5300, + DecorationRestrictPointer = 5355, DecorationRestrictPointerEXT = 5355, + DecorationAliasedPointer = 5356, DecorationAliasedPointerEXT = 5356, + DecorationSIMTCallINTEL = 5599, + DecorationReferencedIndirectlyINTEL = 5602, + DecorationClobberINTEL = 5607, + DecorationSideEffectsINTEL = 5608, + DecorationVectorComputeVariableINTEL = 5624, + DecorationFuncParamIOKindINTEL = 5625, + DecorationVectorComputeFunctionINTEL = 5626, + DecorationStackCallINTEL = 5627, + DecorationGlobalVariableOffsetINTEL = 5628, + DecorationCounterBuffer = 5634, DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslSemanticGOOGLE = 5635, + DecorationUserSemantic = 5635, + DecorationUserTypeGOOGLE = 5636, + DecorationFunctionRoundingModeINTEL = 5822, + DecorationFunctionDenormModeINTEL = 5823, + DecorationRegisterINTEL = 5825, + DecorationMemoryINTEL = 5826, + DecorationNumbanksINTEL = 5827, + DecorationBankwidthINTEL = 5828, + DecorationMaxPrivateCopiesINTEL = 5829, + DecorationSinglepumpINTEL = 5830, + DecorationDoublepumpINTEL = 5831, + DecorationMaxReplicatesINTEL = 5832, + DecorationSimpleDualPortINTEL = 5833, + DecorationMergeINTEL = 5834, + DecorationBankBitsINTEL = 5835, + DecorationForcePow2DepthINTEL = 5836, + DecorationBurstCoalesceINTEL = 5899, + DecorationCacheSizeINTEL = 5900, + DecorationDontStaticallyCoalesceINTEL = 5901, + DecorationPrefetchINTEL = 5902, + DecorationStallEnableINTEL = 5905, + DecorationFuseLoopsInFunctionINTEL = 5907, + DecorationBufferLocationINTEL = 5921, + DecorationIOPipeStorageINTEL = 5944, + DecorationFunctionFloatingPointModeINTEL = 6080, + DecorationSingleElementVectorINTEL = 6085, + DecorationVectorComputeCallableFunctionINTEL = 6087, DecorationMax = 0x7fffffff, }; @@ -500,8 +595,10 @@ enum BuiltIn { BuiltInBaseVertex = 4424, BuiltInBaseInstance = 4425, BuiltInDrawIndex = 4426, + BuiltInPrimitiveShadingRateKHR = 4432, BuiltInDeviceIndex = 4438, BuiltInViewIndex = 4440, + BuiltInShadingRateKHR = 4444, BuiltInBaryCoordNoPerspAMD = 4992, BuiltInBaryCoordNoPerspCentroidAMD = 4993, BuiltInBaryCoordNoPerspSampleAMD = 4994, @@ -530,20 +627,39 @@ enum BuiltIn { BuiltInFragmentSizeNV = 5292, BuiltInFragInvocationCountEXT = 5293, BuiltInInvocationsPerPixelNV = 5293, + BuiltInLaunchIdKHR = 5319, BuiltInLaunchIdNV = 5319, + BuiltInLaunchSizeKHR = 5320, BuiltInLaunchSizeNV = 5320, + BuiltInWorldRayOriginKHR = 5321, BuiltInWorldRayOriginNV = 5321, + BuiltInWorldRayDirectionKHR = 5322, BuiltInWorldRayDirectionNV = 5322, + BuiltInObjectRayOriginKHR = 5323, BuiltInObjectRayOriginNV = 5323, + BuiltInObjectRayDirectionKHR = 5324, BuiltInObjectRayDirectionNV = 5324, + BuiltInRayTminKHR = 5325, BuiltInRayTminNV = 5325, + BuiltInRayTmaxKHR = 5326, BuiltInRayTmaxNV = 5326, + BuiltInInstanceCustomIndexKHR = 5327, BuiltInInstanceCustomIndexNV = 5327, + BuiltInObjectToWorldKHR = 5330, BuiltInObjectToWorldNV = 5330, + BuiltInWorldToObjectKHR = 5331, BuiltInWorldToObjectNV = 5331, BuiltInHitTNV = 5332, + BuiltInHitKindKHR = 5333, BuiltInHitKindNV = 5333, + BuiltInCurrentRayTimeNV = 5334, + BuiltInIncomingRayFlagsKHR = 5351, BuiltInIncomingRayFlagsNV = 5351, + BuiltInRayGeometryIndexKHR = 5352, + BuiltInWarpsPerSMNV = 5374, + BuiltInSMCountNV = 5375, + BuiltInWarpIDNV = 5376, + BuiltInSMIDNV = 5377, BuiltInMax = 0x7fffffff, }; @@ -564,6 +680,19 @@ enum LoopControlShift { LoopControlDontUnrollShift = 1, LoopControlDependencyInfiniteShift = 2, LoopControlDependencyLengthShift = 3, + LoopControlMinIterationsShift = 4, + LoopControlMaxIterationsShift = 5, + LoopControlIterationMultipleShift = 6, + LoopControlPeelCountShift = 7, + LoopControlPartialCountShift = 8, + LoopControlInitiationIntervalINTELShift = 16, + LoopControlMaxConcurrencyINTELShift = 17, + LoopControlDependencyArrayINTELShift = 18, + LoopControlPipelineEnableINTELShift = 19, + LoopControlLoopCoalesceINTELShift = 20, + LoopControlMaxInterleavingINTELShift = 21, + LoopControlSpeculatedIterationsINTELShift = 22, + LoopControlNoFusionINTELShift = 23, LoopControlMax = 0x7fffffff, }; @@ -573,6 +702,19 @@ enum LoopControlMask { LoopControlDontUnrollMask = 0x00000002, LoopControlDependencyInfiniteMask = 0x00000004, LoopControlDependencyLengthMask = 0x00000008, + LoopControlMinIterationsMask = 0x00000010, + LoopControlMaxIterationsMask = 0x00000020, + LoopControlIterationMultipleMask = 0x00000040, + LoopControlPeelCountMask = 0x00000080, + LoopControlPartialCountMask = 0x00000100, + LoopControlInitiationIntervalINTELMask = 0x00010000, + LoopControlMaxConcurrencyINTELMask = 0x00020000, + LoopControlDependencyArrayINTELMask = 0x00040000, + LoopControlPipelineEnableINTELMask = 0x00080000, + LoopControlLoopCoalesceINTELMask = 0x00100000, + LoopControlMaxInterleavingINTELMask = 0x00200000, + LoopControlSpeculatedIterationsINTELMask = 0x00400000, + LoopControlNoFusionINTELMask = 0x00800000, }; enum FunctionControlShift { @@ -602,9 +744,13 @@ enum MemorySemanticsShift { MemorySemanticsCrossWorkgroupMemoryShift = 9, MemorySemanticsAtomicCounterMemoryShift = 10, MemorySemanticsImageMemoryShift = 11, + MemorySemanticsOutputMemoryShift = 12, MemorySemanticsOutputMemoryKHRShift = 12, + MemorySemanticsMakeAvailableShift = 13, MemorySemanticsMakeAvailableKHRShift = 13, + MemorySemanticsMakeVisibleShift = 14, MemorySemanticsMakeVisibleKHRShift = 14, + MemorySemanticsVolatileShift = 15, MemorySemanticsMax = 0x7fffffff, }; @@ -620,17 +766,24 @@ enum MemorySemanticsMask { MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, MemorySemanticsAtomicCounterMemoryMask = 0x00000400, MemorySemanticsImageMemoryMask = 0x00000800, + MemorySemanticsOutputMemoryMask = 0x00001000, MemorySemanticsOutputMemoryKHRMask = 0x00001000, + MemorySemanticsMakeAvailableMask = 0x00002000, MemorySemanticsMakeAvailableKHRMask = 0x00002000, + MemorySemanticsMakeVisibleMask = 0x00004000, MemorySemanticsMakeVisibleKHRMask = 0x00004000, + MemorySemanticsVolatileMask = 0x00008000, }; enum MemoryAccessShift { MemoryAccessVolatileShift = 0, MemoryAccessAlignedShift = 1, MemoryAccessNontemporalShift = 2, + MemoryAccessMakePointerAvailableShift = 3, MemoryAccessMakePointerAvailableKHRShift = 3, + MemoryAccessMakePointerVisibleShift = 4, MemoryAccessMakePointerVisibleKHRShift = 4, + MemoryAccessNonPrivatePointerShift = 5, MemoryAccessNonPrivatePointerKHRShift = 5, MemoryAccessMax = 0x7fffffff, }; @@ -640,8 +793,11 @@ enum MemoryAccessMask { MemoryAccessVolatileMask = 0x00000001, MemoryAccessAlignedMask = 0x00000002, MemoryAccessNontemporalMask = 0x00000004, + MemoryAccessMakePointerAvailableMask = 0x00000008, MemoryAccessMakePointerAvailableKHRMask = 0x00000008, + MemoryAccessMakePointerVisibleMask = 0x00000010, MemoryAccessMakePointerVisibleKHRMask = 0x00000010, + MemoryAccessNonPrivatePointerMask = 0x00000020, MemoryAccessNonPrivatePointerKHRMask = 0x00000020, }; @@ -651,7 +807,9 @@ enum Scope { ScopeWorkgroup = 2, ScopeSubgroup = 3, ScopeInvocation = 4, + ScopeQueueFamily = 5, ScopeQueueFamilyKHR = 5, + ScopeShaderCallKHR = 6, ScopeMax = 0x7fffffff, }; @@ -751,8 +909,14 @@ enum Capability { CapabilityGroupNonUniformShuffleRelative = 66, CapabilityGroupNonUniformClustered = 67, CapabilityGroupNonUniformQuad = 68, + CapabilityShaderLayer = 69, + CapabilityShaderViewportIndex = 70, + CapabilityFragmentShadingRateKHR = 4422, CapabilitySubgroupBallotKHR = 4423, CapabilityDrawParameters = 4427, + CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, CapabilitySubgroupVoteKHR = 4431, CapabilityStorageBuffer16BitAccess = 4433, CapabilityStorageUniformBufferBlock16 = 4433, @@ -774,11 +938,17 @@ enum Capability { CapabilitySignedZeroInfNanPreserve = 4466, CapabilityRoundingModeRTE = 4467, CapabilityRoundingModeRTZ = 4468, + CapabilityRayQueryProvisionalKHR = 4471, + CapabilityRayQueryKHR = 4472, + CapabilityRayTraversalPrimitiveCullingKHR = 4478, + CapabilityRayTracingKHR = 4479, CapabilityFloat16ImageAMD = 5008, CapabilityImageGatherBiasLodAMD = 5009, CapabilityFragmentMaskAMD = 5010, CapabilityStencilExportEXT = 5013, CapabilityImageReadWriteLodAMD = 5015, + CapabilityInt64ImageEXT = 5016, + CapabilityShaderClockKHR = 5055, CapabilitySampleMaskOverrideCoverageNV = 5249, CapabilityGeometryShaderPassthroughNV = 5251, CapabilityShaderViewportIndexLayerEXT = 5254, @@ -794,29 +964,164 @@ enum Capability { CapabilityFragmentDensityEXT = 5291, CapabilityShadingRateNV = 5291, CapabilityGroupNonUniformPartitionedNV = 5297, + CapabilityShaderNonUniform = 5301, CapabilityShaderNonUniformEXT = 5301, + CapabilityRuntimeDescriptorArray = 5302, CapabilityRuntimeDescriptorArrayEXT = 5302, + CapabilityInputAttachmentArrayDynamicIndexing = 5303, CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + CapabilityUniformTexelBufferArrayDynamicIndexing = 5304, CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + CapabilityStorageTexelBufferArrayDynamicIndexing = 5305, CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + CapabilityUniformBufferArrayNonUniformIndexing = 5306, CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + CapabilitySampledImageArrayNonUniformIndexing = 5307, CapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + CapabilityStorageBufferArrayNonUniformIndexing = 5308, CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + CapabilityStorageImageArrayNonUniformIndexing = 5309, CapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + CapabilityInputAttachmentArrayNonUniformIndexing = 5310, CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + CapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, CapabilityRayTracingNV = 5340, + CapabilityRayTracingMotionBlurNV = 5341, + CapabilityVulkanMemoryModel = 5345, CapabilityVulkanMemoryModelKHR = 5345, + CapabilityVulkanMemoryModelDeviceScope = 5346, CapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + CapabilityPhysicalStorageBufferAddresses = 5347, CapabilityPhysicalStorageBufferAddressesEXT = 5347, CapabilityComputeDerivativeGroupLinearNV = 5350, + CapabilityRayTracingProvisionalKHR = 5353, + CapabilityCooperativeMatrixNV = 5357, + CapabilityFragmentShaderSampleInterlockEXT = 5363, + CapabilityFragmentShaderShadingRateInterlockEXT = 5372, + CapabilityShaderSMBuiltinsNV = 5373, + CapabilityFragmentShaderPixelInterlockEXT = 5378, + CapabilityDemoteToHelperInvocationEXT = 5379, CapabilitySubgroupShuffleINTEL = 5568, CapabilitySubgroupBufferBlockIOINTEL = 5569, CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilitySubgroupImageMediaBlockIOINTEL = 5579, + CapabilityRoundToInfinityINTEL = 5582, + CapabilityFloatingPointModeINTEL = 5583, + CapabilityIntegerFunctions2INTEL = 5584, + CapabilityFunctionPointersINTEL = 5603, + CapabilityIndirectReferencesINTEL = 5604, + CapabilityAsmINTEL = 5606, + CapabilityAtomicFloat32MinMaxEXT = 5612, + CapabilityAtomicFloat64MinMaxEXT = 5613, + CapabilityAtomicFloat16MinMaxEXT = 5616, + CapabilityVectorComputeINTEL = 5617, + CapabilityVectorAnyINTEL = 5619, + CapabilityExpectAssumeKHR = 5629, + CapabilitySubgroupAvcMotionEstimationINTEL = 5696, + CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, + CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + CapabilityVariableLengthArrayINTEL = 5817, + CapabilityFunctionFloatControlINTEL = 5821, + CapabilityFPGAMemoryAttributesINTEL = 5824, + CapabilityFPFastMathModeINTEL = 5837, + CapabilityArbitraryPrecisionIntegersINTEL = 5844, + CapabilityUnstructuredLoopControlsINTEL = 5886, + CapabilityFPGALoopControlsINTEL = 5888, + CapabilityKernelAttributesINTEL = 5892, + CapabilityFPGAKernelAttributesINTEL = 5897, + CapabilityFPGAMemoryAccessesINTEL = 5898, + CapabilityFPGAClusterAttributesINTEL = 5904, + CapabilityLoopFuseINTEL = 5906, + CapabilityFPGABufferLocationINTEL = 5920, + CapabilityUSMStorageClassesINTEL = 5935, + CapabilityIOPipesINTEL = 5943, + CapabilityBlockingPipesINTEL = 5945, + CapabilityFPGARegINTEL = 5948, + CapabilityAtomicFloat32AddEXT = 6033, + CapabilityAtomicFloat64AddEXT = 6034, + CapabilityLongConstantCompositeINTEL = 6089, + CapabilityAtomicFloat16AddEXT = 6095, CapabilityMax = 0x7fffffff, }; +enum RayFlagsShift { + RayFlagsOpaqueKHRShift = 0, + RayFlagsNoOpaqueKHRShift = 1, + RayFlagsTerminateOnFirstHitKHRShift = 2, + RayFlagsSkipClosestHitShaderKHRShift = 3, + RayFlagsCullBackFacingTrianglesKHRShift = 4, + RayFlagsCullFrontFacingTrianglesKHRShift = 5, + RayFlagsCullOpaqueKHRShift = 6, + RayFlagsCullNoOpaqueKHRShift = 7, + RayFlagsSkipTrianglesKHRShift = 8, + RayFlagsSkipAABBsKHRShift = 9, + RayFlagsMax = 0x7fffffff, +}; + +enum RayFlagsMask { + RayFlagsMaskNone = 0, + RayFlagsOpaqueKHRMask = 0x00000001, + RayFlagsNoOpaqueKHRMask = 0x00000002, + RayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + RayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + RayFlagsCullOpaqueKHRMask = 0x00000040, + RayFlagsCullNoOpaqueKHRMask = 0x00000080, + RayFlagsSkipTrianglesKHRMask = 0x00000100, + RayFlagsSkipAABBsKHRMask = 0x00000200, +}; + +enum RayQueryIntersection { + RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + RayQueryIntersectionMax = 0x7fffffff, +}; + +enum RayQueryCommittedIntersectionType { + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + RayQueryCommittedIntersectionTypeMax = 0x7fffffff, +}; + +enum RayQueryCandidateIntersectionType { + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + RayQueryCandidateIntersectionTypeMax = 0x7fffffff, +}; + +enum FragmentShadingRateShift { + FragmentShadingRateVertical2PixelsShift = 0, + FragmentShadingRateVertical4PixelsShift = 1, + FragmentShadingRateHorizontal2PixelsShift = 2, + FragmentShadingRateHorizontal4PixelsShift = 3, + FragmentShadingRateMax = 0x7fffffff, +}; + +enum FragmentShadingRateMask { + FragmentShadingRateMaskNone = 0, + FragmentShadingRateVertical2PixelsMask = 0x00000001, + FragmentShadingRateVertical4PixelsMask = 0x00000002, + FragmentShadingRateHorizontal2PixelsMask = 0x00000004, + FragmentShadingRateHorizontal4PixelsMask = 0x00000008, +}; + +enum FPDenormMode { + FPDenormModePreserve = 0, + FPDenormModeFlushToZero = 1, + FPDenormModeMax = 0x7fffffff, +}; + +enum FPOperationMode { + FPOperationModeIEEE = 0, + FPOperationModeALT = 1, + FPOperationModeMax = 0x7fffffff, +}; + enum Op { OpNop = 0, OpUndef = 1, @@ -1158,12 +1463,29 @@ enum Op { OpGroupNonUniformLogicalXor = 364, OpGroupNonUniformQuadBroadcast = 365, OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpTerminateInvocation = 4416, OpSubgroupBallotKHR = 4421, OpSubgroupFirstInvocationKHR = 4422, OpSubgroupAllKHR = 4428, OpSubgroupAnyKHR = 4429, OpSubgroupAllEqualKHR = 4430, OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, OpGroupIAddNonUniformAMD = 5000, OpGroupFAddNonUniformAMD = 5001, OpGroupFMinNonUniformAMD = 5002, @@ -1174,15 +1496,29 @@ enum Op { OpGroupSMaxNonUniformAMD = 5007, OpFragmentMaskFetchAMD = 5011, OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, OpImageSampleFootprintNV = 5283, OpGroupNonUniformPartitionNV = 5296, OpWritePackedPrimitiveIndices4x8NV = 5299, + OpReportIntersectionKHR = 5334, OpReportIntersectionNV = 5334, OpIgnoreIntersectionNV = 5335, OpTerminateRayNV = 5336, OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpTypeAccelerationStructureKHR = 5341, OpTypeAccelerationStructureNV = 5341, OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, OpSubgroupShuffleINTEL = 5571, OpSubgroupShuffleDownINTEL = 5572, OpSubgroupShuffleUpINTEL = 5573, @@ -1191,11 +1527,774 @@ enum Op { OpSubgroupBlockWriteINTEL = 5576, OpSubgroupImageBlockReadINTEL = 5577, OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpLoopControlINTEL = 5887, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, OpMax = 0x7fffffff, }; +#ifdef SPV_ENABLE_UTILITY_CODE +inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case OpNop: *hasResult = false; *hasResultType = false; break; + case OpUndef: *hasResult = true; *hasResultType = true; break; + case OpSourceContinued: *hasResult = false; *hasResultType = false; break; + case OpSource: *hasResult = false; *hasResultType = false; break; + case OpSourceExtension: *hasResult = false; *hasResultType = false; break; + case OpName: *hasResult = false; *hasResultType = false; break; + case OpMemberName: *hasResult = false; *hasResultType = false; break; + case OpString: *hasResult = true; *hasResultType = false; break; + case OpLine: *hasResult = false; *hasResultType = false; break; + case OpExtension: *hasResult = false; *hasResultType = false; break; + case OpExtInstImport: *hasResult = true; *hasResultType = false; break; + case OpExtInst: *hasResult = true; *hasResultType = true; break; + case OpMemoryModel: *hasResult = false; *hasResultType = false; break; + case OpEntryPoint: *hasResult = false; *hasResultType = false; break; + case OpExecutionMode: *hasResult = false; *hasResultType = false; break; + case OpCapability: *hasResult = false; *hasResultType = false; break; + case OpTypeVoid: *hasResult = true; *hasResultType = false; break; + case OpTypeBool: *hasResult = true; *hasResultType = false; break; + case OpTypeInt: *hasResult = true; *hasResultType = false; break; + case OpTypeFloat: *hasResult = true; *hasResultType = false; break; + case OpTypeVector: *hasResult = true; *hasResultType = false; break; + case OpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case OpTypeImage: *hasResult = true; *hasResultType = false; break; + case OpTypeSampler: *hasResult = true; *hasResultType = false; break; + case OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case OpTypeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeStruct: *hasResult = true; *hasResultType = false; break; + case OpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case OpTypePointer: *hasResult = true; *hasResultType = false; break; + case OpTypeFunction: *hasResult = true; *hasResultType = false; break; + case OpTypeEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case OpTypeQueue: *hasResult = true; *hasResultType = false; break; + case OpTypePipe: *hasResult = true; *hasResultType = false; break; + case OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case OpConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpConstant: *hasResult = true; *hasResultType = true; break; + case OpConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpConstantSampler: *hasResult = true; *hasResultType = true; break; + case OpConstantNull: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpSpecConstant: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case OpFunction: *hasResult = true; *hasResultType = true; break; + case OpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case OpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case OpFunctionCall: *hasResult = true; *hasResultType = true; break; + case OpVariable: *hasResult = true; *hasResultType = true; break; + case OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case OpLoad: *hasResult = true; *hasResultType = true; break; + case OpStore: *hasResult = false; *hasResultType = false; break; + case OpCopyMemory: *hasResult = false; *hasResultType = false; break; + case OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case OpAccessChain: *hasResult = true; *hasResultType = true; break; + case OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpArrayLength: *hasResult = true; *hasResultType = true; break; + case OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpDecorate: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case OpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case OpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case OpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case OpCopyObject: *hasResult = true; *hasResultType = true; break; + case OpTranspose: *hasResult = true; *hasResultType = true; break; + case OpSampledImage: *hasResult = true; *hasResultType = true; break; + case OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageFetch: *hasResult = true; *hasResultType = true; break; + case OpImageGather: *hasResult = true; *hasResultType = true; break; + case OpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageRead: *hasResult = true; *hasResultType = true; break; + case OpImageWrite: *hasResult = false; *hasResultType = false; break; + case OpImage: *hasResult = true; *hasResultType = true; break; + case OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case OpConvertFToU: *hasResult = true; *hasResultType = true; break; + case OpConvertFToS: *hasResult = true; *hasResultType = true; break; + case OpConvertSToF: *hasResult = true; *hasResultType = true; break; + case OpConvertUToF: *hasResult = true; *hasResultType = true; break; + case OpUConvert: *hasResult = true; *hasResultType = true; break; + case OpSConvert: *hasResult = true; *hasResultType = true; break; + case OpFConvert: *hasResult = true; *hasResultType = true; break; + case OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case OpBitcast: *hasResult = true; *hasResultType = true; break; + case OpSNegate: *hasResult = true; *hasResultType = true; break; + case OpFNegate: *hasResult = true; *hasResultType = true; break; + case OpIAdd: *hasResult = true; *hasResultType = true; break; + case OpFAdd: *hasResult = true; *hasResultType = true; break; + case OpISub: *hasResult = true; *hasResultType = true; break; + case OpFSub: *hasResult = true; *hasResultType = true; break; + case OpIMul: *hasResult = true; *hasResultType = true; break; + case OpFMul: *hasResult = true; *hasResultType = true; break; + case OpUDiv: *hasResult = true; *hasResultType = true; break; + case OpSDiv: *hasResult = true; *hasResultType = true; break; + case OpFDiv: *hasResult = true; *hasResultType = true; break; + case OpUMod: *hasResult = true; *hasResultType = true; break; + case OpSRem: *hasResult = true; *hasResultType = true; break; + case OpSMod: *hasResult = true; *hasResultType = true; break; + case OpFRem: *hasResult = true; *hasResultType = true; break; + case OpFMod: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpOuterProduct: *hasResult = true; *hasResultType = true; break; + case OpDot: *hasResult = true; *hasResultType = true; break; + case OpIAddCarry: *hasResult = true; *hasResultType = true; break; + case OpISubBorrow: *hasResult = true; *hasResultType = true; break; + case OpUMulExtended: *hasResult = true; *hasResultType = true; break; + case OpSMulExtended: *hasResult = true; *hasResultType = true; break; + case OpAny: *hasResult = true; *hasResultType = true; break; + case OpAll: *hasResult = true; *hasResultType = true; break; + case OpIsNan: *hasResult = true; *hasResultType = true; break; + case OpIsInf: *hasResult = true; *hasResultType = true; break; + case OpIsFinite: *hasResult = true; *hasResultType = true; break; + case OpIsNormal: *hasResult = true; *hasResultType = true; break; + case OpSignBitSet: *hasResult = true; *hasResultType = true; break; + case OpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case OpOrdered: *hasResult = true; *hasResultType = true; break; + case OpUnordered: *hasResult = true; *hasResultType = true; break; + case OpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpLogicalNot: *hasResult = true; *hasResultType = true; break; + case OpSelect: *hasResult = true; *hasResultType = true; break; + case OpIEqual: *hasResult = true; *hasResultType = true; break; + case OpINotEqual: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpULessThan: *hasResult = true; *hasResultType = true; break; + case OpSLessThan: *hasResult = true; *hasResultType = true; break; + case OpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case OpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpNot: *hasResult = true; *hasResultType = true; break; + case OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case OpBitReverse: *hasResult = true; *hasResultType = true; break; + case OpBitCount: *hasResult = true; *hasResultType = true; break; + case OpDPdx: *hasResult = true; *hasResultType = true; break; + case OpDPdy: *hasResult = true; *hasResultType = true; break; + case OpFwidth: *hasResult = true; *hasResultType = true; break; + case OpDPdxFine: *hasResult = true; *hasResultType = true; break; + case OpDPdyFine: *hasResult = true; *hasResultType = true; break; + case OpFwidthFine: *hasResult = true; *hasResultType = true; break; + case OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case OpEmitVertex: *hasResult = false; *hasResultType = false; break; + case OpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case OpControlBarrier: *hasResult = false; *hasResultType = false; break; + case OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case OpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case OpAtomicStore: *hasResult = false; *hasResultType = false; break; + case OpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case OpAtomicISub: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case OpAtomicOr: *hasResult = true; *hasResultType = true; break; + case OpAtomicXor: *hasResult = true; *hasResultType = true; break; + case OpPhi: *hasResult = true; *hasResultType = true; break; + case OpLoopMerge: *hasResult = false; *hasResultType = false; break; + case OpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case OpLabel: *hasResult = true; *hasResultType = false; break; + case OpBranch: *hasResult = false; *hasResultType = false; break; + case OpBranchConditional: *hasResult = false; *hasResultType = false; break; + case OpSwitch: *hasResult = false; *hasResultType = false; break; + case OpKill: *hasResult = false; *hasResultType = false; break; + case OpReturn: *hasResult = false; *hasResultType = false; break; + case OpReturnValue: *hasResult = false; *hasResultType = false; break; + case OpUnreachable: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case OpGroupAll: *hasResult = true; *hasResultType = true; break; + case OpGroupAny: *hasResult = true; *hasResultType = true; break; + case OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupSMax: *hasResult = true; *hasResultType = true; break; + case OpReadPipe: *hasResult = true; *hasResultType = true; break; + case OpWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case OpRetainEvent: *hasResult = false; *hasResultType = false; break; + case OpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case OpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case OpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case OpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case OpNoLine: *hasResult = false; *hasResultType = false; break; + case OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case OpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case OpSizeOf: *hasResult = true; *hasResultType = true; break; + case OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case OpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case OpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case OpDecorateId: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case OpCopyLogical: *hasResult = true; *hasResultType = true; break; + case OpPtrEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case OpTraceNV: *hasResult = false; *hasResultType = false; break; + case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break; + case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpConstFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case OpExpectKHR: *hasResult = true; *hasResultType = true; break; + case OpDecorateString: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + // Overload operator| for mask bit combining inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } @@ -1206,6 +2305,8 @@ inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } +inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } +inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } } // end namespace spv diff --git a/thirdparty/ShaderCompiler/spirv/spvIR.h b/thirdparty/ShaderCompiler/spirv/spvIR.h index 8c2d0b6..486e80d 100644 --- a/thirdparty/ShaderCompiler/spirv/spvIR.h +++ b/thirdparty/ShaderCompiler/spirv/spvIR.h @@ -55,6 +55,7 @@ #include #include #include +#include namespace spv { @@ -83,6 +84,7 @@ const MemorySemanticsMask MemorySemanticsAllMemory = struct IdImmediate { bool isId; // true if word is an Id, false if word is an immediate unsigned word; + IdImmediate(bool i, unsigned w) : isId(i), word(w) {} }; // @@ -225,6 +227,35 @@ public: return nullptr; } + // Change this block into a canonical dead merge block. Delete instructions + // as necessary. A canonical dead merge block has only an OpLabel and an + // OpUnreachable. + void rewriteAsCanonicalUnreachableMerge() { + assert(localVariables.empty()); + // Delete all instructions except for the label. + assert(instructions.size() > 0); + instructions.resize(1); + successors.clear(); + addInstruction(std::unique_ptr(new Instruction(OpUnreachable))); + } + // Change this block into a canonical dead continue target branching to the + // given header ID. Delete instructions as necessary. A canonical dead continue + // target has only an OpLabel and an unconditional branch back to the corresponding + // header. + void rewriteAsCanonicalUnreachableContinue(Block* header) { + assert(localVariables.empty()); + // Delete all instructions except for the label. + assert(instructions.size() > 0); + instructions.resize(1); + successors.clear(); + // Add OpBranch back to the header. + assert(header != nullptr); + Instruction* branch = new Instruction(OpBranch); + branch->addIdOperand(header->getId()); + addInstruction(std::unique_ptr(branch)); + successors.push_back(header); + } + bool isTerminated() const { switch (instructions.back()->getOpCode()) { @@ -232,8 +263,10 @@ public: case OpBranchConditional: case OpSwitch: case OpKill: + case OpTerminateInvocation: case OpReturn: case OpReturnValue: + case OpUnreachable: return true; default: return false; @@ -267,10 +300,24 @@ protected: bool unreachable; }; +// The different reasons for reaching a block in the inReadableOrder traversal. +enum ReachReason { + // Reachable from the entry block via transfers of control, i.e. branches. + ReachViaControlFlow = 0, + // A continue target that is not reachable via control flow. + ReachDeadContinue, + // A merge block that is not reachable via control flow. + ReachDeadMerge +}; + // Traverses the control-flow graph rooted at root in an order suited for // readable code generation. Invokes callback at every node in the traversal -// order. -void inReadableOrder(Block* root, std::function callback); +// order. The callback arguments are: +// - the block, +// - the reason we reached the block, +// - if the reason was that block is an unreachable continue or unreachable merge block +// then the last parameter is the corresponding header block. +void inReadableOrder(Block* root, std::function callback); // // SPIR-V IR Function. @@ -306,10 +353,28 @@ public: const std::vector& getBlocks() const { return blocks; } void addLocalVariable(std::unique_ptr inst); Id getReturnType() const { return functionInstruction.getTypeId(); } + void setReturnPrecision(Decoration precision) + { + if (precision == DecorationRelaxedPrecision) + reducedPrecisionReturn = true; + } + Decoration getReturnPrecision() const + { return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; } void setImplicitThis() { implicitThis = true; } bool hasImplicitThis() const { return implicitThis; } + void addParamPrecision(unsigned param, Decoration precision) + { + if (precision == DecorationRelaxedPrecision) + reducedPrecisionParams.insert(param); + } + Decoration getParamPrecision(unsigned param) const + { + return reducedPrecisionParams.find(param) != reducedPrecisionParams.end() ? + DecorationRelaxedPrecision : NoPrecision; + } + void dump(std::vector& out) const { // OpFunction @@ -320,7 +385,7 @@ public: parameterInstructions[p]->dump(out); // Blocks - inReadableOrder(blocks[0], [&out](const Block* b) { b->dump(out); }); + inReadableOrder(blocks[0], [&out](const Block* b, ReachReason, Block*) { b->dump(out); }); Instruction end(0, 0, OpFunctionEnd); end.dump(out); } @@ -334,6 +399,8 @@ protected: std::vector parameterInstructions; std::vector blocks; bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument + bool reducedPrecisionReturn; + std::set reducedPrecisionParams; // list of parameter indexes that need a relaxed precision arg }; // @@ -394,7 +461,8 @@ protected: // - the OpFunction instruction // - all the OpFunctionParameter instructions __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent) - : parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false) + : parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false), + reducedPrecisionReturn(false) { // OpFunction functionInstruction.addImmediateOperand(FunctionControlMaskNone); @@ -435,6 +503,6 @@ __inline void Block::addInstruction(std::unique_ptr inst) parent.getParent().mapInstruction(raw_instruction); } -}; // end spv namespace +} // end spv namespace #endif // spvIR_H