mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-01-24 08:41:06 +00:00
Upgrade glsl compiler to 11.6.0
This commit is contained in:
parent
b06f1b6128
commit
0e7bb52c19
84 changed files with 33201 additions and 14648 deletions
|
@ -267,6 +267,8 @@ set(THIRDPARTY_SOURCES
|
||||||
../thirdparty/ShaderCompiler/glslang/MachineIndependent/Scan.h
|
../thirdparty/ShaderCompiler/glslang/MachineIndependent/Scan.h
|
||||||
../thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.h
|
../thirdparty/ShaderCompiler/glslang/MachineIndependent/reflection.h
|
||||||
../thirdparty/ShaderCompiler/glslang/MachineIndependent/ScanContext.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/OSDependent/osinclude.h
|
||||||
../thirdparty/ShaderCompiler/glslang/GenericCodeGen/Link.cpp
|
../thirdparty/ShaderCompiler/glslang/GenericCodeGen/Link.cpp
|
||||||
../thirdparty/ShaderCompiler/glslang/GenericCodeGen/CodeGen.cpp
|
../thirdparty/ShaderCompiler/glslang/GenericCodeGen/CodeGen.cpp
|
||||||
|
@ -280,9 +282,9 @@ set(THIRDPARTY_SOURCES
|
||||||
../thirdparty/ShaderCompiler/glslang/Include/InfoSink.h
|
../thirdparty/ShaderCompiler/glslang/Include/InfoSink.h
|
||||||
../thirdparty/ShaderCompiler/glslang/Include/ResourceLimits.h
|
../thirdparty/ShaderCompiler/glslang/Include/ResourceLimits.h
|
||||||
../thirdparty/ShaderCompiler/glslang/Include/Types.h
|
../thirdparty/ShaderCompiler/glslang/Include/Types.h
|
||||||
../thirdparty/ShaderCompiler/glslang/Include/revision.h
|
|
||||||
../thirdparty/ShaderCompiler/glslang/Include/BaseTypes.h
|
../thirdparty/ShaderCompiler/glslang/Include/BaseTypes.h
|
||||||
../thirdparty/ShaderCompiler/glslang/Include/intermediate.h
|
../thirdparty/ShaderCompiler/glslang/Include/intermediate.h
|
||||||
|
../thirdparty/ShaderCompiler/glslang/Include/SpirvIntrinsics.h
|
||||||
../thirdparty/ShaderCompiler/spirv/Logger.h
|
../thirdparty/ShaderCompiler/spirv/Logger.h
|
||||||
../thirdparty/ShaderCompiler/spirv/GlslangToSpv.cpp
|
../thirdparty/ShaderCompiler/spirv/GlslangToSpv.cpp
|
||||||
../thirdparty/ShaderCompiler/spirv/SPVRemapper.h
|
../thirdparty/ShaderCompiler/spirv/SPVRemapper.h
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -61,12 +62,13 @@ enum TBasicType {
|
||||||
EbtSampler,
|
EbtSampler,
|
||||||
EbtStruct,
|
EbtStruct,
|
||||||
EbtBlock,
|
EbtBlock,
|
||||||
|
EbtAccStruct,
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
EbtAccStructNV,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EbtReference,
|
EbtReference,
|
||||||
|
EbtRayQuery,
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
// SPIR-V type defined by spirv_type
|
||||||
|
EbtSpirvType,
|
||||||
|
#endif
|
||||||
|
|
||||||
// HLSL types that live only temporarily.
|
// HLSL types that live only temporarily.
|
||||||
EbtString,
|
EbtString,
|
||||||
|
@ -93,15 +95,16 @@ enum TStorageQualifier {
|
||||||
EvqUniform, // read only, shared with app
|
EvqUniform, // read only, shared with app
|
||||||
EvqBuffer, // read/write, shared with app
|
EvqBuffer, // read/write, shared with app
|
||||||
EvqShared, // compute shader's read/write 'shared' qualifier
|
EvqShared, // compute shader's read/write 'shared' qualifier
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
#ifdef NV_EXTENSIONS
|
EvqSpirvStorageClass, // spirv_storage_class
|
||||||
EvqPayloadNV,
|
|
||||||
EvqPayloadInNV,
|
|
||||||
EvqHitAttrNV,
|
|
||||||
EvqCallableDataNV,
|
|
||||||
EvqCallableDataInNV,
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EvqPayload,
|
||||||
|
EvqPayloadIn,
|
||||||
|
EvqHitAttr,
|
||||||
|
EvqCallableData,
|
||||||
|
EvqCallableDataIn,
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
|
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
|
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,
|
EbvSampleMask,
|
||||||
EbvHelperInvocation,
|
EbvHelperInvocation,
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EbvBaryCoordNoPersp,
|
EbvBaryCoordNoPersp,
|
||||||
EbvBaryCoordNoPerspCentroid,
|
EbvBaryCoordNoPerspCentroid,
|
||||||
EbvBaryCoordNoPerspSample,
|
EbvBaryCoordNoPerspSample,
|
||||||
|
@ -229,15 +231,19 @@ enum TBuiltInVariable {
|
||||||
EbvBaryCoordSmoothCentroid,
|
EbvBaryCoordSmoothCentroid,
|
||||||
EbvBaryCoordSmoothSample,
|
EbvBaryCoordSmoothSample,
|
||||||
EbvBaryCoordPullModel,
|
EbvBaryCoordPullModel,
|
||||||
#endif
|
|
||||||
|
|
||||||
EbvViewIndex,
|
EbvViewIndex,
|
||||||
EbvDeviceIndex,
|
EbvDeviceIndex,
|
||||||
|
|
||||||
|
EbvShadingRateKHR,
|
||||||
|
EbvPrimitiveShadingRateKHR,
|
||||||
|
|
||||||
EbvFragSizeEXT,
|
EbvFragSizeEXT,
|
||||||
EbvFragInvocationCountEXT,
|
EbvFragInvocationCountEXT,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
EbvSecondaryFragDataEXT,
|
||||||
|
EbvSecondaryFragColorEXT,
|
||||||
|
|
||||||
EbvViewportMaskNV,
|
EbvViewportMaskNV,
|
||||||
EbvSecondaryPositionNV,
|
EbvSecondaryPositionNV,
|
||||||
EbvSecondaryViewportMaskNV,
|
EbvSecondaryViewportMaskNV,
|
||||||
|
@ -247,22 +253,28 @@ enum TBuiltInVariable {
|
||||||
EbvFragmentSizeNV,
|
EbvFragmentSizeNV,
|
||||||
EbvInvocationsPerPixelNV,
|
EbvInvocationsPerPixelNV,
|
||||||
// ray tracing
|
// ray tracing
|
||||||
EbvLaunchIdNV,
|
EbvLaunchId,
|
||||||
EbvLaunchSizeNV,
|
EbvLaunchSize,
|
||||||
EbvInstanceCustomIndexNV,
|
EbvInstanceCustomIndex,
|
||||||
EbvWorldRayOriginNV,
|
EbvGeometryIndex,
|
||||||
EbvWorldRayDirectionNV,
|
EbvWorldRayOrigin,
|
||||||
EbvObjectRayOriginNV,
|
EbvWorldRayDirection,
|
||||||
EbvObjectRayDirectionNV,
|
EbvObjectRayOrigin,
|
||||||
EbvRayTminNV,
|
EbvObjectRayDirection,
|
||||||
EbvRayTmaxNV,
|
EbvRayTmin,
|
||||||
EbvHitTNV,
|
EbvRayTmax,
|
||||||
EbvHitKindNV,
|
EbvHitT,
|
||||||
EbvObjectToWorldNV,
|
EbvHitKind,
|
||||||
EbvWorldToObjectNV,
|
EbvObjectToWorld,
|
||||||
EbvIncomingRayFlagsNV,
|
EbvObjectToWorld3x4,
|
||||||
|
EbvWorldToObject,
|
||||||
|
EbvWorldToObject3x4,
|
||||||
|
EbvIncomingRayFlags,
|
||||||
|
EbvCurrentRayTimeNV,
|
||||||
|
// barycentrics
|
||||||
EbvBaryCoordNV,
|
EbvBaryCoordNV,
|
||||||
EbvBaryCoordNoPerspNV,
|
EbvBaryCoordNoPerspNV,
|
||||||
|
// mesh shaders
|
||||||
EbvTaskCountNV,
|
EbvTaskCountNV,
|
||||||
EbvPrimitiveCountNV,
|
EbvPrimitiveCountNV,
|
||||||
EbvPrimitiveIndicesNV,
|
EbvPrimitiveIndicesNV,
|
||||||
|
@ -271,7 +283,12 @@ enum TBuiltInVariable {
|
||||||
EbvLayerPerViewNV,
|
EbvLayerPerViewNV,
|
||||||
EbvMeshViewCountNV,
|
EbvMeshViewCountNV,
|
||||||
EbvMeshViewIndicesNV,
|
EbvMeshViewIndicesNV,
|
||||||
#endif
|
|
||||||
|
// sm builtins
|
||||||
|
EbvWarpsPerSM,
|
||||||
|
EbvSMCount,
|
||||||
|
EbvWarpID,
|
||||||
|
EbvSMID,
|
||||||
|
|
||||||
// HLSL built-ins that live only temporarily, until they get remapped
|
// HLSL built-ins that live only temporarily, until they get remapped
|
||||||
// to one of the above.
|
// to one of the above.
|
||||||
|
@ -291,6 +308,19 @@ enum TBuiltInVariable {
|
||||||
EbvLast
|
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
|
// These will show up in error messages
|
||||||
__inline const char* GetStorageQualifierString(TStorageQualifier q)
|
__inline const char* GetStorageQualifierString(TStorageQualifier q)
|
||||||
{
|
{
|
||||||
|
@ -299,6 +329,9 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
|
||||||
case EvqGlobal: return "global"; break;
|
case EvqGlobal: return "global"; break;
|
||||||
case EvqConst: return "const"; break;
|
case EvqConst: return "const"; break;
|
||||||
case EvqConstReadOnly: return "const (read only)"; 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 EvqVaryingIn: return "in"; break;
|
||||||
case EvqVaryingOut: return "out"; break;
|
case EvqVaryingOut: return "out"; break;
|
||||||
case EvqUniform: return "uniform"; break;
|
case EvqUniform: return "uniform"; break;
|
||||||
|
@ -317,13 +350,11 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
|
||||||
case EvqPointCoord: return "gl_PointCoord"; break;
|
case EvqPointCoord: return "gl_PointCoord"; break;
|
||||||
case EvqFragColor: return "fragColor"; break;
|
case EvqFragColor: return "fragColor"; break;
|
||||||
case EvqFragDepth: return "gl_FragDepth"; break;
|
case EvqFragDepth: return "gl_FragDepth"; break;
|
||||||
#ifdef NV_EXTENSIONS
|
case EvqPayload: return "rayPayloadNV"; break;
|
||||||
case EvqPayloadNV: return "rayPayloadNV"; break;
|
case EvqPayloadIn: return "rayPayloadInNV"; break;
|
||||||
case EvqPayloadInNV: return "rayPayloadInNV"; break;
|
case EvqHitAttr: return "hitAttributeNV"; break;
|
||||||
case EvqHitAttrNV: return "hitAttributeNV"; break;
|
case EvqCallableData: return "callableDataNV"; break;
|
||||||
case EvqCallableDataNV: return "callableDataNV"; break;
|
case EvqCallableDataIn: return "callableDataInNV"; break;
|
||||||
case EvqCallableDataInNV: return "callableDataInNV"; break;
|
|
||||||
#endif
|
|
||||||
default: return "unknown qualifier";
|
default: return "unknown qualifier";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,6 +369,8 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvLocalInvocationId: return "LocalInvocationID";
|
case EbvLocalInvocationId: return "LocalInvocationID";
|
||||||
case EbvGlobalInvocationId: return "GlobalInvocationID";
|
case EbvGlobalInvocationId: return "GlobalInvocationID";
|
||||||
case EbvLocalInvocationIndex: return "LocalInvocationIndex";
|
case EbvLocalInvocationIndex: return "LocalInvocationIndex";
|
||||||
|
case EbvNumSubgroups: return "NumSubgroups";
|
||||||
|
case EbvSubgroupID: return "SubgroupID";
|
||||||
case EbvSubGroupSize: return "SubGroupSize";
|
case EbvSubGroupSize: return "SubGroupSize";
|
||||||
case EbvSubGroupInvocation: return "SubGroupInvocation";
|
case EbvSubGroupInvocation: return "SubGroupInvocation";
|
||||||
case EbvSubGroupEqMask: return "SubGroupEqMask";
|
case EbvSubGroupEqMask: return "SubGroupEqMask";
|
||||||
|
@ -345,6 +378,13 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvSubGroupGtMask: return "SubGroupGtMask";
|
case EbvSubGroupGtMask: return "SubGroupGtMask";
|
||||||
case EbvSubGroupLeMask: return "SubGroupLeMask";
|
case EbvSubGroupLeMask: return "SubGroupLeMask";
|
||||||
case EbvSubGroupLtMask: return "SubGroupLtMask";
|
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 EbvVertexId: return "VertexId";
|
||||||
case EbvInstanceId: return "InstanceId";
|
case EbvInstanceId: return "InstanceId";
|
||||||
case EbvVertexIndex: return "VertexIndex";
|
case EbvVertexIndex: return "VertexIndex";
|
||||||
|
@ -396,7 +436,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvSampleMask: return "SampleMaskIn";
|
case EbvSampleMask: return "SampleMaskIn";
|
||||||
case EbvHelperInvocation: return "HelperInvocation";
|
case EbvHelperInvocation: return "HelperInvocation";
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbvBaryCoordNoPersp: return "BaryCoordNoPersp";
|
case EbvBaryCoordNoPersp: return "BaryCoordNoPersp";
|
||||||
case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid";
|
case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid";
|
||||||
case EbvBaryCoordNoPerspSample: return "BaryCoordNoPerspSample";
|
case EbvBaryCoordNoPerspSample: return "BaryCoordNoPerspSample";
|
||||||
|
@ -404,7 +443,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvBaryCoordSmoothCentroid: return "BaryCoordSmoothCentroid";
|
case EbvBaryCoordSmoothCentroid: return "BaryCoordSmoothCentroid";
|
||||||
case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample";
|
case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample";
|
||||||
case EbvBaryCoordPullModel: return "BaryCoordPullModel";
|
case EbvBaryCoordPullModel: return "BaryCoordPullModel";
|
||||||
#endif
|
|
||||||
|
|
||||||
case EbvViewIndex: return "ViewIndex";
|
case EbvViewIndex: return "ViewIndex";
|
||||||
case EbvDeviceIndex: return "DeviceIndex";
|
case EbvDeviceIndex: return "DeviceIndex";
|
||||||
|
@ -412,7 +450,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvFragSizeEXT: return "FragSizeEXT";
|
case EbvFragSizeEXT: return "FragSizeEXT";
|
||||||
case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
|
case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
case EbvSecondaryFragDataEXT: return "SecondaryFragDataEXT";
|
||||||
|
case EbvSecondaryFragColorEXT: return "SecondaryFragColorEXT";
|
||||||
|
|
||||||
case EbvViewportMaskNV: return "ViewportMaskNV";
|
case EbvViewportMaskNV: return "ViewportMaskNV";
|
||||||
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
|
@ -421,23 +461,26 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvFragFullyCoveredNV: return "FragFullyCoveredNV";
|
case EbvFragFullyCoveredNV: return "FragFullyCoveredNV";
|
||||||
case EbvFragmentSizeNV: return "FragmentSizeNV";
|
case EbvFragmentSizeNV: return "FragmentSizeNV";
|
||||||
case EbvInvocationsPerPixelNV: return "InvocationsPerPixelNV";
|
case EbvInvocationsPerPixelNV: return "InvocationsPerPixelNV";
|
||||||
case EbvLaunchIdNV: return "LaunchIdNV";
|
case EbvLaunchId: return "LaunchIdNV";
|
||||||
case EbvLaunchSizeNV: return "LaunchSizeNV";
|
case EbvLaunchSize: return "LaunchSizeNV";
|
||||||
case EbvInstanceCustomIndexNV: return "InstanceCustomIndexNV";
|
case EbvInstanceCustomIndex: return "InstanceCustomIndexNV";
|
||||||
case EbvWorldRayOriginNV: return "WorldRayOriginNV";
|
case EbvGeometryIndex: return "GeometryIndexEXT";
|
||||||
case EbvWorldRayDirectionNV: return "WorldRayDirectionNV";
|
case EbvWorldRayOrigin: return "WorldRayOriginNV";
|
||||||
case EbvObjectRayOriginNV: return "ObjectRayOriginNV";
|
case EbvWorldRayDirection: return "WorldRayDirectionNV";
|
||||||
case EbvObjectRayDirectionNV: return "ObjectRayDirectionNV";
|
case EbvObjectRayOrigin: return "ObjectRayOriginNV";
|
||||||
case EbvRayTminNV: return "ObjectRayTminNV";
|
case EbvObjectRayDirection: return "ObjectRayDirectionNV";
|
||||||
case EbvRayTmaxNV: return "ObjectRayTmaxNV";
|
case EbvRayTmin: return "ObjectRayTminNV";
|
||||||
case EbvHitTNV: return "HitTNV";
|
case EbvRayTmax: return "ObjectRayTmaxNV";
|
||||||
case EbvHitKindNV: return "HitKindNV";
|
case EbvHitT: return "HitTNV";
|
||||||
case EbvIncomingRayFlagsNV: return "IncomingRayFlagsNV";
|
case EbvHitKind: return "HitKindNV";
|
||||||
case EbvObjectToWorldNV: return "ObjectToWorldNV";
|
case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
|
||||||
case EbvWorldToObjectNV: return "WorldToObjectNV";
|
case EbvObjectToWorld: return "ObjectToWorldNV";
|
||||||
|
case EbvWorldToObject: return "WorldToObjectNV";
|
||||||
|
case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
|
||||||
|
|
||||||
case EbvBaryCoordNV: return "BaryCoordNV";
|
case EbvBaryCoordNV: return "BaryCoordNV";
|
||||||
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||||
|
|
||||||
case EbvTaskCountNV: return "TaskCountNV";
|
case EbvTaskCountNV: return "TaskCountNV";
|
||||||
case EbvPrimitiveCountNV: return "PrimitiveCountNV";
|
case EbvPrimitiveCountNV: return "PrimitiveCountNV";
|
||||||
case EbvPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
case EbvPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||||
|
@ -446,20 +489,19 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvLayerPerViewNV: return "LayerPerViewNV";
|
case EbvLayerPerViewNV: return "LayerPerViewNV";
|
||||||
case EbvMeshViewCountNV: return "MeshViewCountNV";
|
case EbvMeshViewCountNV: return "MeshViewCountNV";
|
||||||
case EbvMeshViewIndicesNV: return "MeshViewIndicesNV";
|
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";
|
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)
|
__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
|
@ -470,6 +512,7 @@ __inline const char* GetPrecisionQualifierString(TPrecisionQualifier p)
|
||||||
default: return "unknown precision qualifier";
|
default: return "unknown precision qualifier";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
__inline bool isTypeSignedInt(TBasicType type)
|
__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;
|
int res = -1;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
|
|
|
@ -37,8 +37,19 @@
|
||||||
#ifndef _COMMON_INCLUDED_
|
#ifndef _COMMON_INCLUDED_
|
||||||
#define _COMMON_INCLUDED_
|
#define _COMMON_INCLUDED_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#if defined(__ANDROID__) || _MSC_VER < 1700
|
#if defined(__ANDROID__) || (defined(_MSC_VER) && _MSC_VER < 1700)
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
namespace std {
|
namespace std {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -93,17 +104,6 @@ std::string to_string(const T& val) {
|
||||||
#pragma warning(disable : 4201) // nameless union
|
#pragma warning(disable : 4201) // nameless union
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <list>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <string>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "PoolAlloc.h"
|
#include "PoolAlloc.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -194,6 +194,10 @@ template <class K, class D, class HASH = std::hash<K>, class PRED = std::equal_t
|
||||||
class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > {
|
class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class K, class CMP = std::less<K> >
|
||||||
|
class TSet : public std::set<K, CMP, pool_allocator<K> > {
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Persistent string memory. Should only be used for strings that survive
|
// Persistent string memory. Should only be used for strings that survive
|
||||||
// across compiles/links.
|
// across compiles/links.
|
||||||
|
@ -286,6 +290,18 @@ template <class T> bool IsMultipleOfPow2(T number, int powerOf2)
|
||||||
return ! (number & (powerOf2 - 1));
|
return ! (number & (powerOf2 - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns log2 of an integer power of 2.
|
||||||
|
// T should be integral.
|
||||||
|
template <class T> int IntLog2(T n)
|
||||||
|
{
|
||||||
|
assert(IsPow2(n));
|
||||||
|
int result = 0;
|
||||||
|
while ((T(1) << result) != n) {
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _COMMON_INCLUDED_
|
#endif // _COMMON_INCLUDED_
|
||||||
|
|
|
@ -213,6 +213,28 @@ public:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (type) {
|
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:
|
case EbtInt16:
|
||||||
if (constant.i16Const == i16Const)
|
if (constant.i16Const == i16Const)
|
||||||
return true;
|
return true;
|
||||||
|
@ -232,16 +254,6 @@ public:
|
||||||
if (constant.u8Const == u8Const)
|
if (constant.u8Const == u8Const)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
break;
|
|
||||||
case EbtInt:
|
|
||||||
if (constant.iConst == iConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case EbtUint:
|
|
||||||
if (constant.uConst == uConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (constant.i64Const == i64Const)
|
if (constant.i64Const == i64Const)
|
||||||
|
@ -253,16 +265,7 @@ public:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case EbtDouble:
|
#endif
|
||||||
if (constant.dConst == dConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case EbtBool:
|
|
||||||
if (constant.bConst == bConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
assert(false && "Default missing");
|
assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
@ -329,6 +332,22 @@ public:
|
||||||
{
|
{
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (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:
|
case EbtInt8:
|
||||||
if (i8Const > constant.i8Const)
|
if (i8Const > constant.i8Const)
|
||||||
return true;
|
return true;
|
||||||
|
@ -348,16 +367,6 @@ public:
|
||||||
if (u16Const > constant.u16Const)
|
if (u16Const > constant.u16Const)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
|
||||||
case EbtInt:
|
|
||||||
if (iConst > constant.iConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
case EbtUint:
|
|
||||||
if (uConst > constant.uConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (i64Const > constant.i64Const)
|
if (i64Const > constant.i64Const)
|
||||||
|
@ -369,11 +378,7 @@ public:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
case EbtDouble:
|
#endif
|
||||||
if (dConst > constant.dConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
default:
|
default:
|
||||||
assert(false && "Default missing");
|
assert(false && "Default missing");
|
||||||
return false;
|
return false;
|
||||||
|
@ -384,6 +389,7 @@ public:
|
||||||
{
|
{
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
if (i8Const < constant.i8Const)
|
if (i8Const < constant.i8Const)
|
||||||
return true;
|
return true;
|
||||||
|
@ -402,17 +408,6 @@ public:
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
if (u16Const < constant.u16Const)
|
if (u16Const < constant.u16Const)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
|
||||||
case EbtInt:
|
|
||||||
if (iConst < constant.iConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
case EbtUint:
|
|
||||||
if (uConst < constant.uConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (i64Const < constant.i64Const)
|
if (i64Const < constant.i64Const)
|
||||||
|
@ -424,10 +419,21 @@ public:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
if (dConst < constant.dConst)
|
if (dConst < constant.dConst)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtInt:
|
||||||
|
if (iConst < constant.iConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtUint:
|
||||||
|
if (uConst < constant.uConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
assert(false && "Default missing");
|
assert(false && "Default missing");
|
||||||
|
@ -440,15 +446,17 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (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 EbtInt8: returnValue.setI8Const(i8Const + constant.i8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); 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 EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const + constant.u16Const); 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 EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break;
|
||||||
case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break;
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,15 +468,17 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (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 EbtInt8: returnValue.setI8Const(i8Const - constant.i8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); 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 EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const - constant.u16Const); 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 EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break;
|
||||||
case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break;
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,15 +490,17 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (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 EbtInt8: returnValue.setI8Const(i8Const * constant.i8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); 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 EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const * constant.u16Const); 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 EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break;
|
||||||
case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,14 +512,16 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (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 EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break;
|
||||||
case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); 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 EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); 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 EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,6 +532,7 @@ public:
|
||||||
{
|
{
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break;
|
||||||
|
@ -570,32 +585,38 @@ public:
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch (constant.type) {
|
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 EbtInt8: returnValue.setIConst(iConst >> constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setIConst(iConst >> constant.u8Const); break;
|
case EbtUint8: returnValue.setIConst(iConst >> constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setIConst(iConst >> constant.i16Const); break;
|
case EbtInt16: returnValue.setIConst(iConst >> constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setIConst(iConst >> constant.u16Const); 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 EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break;
|
case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
switch (constant.type) {
|
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 EbtInt8: returnValue.setUConst(uConst >> constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setUConst(uConst >> constant.u8Const); break;
|
case EbtUint8: returnValue.setUConst(uConst >> constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setUConst(uConst >> constant.i16Const); break;
|
case EbtInt16: returnValue.setUConst(uConst >> constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setUConst(uConst >> constant.u16Const); 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 EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break;
|
case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break;
|
case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break;
|
||||||
|
@ -622,6 +643,7 @@ public:
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,6 +654,7 @@ public:
|
||||||
{
|
{
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break;
|
||||||
|
@ -684,32 +707,6 @@ public:
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case EbtInt64:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
case EbtInt8: returnValue.setI64Const(i64Const << constant.i8Const); break;
|
case EbtInt8: returnValue.setI64Const(i64Const << constant.i8Const); break;
|
||||||
|
@ -736,6 +733,37 @@ public:
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
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");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,14 +775,16 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (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 EbtInt8: returnValue.setI8Const(i8Const & constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break;
|
case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const & constant.u16Const); 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 EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,14 +796,16 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (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 EbtInt8: returnValue.setI8Const(i8Const | constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break;
|
case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const | constant.u16Const); 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 EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -785,14 +817,16 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (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 EbtInt8: returnValue.setI8Const(i8Const ^ constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break;
|
case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const ^ constant.u16Const); 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 EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,14 +837,16 @@ public:
|
||||||
{
|
{
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(~iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(~uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setI8Const(~i8Const); break;
|
case EbtInt8: returnValue.setI8Const(~i8Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(~u8Const); break;
|
case EbtUint8: returnValue.setU8Const(~u8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(~i16Const); break;
|
case EbtInt16: returnValue.setI16Const(~i16Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(~u16Const); 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 EbtInt64: returnValue.setI64Const(~i64Const); break;
|
||||||
case EbtUint64: returnValue.setU64Const(~u64Const); break;
|
case EbtUint64: returnValue.setU64Const(~u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,7 +921,7 @@ public:
|
||||||
else
|
else
|
||||||
unionArray = new TConstUnionVector(size);
|
unionArray = new TConstUnionVector(size);
|
||||||
}
|
}
|
||||||
TConstUnionArray(const TConstUnionArray& a) : unionArray(a.unionArray) { }
|
TConstUnionArray(const TConstUnionArray& a) = default;
|
||||||
TConstUnionArray(const TConstUnionArray& a, int start, int size)
|
TConstUnionArray(const TConstUnionArray& a, int start, int size)
|
||||||
{
|
{
|
||||||
unionArray = new TConstUnionVector(size);
|
unionArray = new TConstUnionVector(size);
|
||||||
|
|
|
@ -304,7 +304,6 @@ public:
|
||||||
size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
|
size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
|
||||||
size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
|
size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
|
||||||
|
|
||||||
void setAllocator(TPoolAllocator* a) { allocator = *a; }
|
|
||||||
TPoolAllocator& getAllocator() const { return allocator; }
|
TPoolAllocator& getAllocator() const { return allocator; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -142,6 +142,7 @@ struct TBuiltInResource {
|
||||||
int maxTaskWorkGroupSizeY_NV;
|
int maxTaskWorkGroupSizeY_NV;
|
||||||
int maxTaskWorkGroupSizeZ_NV;
|
int maxTaskWorkGroupSizeZ_NV;
|
||||||
int maxMeshViewCountNV;
|
int maxMeshViewCountNV;
|
||||||
|
int maxDualSourceDrawBuffersEXT;
|
||||||
|
|
||||||
TLimits limits;
|
TLimits limits;
|
||||||
};
|
};
|
||||||
|
|
136
thirdparty/ShaderCompiler/glslang/Include/SpirvIntrinsics.h
vendored
Normal file
136
thirdparty/ShaderCompiler/glslang/Include/SpirvIntrinsics.h
vendored
Normal file
|
@ -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<TString> extensions;
|
||||||
|
// extension = [..]
|
||||||
|
TSet<int> capabilities;
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPIR-V execution modes
|
||||||
|
struct TSpirvExecutionMode {
|
||||||
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
|
|
||||||
|
// spirv_execution_mode
|
||||||
|
TMap<int, TVector<const TIntermConstantUnion*>> modes;
|
||||||
|
// spirv_execution_mode_id
|
||||||
|
TMap<int, TVector<const TIntermConstantUnion*> > modeIds;
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPIR-V decorations
|
||||||
|
struct TSpirvDecorate {
|
||||||
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
|
|
||||||
|
// spirv_decorate
|
||||||
|
TMap<int, TVector<const TIntermConstantUnion*> > decorates;
|
||||||
|
// spirv_decorate_id
|
||||||
|
TMap<int, TVector<const TIntermConstantUnion*> > decorateIds;
|
||||||
|
// spirv_decorate_string
|
||||||
|
TMap<int, TVector<const TIntermConstantUnion*> > 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<TSpirvTypeParameter> 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
|
941
thirdparty/ShaderCompiler/glslang/Include/Types.h
vendored
941
thirdparty/ShaderCompiler/glslang/Include/Types.h
vendored
File diff suppressed because it is too large
Load diff
|
@ -254,7 +254,9 @@ struct TArraySizes {
|
||||||
void addInnerSize() { addInnerSize((unsigned)UnsizedArraySize); }
|
void addInnerSize() { addInnerSize((unsigned)UnsizedArraySize); }
|
||||||
void addInnerSize(int s) { addInnerSize((unsigned)s, nullptr); }
|
void addInnerSize(int s) { addInnerSize((unsigned)s, nullptr); }
|
||||||
void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); }
|
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 addInnerSizes(const TArraySizes& s) { sizes.push_back(s.sizes); }
|
||||||
void changeOuterSize(int s) { sizes.changeFront((unsigned)s); }
|
void changeOuterSize(int s) { sizes.changeFront((unsigned)s); }
|
||||||
int getImplicitSize() const { return implicitArraySize; }
|
int getImplicitSize() const { return implicitArraySize; }
|
||||||
|
@ -318,8 +320,8 @@ struct TArraySizes {
|
||||||
void setVariablyIndexed() { variablyIndexed = true; }
|
void setVariablyIndexed() { variablyIndexed = true; }
|
||||||
bool isVariablyIndexed() const { return variablyIndexed; }
|
bool isVariablyIndexed() const { return variablyIndexed; }
|
||||||
|
|
||||||
bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
|
bool operator==(const TArraySizes& rhs) const { return sizes == rhs.sizes; }
|
||||||
bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
|
bool operator!=(const TArraySizes& rhs) const { return sizes != rhs.sizes; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TSmallArrayVector sizes;
|
TSmallArrayVector sizes;
|
||||||
|
|
62
thirdparty/ShaderCompiler/glslang/Include/build_info.h
vendored
Normal file
62
thirdparty/ShaderCompiler/glslang/Include/build_info.h
vendored
Normal file
|
@ -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
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2016 LunarG, Inc.
|
// Copyright (C) 2012-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -70,6 +71,9 @@ enum TOperator {
|
||||||
EOpFunctionCall,
|
EOpFunctionCall,
|
||||||
EOpFunction, // For function definition
|
EOpFunction, // For function definition
|
||||||
EOpParameters, // an aggregate listing the parameters to a function
|
EOpParameters, // an aggregate listing the parameters to a function
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
EOpSpirvInst,
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Unary operators
|
// Unary operators
|
||||||
|
@ -85,6 +89,8 @@ enum TOperator {
|
||||||
EOpPreIncrement,
|
EOpPreIncrement,
|
||||||
EOpPreDecrement,
|
EOpPreDecrement,
|
||||||
|
|
||||||
|
EOpCopyObject,
|
||||||
|
|
||||||
// (u)int* -> bool
|
// (u)int* -> bool
|
||||||
EOpConvInt8ToBool,
|
EOpConvInt8ToBool,
|
||||||
EOpConvUint8ToBool,
|
EOpConvUint8ToBool,
|
||||||
|
@ -273,6 +279,16 @@ enum TOperator {
|
||||||
EOpConvUint64ToPtr,
|
EOpConvUint64ToPtr,
|
||||||
EOpConvPtrToUint64,
|
EOpConvPtrToUint64,
|
||||||
|
|
||||||
|
// uvec2 <-> pointer
|
||||||
|
EOpConvUvec2ToPtr,
|
||||||
|
EOpConvPtrToUvec2,
|
||||||
|
|
||||||
|
// uint64_t -> accelerationStructureEXT
|
||||||
|
EOpConvUint64ToAccStruct,
|
||||||
|
|
||||||
|
// uvec2 -> accelerationStructureEXT
|
||||||
|
EOpConvUvec2ToAccStruct,
|
||||||
|
|
||||||
//
|
//
|
||||||
// binary operations
|
// binary operations
|
||||||
//
|
//
|
||||||
|
@ -420,11 +436,9 @@ enum TOperator {
|
||||||
EOpReflect,
|
EOpReflect,
|
||||||
EOpRefract,
|
EOpRefract,
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpMin3,
|
EOpMin3,
|
||||||
EOpMax3,
|
EOpMax3,
|
||||||
EOpMid3,
|
EOpMid3,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpDPdx, // Fragment only
|
EOpDPdx, // Fragment only
|
||||||
EOpDPdy, // Fragment only
|
EOpDPdy, // Fragment only
|
||||||
|
@ -439,10 +453,7 @@ enum TOperator {
|
||||||
EOpInterpolateAtCentroid, // Fragment only
|
EOpInterpolateAtCentroid, // Fragment only
|
||||||
EOpInterpolateAtSample, // Fragment only
|
EOpInterpolateAtSample, // Fragment only
|
||||||
EOpInterpolateAtOffset, // Fragment only
|
EOpInterpolateAtOffset, // Fragment only
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpInterpolateAtVertex,
|
EOpInterpolateAtVertex,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpMatrixTimesMatrix,
|
EOpMatrixTimesMatrix,
|
||||||
EOpOuterProduct,
|
EOpOuterProduct,
|
||||||
|
@ -532,7 +543,6 @@ enum TOperator {
|
||||||
EOpSubgroupQuadSwapVertical,
|
EOpSubgroupQuadSwapVertical,
|
||||||
EOpSubgroupQuadSwapDiagonal,
|
EOpSubgroupQuadSwapDiagonal,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
EOpSubgroupPartition,
|
EOpSubgroupPartition,
|
||||||
EOpSubgroupPartitionedAdd,
|
EOpSubgroupPartitionedAdd,
|
||||||
EOpSubgroupPartitionedMul,
|
EOpSubgroupPartitionedMul,
|
||||||
|
@ -555,11 +565,9 @@ enum TOperator {
|
||||||
EOpSubgroupPartitionedExclusiveAnd,
|
EOpSubgroupPartitionedExclusiveAnd,
|
||||||
EOpSubgroupPartitionedExclusiveOr,
|
EOpSubgroupPartitionedExclusiveOr,
|
||||||
EOpSubgroupPartitionedExclusiveXor,
|
EOpSubgroupPartitionedExclusiveXor,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpSubgroupGuardStop,
|
EOpSubgroupGuardStop,
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpMinInvocations,
|
EOpMinInvocations,
|
||||||
EOpMaxInvocations,
|
EOpMaxInvocations,
|
||||||
EOpAddInvocations,
|
EOpAddInvocations,
|
||||||
|
@ -586,9 +594,9 @@ enum TOperator {
|
||||||
EOpCubeFaceIndex,
|
EOpCubeFaceIndex,
|
||||||
EOpCubeFaceCoord,
|
EOpCubeFaceCoord,
|
||||||
EOpTime,
|
EOpTime,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpAtomicAdd,
|
EOpAtomicAdd,
|
||||||
|
EOpAtomicSubtract,
|
||||||
EOpAtomicMin,
|
EOpAtomicMin,
|
||||||
EOpAtomicMax,
|
EOpAtomicMax,
|
||||||
EOpAtomicAnd,
|
EOpAtomicAnd,
|
||||||
|
@ -615,11 +623,26 @@ enum TOperator {
|
||||||
EOpAny,
|
EOpAny,
|
||||||
EOpAll,
|
EOpAll,
|
||||||
|
|
||||||
|
EOpCooperativeMatrixLoad,
|
||||||
|
EOpCooperativeMatrixStore,
|
||||||
|
EOpCooperativeMatrixMulAdd,
|
||||||
|
|
||||||
|
EOpBeginInvocationInterlock, // Fragment only
|
||||||
|
EOpEndInvocationInterlock, // Fragment only
|
||||||
|
|
||||||
|
EOpIsHelperInvocation,
|
||||||
|
|
||||||
|
EOpDebugPrintf,
|
||||||
|
|
||||||
//
|
//
|
||||||
// Branch
|
// Branch
|
||||||
//
|
//
|
||||||
|
|
||||||
EOpKill, // Fragment only
|
EOpKill, // Fragment only
|
||||||
|
EOpTerminateInvocation, // Fragment only
|
||||||
|
EOpDemote, // Fragment only
|
||||||
|
EOpTerminateRayKHR, // Any-hit only
|
||||||
|
EOpIgnoreIntersectionKHR, // Any-hit only
|
||||||
EOpReturn,
|
EOpReturn,
|
||||||
EOpBreak,
|
EOpBreak,
|
||||||
EOpContinue,
|
EOpContinue,
|
||||||
|
@ -642,9 +665,21 @@ enum TOperator {
|
||||||
EOpConstructBool,
|
EOpConstructBool,
|
||||||
EOpConstructFloat,
|
EOpConstructFloat,
|
||||||
EOpConstructDouble,
|
EOpConstructDouble,
|
||||||
|
// Keep vector and matrix constructors in a consistent relative order for
|
||||||
|
// TParseContext::constructBuiltIn, which converts between 8/16/32 bit
|
||||||
|
// vector constructors
|
||||||
EOpConstructVec2,
|
EOpConstructVec2,
|
||||||
EOpConstructVec3,
|
EOpConstructVec3,
|
||||||
EOpConstructVec4,
|
EOpConstructVec4,
|
||||||
|
EOpConstructMat2x2,
|
||||||
|
EOpConstructMat2x3,
|
||||||
|
EOpConstructMat2x4,
|
||||||
|
EOpConstructMat3x2,
|
||||||
|
EOpConstructMat3x3,
|
||||||
|
EOpConstructMat3x4,
|
||||||
|
EOpConstructMat4x2,
|
||||||
|
EOpConstructMat4x3,
|
||||||
|
EOpConstructMat4x4,
|
||||||
EOpConstructDVec2,
|
EOpConstructDVec2,
|
||||||
EOpConstructDVec3,
|
EOpConstructDVec3,
|
||||||
EOpConstructDVec4,
|
EOpConstructDVec4,
|
||||||
|
@ -675,15 +710,6 @@ enum TOperator {
|
||||||
EOpConstructU64Vec2,
|
EOpConstructU64Vec2,
|
||||||
EOpConstructU64Vec3,
|
EOpConstructU64Vec3,
|
||||||
EOpConstructU64Vec4,
|
EOpConstructU64Vec4,
|
||||||
EOpConstructMat2x2,
|
|
||||||
EOpConstructMat2x3,
|
|
||||||
EOpConstructMat2x4,
|
|
||||||
EOpConstructMat3x2,
|
|
||||||
EOpConstructMat3x3,
|
|
||||||
EOpConstructMat3x4,
|
|
||||||
EOpConstructMat4x2,
|
|
||||||
EOpConstructMat4x3,
|
|
||||||
EOpConstructMat4x4,
|
|
||||||
EOpConstructDMat2x2,
|
EOpConstructDMat2x2,
|
||||||
EOpConstructDMat2x3,
|
EOpConstructDMat2x3,
|
||||||
EOpConstructDMat2x4,
|
EOpConstructDMat2x4,
|
||||||
|
@ -737,6 +763,8 @@ enum TOperator {
|
||||||
EOpConstructTextureSampler,
|
EOpConstructTextureSampler,
|
||||||
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
|
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
|
||||||
EOpConstructReference,
|
EOpConstructReference,
|
||||||
|
EOpConstructCooperativeMatrix,
|
||||||
|
EOpConstructAccStruct,
|
||||||
EOpConstructGuardEnd,
|
EOpConstructGuardEnd,
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -779,10 +807,8 @@ enum TOperator {
|
||||||
EOpImageQuerySamples,
|
EOpImageQuerySamples,
|
||||||
EOpImageLoad,
|
EOpImageLoad,
|
||||||
EOpImageStore,
|
EOpImageStore,
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpImageLoadLod,
|
EOpImageLoadLod,
|
||||||
EOpImageStoreLod,
|
EOpImageStoreLod,
|
||||||
#endif
|
|
||||||
EOpImageAtomicAdd,
|
EOpImageAtomicAdd,
|
||||||
EOpImageAtomicMin,
|
EOpImageAtomicMin,
|
||||||
EOpImageAtomicMax,
|
EOpImageAtomicMax,
|
||||||
|
@ -797,9 +823,7 @@ enum TOperator {
|
||||||
EOpSubpassLoad,
|
EOpSubpassLoad,
|
||||||
EOpSubpassLoadMS,
|
EOpSubpassLoadMS,
|
||||||
EOpSparseImageLoad,
|
EOpSparseImageLoad,
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpSparseImageLoadLod,
|
EOpSparseImageLoadLod,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpImageGuardEnd,
|
EOpImageGuardEnd,
|
||||||
|
|
||||||
|
@ -837,13 +861,11 @@ enum TOperator {
|
||||||
EOpTextureOffsetClamp,
|
EOpTextureOffsetClamp,
|
||||||
EOpTextureGradClamp,
|
EOpTextureGradClamp,
|
||||||
EOpTextureGradOffsetClamp,
|
EOpTextureGradOffsetClamp,
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpTextureGatherLod,
|
EOpTextureGatherLod,
|
||||||
EOpTextureGatherLodOffset,
|
EOpTextureGatherLodOffset,
|
||||||
EOpTextureGatherLodOffsets,
|
EOpTextureGatherLodOffsets,
|
||||||
EOpFragmentMaskFetch,
|
EOpFragmentMaskFetch,
|
||||||
EOpFragmentFetch,
|
EOpFragmentFetch,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpSparseTextureGuardBegin,
|
EOpSparseTextureGuardBegin,
|
||||||
|
|
||||||
|
@ -863,15 +885,12 @@ enum TOperator {
|
||||||
EOpSparseTextureOffsetClamp,
|
EOpSparseTextureOffsetClamp,
|
||||||
EOpSparseTextureGradClamp,
|
EOpSparseTextureGradClamp,
|
||||||
EOpSparseTextureGradOffsetClamp,
|
EOpSparseTextureGradOffsetClamp,
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpSparseTextureGatherLod,
|
EOpSparseTextureGatherLod,
|
||||||
EOpSparseTextureGatherLodOffset,
|
EOpSparseTextureGatherLodOffset,
|
||||||
EOpSparseTextureGatherLodOffsets,
|
EOpSparseTextureGatherLodOffsets,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpSparseTextureGuardEnd,
|
EOpSparseTextureGuardEnd,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
EOpImageFootprintGuardBegin,
|
EOpImageFootprintGuardBegin,
|
||||||
EOpImageSampleFootprintNV,
|
EOpImageSampleFootprintNV,
|
||||||
EOpImageSampleFootprintClampNV,
|
EOpImageSampleFootprintClampNV,
|
||||||
|
@ -879,7 +898,6 @@ enum TOperator {
|
||||||
EOpImageSampleFootprintGradNV,
|
EOpImageSampleFootprintGradNV,
|
||||||
EOpImageSampleFootprintGradClampNV,
|
EOpImageSampleFootprintGradClampNV,
|
||||||
EOpImageFootprintGuardEnd,
|
EOpImageFootprintGuardEnd,
|
||||||
#endif
|
|
||||||
EOpSamplingGuardEnd,
|
EOpSamplingGuardEnd,
|
||||||
EOpTextureGuardEnd,
|
EOpTextureGuardEnd,
|
||||||
|
|
||||||
|
@ -898,14 +916,53 @@ enum TOperator {
|
||||||
EOpFindLSB,
|
EOpFindLSB,
|
||||||
EOpFindMSB,
|
EOpFindMSB,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
EOpCountLeadingZeros,
|
||||||
|
EOpCountTrailingZeros,
|
||||||
|
EOpAbsDifference,
|
||||||
|
EOpAddSaturate,
|
||||||
|
EOpSubSaturate,
|
||||||
|
EOpAverage,
|
||||||
|
EOpAverageRounded,
|
||||||
|
EOpMul32x16,
|
||||||
|
|
||||||
EOpTraceNV,
|
EOpTraceNV,
|
||||||
EOpReportIntersectionNV,
|
EOpTraceRayMotionNV,
|
||||||
|
EOpTraceKHR,
|
||||||
|
EOpReportIntersection,
|
||||||
EOpIgnoreIntersectionNV,
|
EOpIgnoreIntersectionNV,
|
||||||
EOpTerminateRayNV,
|
EOpTerminateRayNV,
|
||||||
EOpExecuteCallableNV,
|
EOpExecuteCallableNV,
|
||||||
|
EOpExecuteCallableKHR,
|
||||||
EOpWritePackedPrimitiveIndices4x8NV,
|
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
|
// HLSL operations
|
||||||
//
|
//
|
||||||
|
@ -989,6 +1046,10 @@ enum TOperator {
|
||||||
EOpWaveGetLaneIndex, // Will decompose to gl_SubgroupInvocationID.
|
EOpWaveGetLaneIndex, // Will decompose to gl_SubgroupInvocationID.
|
||||||
EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()).
|
EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()).
|
||||||
EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
|
EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
|
||||||
|
|
||||||
|
// Shader Clock Ops
|
||||||
|
EOpReadClockSubgroupKHR,
|
||||||
|
EOpReadClockDeviceKHR,
|
||||||
};
|
};
|
||||||
|
|
||||||
class TIntermTraverser;
|
class TIntermTraverser;
|
||||||
|
@ -1079,6 +1140,8 @@ public:
|
||||||
virtual TBasicType getBasicType() const { return type.getBasicType(); }
|
virtual TBasicType getBasicType() const { return type.getBasicType(); }
|
||||||
virtual TQualifier& getQualifier() { return type.getQualifier(); }
|
virtual TQualifier& getQualifier() { return type.getQualifier(); }
|
||||||
virtual const TQualifier& getQualifier() const { 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 void propagatePrecision(TPrecisionQualifier);
|
||||||
virtual int getVectorSize() const { return type.getVectorSize(); }
|
virtual int getVectorSize() const { return type.getVectorSize(); }
|
||||||
virtual int getMatrixCols() const { return type.getMatrixCols(); }
|
virtual int getMatrixCols() const { return type.getMatrixCols(); }
|
||||||
|
@ -1090,6 +1153,8 @@ public:
|
||||||
virtual bool isStruct() const { return type.isStruct(); }
|
virtual bool isStruct() const { return type.isStruct(); }
|
||||||
virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
|
virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
|
||||||
virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
|
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(); }
|
TString getCompleteString() const { return type.getCompleteString(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1109,7 +1174,12 @@ public:
|
||||||
first(testFirst),
|
first(testFirst),
|
||||||
unroll(false),
|
unroll(false),
|
||||||
dontUnroll(false),
|
dontUnroll(false),
|
||||||
dependency(0)
|
dependency(0),
|
||||||
|
minIterations(0),
|
||||||
|
maxIterations(iterationsInfinite),
|
||||||
|
iterationMultiple(1),
|
||||||
|
peelCount(0),
|
||||||
|
partialCount(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual TIntermLoop* getAsLoopNode() { return this; }
|
virtual TIntermLoop* getAsLoopNode() { return this; }
|
||||||
|
@ -1121,14 +1191,36 @@ public:
|
||||||
bool testFirst() const { return first; }
|
bool testFirst() const { return first; }
|
||||||
|
|
||||||
void setUnroll() { unroll = true; }
|
void setUnroll() { unroll = true; }
|
||||||
void setDontUnroll() { dontUnroll = true; }
|
void setDontUnroll() {
|
||||||
|
dontUnroll = true;
|
||||||
|
peelCount = 0;
|
||||||
|
partialCount = 0;
|
||||||
|
}
|
||||||
bool getUnroll() const { return unroll; }
|
bool getUnroll() const { return unroll; }
|
||||||
bool getDontUnroll() const { return dontUnroll; }
|
bool getDontUnroll() const { return dontUnroll; }
|
||||||
|
|
||||||
static const unsigned int dependencyInfinite = 0xFFFFFFFF;
|
static const unsigned int dependencyInfinite = 0xFFFFFFFF;
|
||||||
|
static const unsigned int iterationsInfinite = 0xFFFFFFFF;
|
||||||
void setLoopDependency(int d) { dependency = d; }
|
void setLoopDependency(int d) { dependency = d; }
|
||||||
int getLoopDependency() const { return dependency; }
|
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:
|
protected:
|
||||||
TIntermNode* body; // code to loop over
|
TIntermNode* body; // code to loop over
|
||||||
TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
|
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 unroll; // true if unroll requested
|
||||||
bool dontUnroll; // true if request to not unroll
|
bool dontUnroll; // true if request to not unroll
|
||||||
unsigned int dependency; // loop dependency hint; 0 means not set or unknown
|
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*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
TOperator getFlowOp() const { return flowOp; }
|
TOperator getFlowOp() const { return flowOp; }
|
||||||
TIntermTyped* getExpression() const { return expression; }
|
TIntermTyped* getExpression() const { return expression; }
|
||||||
|
void setExpression(TIntermTyped* pExpression) { expression = pExpression; }
|
||||||
|
void updatePrecision(TPrecisionQualifier parentPrecision);
|
||||||
protected:
|
protected:
|
||||||
TOperator flowOp;
|
TOperator flowOp;
|
||||||
TIntermTyped* expression;
|
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
|
// 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
|
// per process threadPoolAllocator, then it causes increased memory usage per compile
|
||||||
// it is essential to use "symbol = sym" to assign to symbol
|
// 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),
|
: TIntermTyped(t), id(i),
|
||||||
#ifdef ENABLE_HLSL
|
#ifndef GLSLANG_WEB
|
||||||
flattenSubset(-1),
|
flattenSubset(-1),
|
||||||
#endif
|
#endif
|
||||||
constSubtree(nullptr)
|
constSubtree(nullptr)
|
||||||
{ name = n; }
|
{ name = n; }
|
||||||
virtual int getId() const { return id; }
|
virtual long long getId() const { return id; }
|
||||||
virtual void changeId(int i) { id = i; }
|
virtual void changeId(long long i) { id = i; }
|
||||||
virtual const TString& getName() const { return name; }
|
virtual const TString& getName() const { return name; }
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
virtual TIntermSymbol* getAsSymbolNode() { return this; }
|
virtual TIntermSymbol* getAsSymbolNode() { return this; }
|
||||||
|
@ -1200,18 +1299,20 @@ public:
|
||||||
const TConstUnionArray& getConstArray() const { return constArray; }
|
const TConstUnionArray& getConstArray() const { return constArray; }
|
||||||
void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
|
void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
|
||||||
TIntermTyped* getConstSubtree() const { return constSubtree; }
|
TIntermTyped* getConstSubtree() const { return constSubtree; }
|
||||||
#ifdef ENABLE_HLSL
|
#ifndef GLSLANG_WEB
|
||||||
void setFlattenSubset(int subset) { flattenSubset = subset; }
|
void setFlattenSubset(int subset) { flattenSubset = subset; }
|
||||||
|
virtual const TString& getAccessName() const;
|
||||||
|
|
||||||
int getFlattenSubset() const { return flattenSubset; } // -1 means full object
|
int getFlattenSubset() const { return flattenSubset; } // -1 means full object
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This is meant for cases where a node has already been constructed, and
|
// This is meant for cases where a node has already been constructed, and
|
||||||
// later on, it becomes necessary to switch to a different symbol.
|
// 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:
|
protected:
|
||||||
int id; // the unique id of the symbol this node represents
|
long long id; // the unique id of the symbol this node represents
|
||||||
#ifdef ENABLE_HLSL
|
#ifndef GLSLANG_WEB
|
||||||
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
|
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
|
||||||
#endif
|
#endif
|
||||||
TString name; // the name of the symbol this node represents
|
TString name; // the name of the symbol this node represents
|
||||||
|
@ -1251,9 +1352,7 @@ struct TCrackedTextureOp {
|
||||||
bool grad;
|
bool grad;
|
||||||
bool subpass;
|
bool subpass;
|
||||||
bool lodClamp;
|
bool lodClamp;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
bool fragMask;
|
bool fragMask;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1269,12 +1368,19 @@ public:
|
||||||
bool isConstructor() const;
|
bool isConstructor() const;
|
||||||
bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
|
bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
|
||||||
bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
|
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 isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
|
||||||
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
|
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
|
bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
|
||||||
#endif
|
|
||||||
bool isSparseImage() const { return op == EOpSparseImageLoad; }
|
bool isSparseImage() const { return op == EOpSparseImageLoad; }
|
||||||
|
bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; }
|
||||||
|
#endif
|
||||||
|
|
||||||
void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
|
void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
|
||||||
TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
|
TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
|
||||||
|
@ -1304,9 +1410,7 @@ public:
|
||||||
cracked.grad = false;
|
cracked.grad = false;
|
||||||
cracked.subpass = false;
|
cracked.subpass = false;
|
||||||
cracked.lodClamp = false;
|
cracked.lodClamp = false;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
cracked.fragMask = false;
|
cracked.fragMask = false;
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case EOpImageQuerySize:
|
case EOpImageQuerySize:
|
||||||
|
@ -1321,10 +1425,6 @@ public:
|
||||||
case EOpTexture:
|
case EOpTexture:
|
||||||
case EOpSparseTexture:
|
case EOpSparseTexture:
|
||||||
break;
|
break;
|
||||||
case EOpTextureClamp:
|
|
||||||
case EOpSparseTextureClamp:
|
|
||||||
cracked.lodClamp = true;
|
|
||||||
break;
|
|
||||||
case EOpTextureProj:
|
case EOpTextureProj:
|
||||||
cracked.proj = true;
|
cracked.proj = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1336,22 +1436,17 @@ public:
|
||||||
case EOpSparseTextureOffset:
|
case EOpSparseTextureOffset:
|
||||||
cracked.offset = true;
|
cracked.offset = true;
|
||||||
break;
|
break;
|
||||||
case EOpTextureOffsetClamp:
|
|
||||||
case EOpSparseTextureOffsetClamp:
|
|
||||||
cracked.offset = true;
|
|
||||||
cracked.lodClamp = true;
|
|
||||||
break;
|
|
||||||
case EOpTextureFetch:
|
case EOpTextureFetch:
|
||||||
case EOpSparseTextureFetch:
|
case EOpSparseTextureFetch:
|
||||||
cracked.fetch = true;
|
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;
|
cracked.lod = true;
|
||||||
break;
|
break;
|
||||||
case EOpTextureFetchOffset:
|
case EOpTextureFetchOffset:
|
||||||
case EOpSparseTextureFetchOffset:
|
case EOpSparseTextureFetchOffset:
|
||||||
cracked.fetch = true;
|
cracked.fetch = true;
|
||||||
cracked.offset = 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;
|
cracked.lod = true;
|
||||||
break;
|
break;
|
||||||
case EOpTextureProjOffset:
|
case EOpTextureProjOffset:
|
||||||
|
@ -1376,11 +1471,6 @@ public:
|
||||||
case EOpSparseTextureGrad:
|
case EOpSparseTextureGrad:
|
||||||
cracked.grad = true;
|
cracked.grad = true;
|
||||||
break;
|
break;
|
||||||
case EOpTextureGradClamp:
|
|
||||||
case EOpSparseTextureGradClamp:
|
|
||||||
cracked.grad = true;
|
|
||||||
cracked.lodClamp = true;
|
|
||||||
break;
|
|
||||||
case EOpTextureGradOffset:
|
case EOpTextureGradOffset:
|
||||||
case EOpSparseTextureGradOffset:
|
case EOpSparseTextureGradOffset:
|
||||||
cracked.grad = true;
|
cracked.grad = true;
|
||||||
|
@ -1395,6 +1485,21 @@ public:
|
||||||
cracked.offset = true;
|
cracked.offset = true;
|
||||||
cracked.proj = true;
|
cracked.proj = true;
|
||||||
break;
|
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 EOpTextureGradOffsetClamp:
|
||||||
case EOpSparseTextureGradOffsetClamp:
|
case EOpSparseTextureGradOffsetClamp:
|
||||||
cracked.grad = true;
|
cracked.grad = true;
|
||||||
|
@ -1415,7 +1520,6 @@ public:
|
||||||
cracked.gather = true;
|
cracked.gather = true;
|
||||||
cracked.offsets = true;
|
cracked.offsets = true;
|
||||||
break;
|
break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpTextureGatherLod:
|
case EOpTextureGatherLod:
|
||||||
case EOpSparseTextureGatherLod:
|
case EOpSparseTextureGatherLod:
|
||||||
cracked.gather = true;
|
cracked.gather = true;
|
||||||
|
@ -1446,8 +1550,6 @@ public:
|
||||||
cracked.subpass = sampler.dim == EsdSubpass;
|
cracked.subpass = sampler.dim == EsdSubpass;
|
||||||
cracked.fragMask = true;
|
cracked.fragMask = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EOpImageSampleFootprintNV:
|
case EOpImageSampleFootprintNV:
|
||||||
break;
|
break;
|
||||||
case EOpImageSampleFootprintClampNV:
|
case EOpImageSampleFootprintClampNV:
|
||||||
|
@ -1463,11 +1565,11 @@ public:
|
||||||
cracked.lodClamp = true;
|
cracked.lodClamp = true;
|
||||||
cracked.grad = true;
|
cracked.grad = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case EOpSubpassLoad:
|
case EOpSubpassLoad:
|
||||||
case EOpSubpassLoadMS:
|
case EOpSubpassLoadMS:
|
||||||
cracked.subpass = true;
|
cracked.subpass = true;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1518,8 +1620,15 @@ public:
|
||||||
virtual TIntermUnary* getAsUnaryNode() { return this; }
|
virtual TIntermUnary* getAsUnaryNode() { return this; }
|
||||||
virtual const TIntermUnary* getAsUnaryNode() const { return this; }
|
virtual const TIntermUnary* getAsUnaryNode() const { return this; }
|
||||||
virtual void updatePrecision();
|
virtual void updatePrecision();
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
|
||||||
|
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
|
||||||
|
#endif
|
||||||
protected:
|
protected:
|
||||||
TIntermTyped* operand;
|
TIntermTyped* operand;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
TSpirvInstruction spirvInst;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TVector<TIntermNode*> TIntermSequence;
|
typedef TVector<TIntermNode*> TIntermSequence;
|
||||||
|
@ -1550,6 +1659,10 @@ public:
|
||||||
bool getDebug() const { return debug; }
|
bool getDebug() const { return debug; }
|
||||||
void setPragmaTable(const TPragmaTable& pTable);
|
void setPragmaTable(const TPragmaTable& pTable);
|
||||||
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
|
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
|
||||||
|
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
|
||||||
|
#endif
|
||||||
protected:
|
protected:
|
||||||
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
|
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
|
||||||
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
|
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
|
||||||
|
@ -1560,6 +1673,9 @@ protected:
|
||||||
bool optimize;
|
bool optimize;
|
||||||
bool debug;
|
bool debug;
|
||||||
TPragmaTable* pragmaTable;
|
TPragmaTable* pragmaTable;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
TSpirvInstruction spirvInst;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1577,8 +1693,11 @@ public:
|
||||||
flatten(false), dontFlatten(false) {}
|
flatten(false), dontFlatten(false) {}
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
virtual TIntermTyped* getCondition() const { return condition; }
|
virtual TIntermTyped* getCondition() const { return condition; }
|
||||||
|
virtual void setCondition(TIntermTyped* c) { condition = c; }
|
||||||
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
|
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
|
||||||
|
virtual void setTrueBlock(TIntermTyped* tb) { trueBlock = tb; }
|
||||||
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
|
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
|
||||||
|
virtual void setFalseBlock(TIntermTyped* fb) { falseBlock = fb; }
|
||||||
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
||||||
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
|
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
// This header is generated by the make-revision script.
|
|
||||||
|
|
||||||
#define GLSLANG_PATCH_LEVEL 3057
|
|
|
@ -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$"
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
// Copyright (C) 2018 Google, Inc.
|
// Copyright (C) 2018-2020 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -42,6 +42,10 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable: 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using namespace glslang;
|
using namespace glslang;
|
||||||
|
@ -189,6 +193,24 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
||||||
else
|
else
|
||||||
newConstArray[i].setDConst((double)NAN);
|
newConstArray[i].setDConst((double)NAN);
|
||||||
break;
|
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:
|
case EbtInt8:
|
||||||
if (rightUnionArray[i] == (signed char)0)
|
if (rightUnionArray[i] == (signed char)0)
|
||||||
newConstArray[i].setI8Const((signed char)0x7F);
|
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());
|
newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const());
|
||||||
break;
|
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:
|
case EbtInt64:
|
||||||
if (rightUnionArray[i] == 0ll)
|
if (rightUnionArray[i] == 0ll)
|
||||||
newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll);
|
newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll);
|
||||||
else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == -(long long)0x8000000000000000ll)
|
else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == (long long)-0x8000000000000000ll)
|
||||||
newConstArray[i].setI64Const(-(long long)0x8000000000000000ll);
|
newConstArray[i].setI64Const((long long)-0x8000000000000000ll);
|
||||||
else
|
else
|
||||||
newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const());
|
newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const());
|
||||||
break;
|
break;
|
||||||
|
@ -254,6 +260,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -292,13 +299,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
||||||
newConstArray[i].setIConst(0);
|
newConstArray[i].setIConst(0);
|
||||||
break;
|
break;
|
||||||
} else goto modulo_default;
|
} else goto modulo_default;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) {
|
if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) {
|
||||||
newConstArray[i].setI64Const(0);
|
newConstArray[i].setI64Const(0);
|
||||||
break;
|
break;
|
||||||
} else goto modulo_default;
|
} else goto modulo_default;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == SHRT_MIN) {
|
if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == SHRT_MIN) {
|
||||||
newConstArray[i].setIConst(0);
|
newConstArray[i].setIConst(0);
|
||||||
|
@ -415,8 +421,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
|
|
||||||
case EOpEmitStreamVertex:
|
case EOpEmitStreamVertex:
|
||||||
case EOpEndStreamPrimitive:
|
case EOpEndStreamPrimitive:
|
||||||
// These don't actually fold
|
// These don't fold
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
case EOpPackSnorm2x16:
|
case EOpPackSnorm2x16:
|
||||||
case EOpPackUnorm2x16:
|
case EOpPackUnorm2x16:
|
||||||
|
@ -491,8 +497,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
|
|
||||||
|
|
||||||
case EOpPackSnorm2x16:
|
case EOpPackSnorm2x16:
|
||||||
case EOpPackUnorm2x16:
|
case EOpPackUnorm2x16:
|
||||||
case EOpPackHalf2x16:
|
case EOpPackHalf2x16:
|
||||||
|
@ -510,7 +514,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
case EOpDeterminant:
|
case EOpDeterminant:
|
||||||
case EOpMatrixInverse:
|
case EOpMatrixInverse:
|
||||||
case EOpTranspose:
|
case EOpTranspose:
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(componentWise);
|
assert(componentWise);
|
||||||
|
@ -529,16 +533,23 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
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<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
|
case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
|
||||||
case EbtUint8: newConstArray[i].setU8Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU8Const()))); break;
|
case EbtUint8: newConstArray[i].setU8Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU8Const()))); break;
|
||||||
case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break;
|
case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break;
|
||||||
case EbtUint16:newConstArray[i].setU16Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU16Const()))); break;
|
case EbtUint16:newConstArray[i].setU16Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU16Const()))); break;
|
||||||
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
|
||||||
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
|
||||||
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
|
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
|
||||||
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
|
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EOpLogicalNot:
|
case EOpLogicalNot:
|
||||||
|
@ -546,7 +557,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
switch (getType().getBasicType()) {
|
switch (getType().getBasicType()) {
|
||||||
case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
|
case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EOpBitwiseNot:
|
case EOpBitwiseNot:
|
||||||
|
@ -597,17 +608,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
newConstArray[i].setDConst(log(unionArray[i].getDConst()));
|
newConstArray[i].setDConst(log(unionArray[i].getDConst()));
|
||||||
break;
|
break;
|
||||||
case EOpExp2:
|
case EOpExp2:
|
||||||
{
|
newConstArray[i].setDConst(exp2(unionArray[i].getDConst()));
|
||||||
const double inv_log2_e = 0.69314718055994530941723212145818;
|
|
||||||
newConstArray[i].setDConst(exp(unionArray[i].getDConst() * inv_log2_e));
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case EOpLog2:
|
case EOpLog2:
|
||||||
{
|
newConstArray[i].setDConst(log2(unionArray[i].getDConst()));
|
||||||
const double log2_e = 1.4426950408889634073599246810019;
|
|
||||||
newConstArray[i].setDConst(log2_e * log(unionArray[i].getDConst()));
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case EOpSqrt:
|
case EOpSqrt:
|
||||||
newConstArray[i].setDConst(sqrt(unionArray[i].getDConst()));
|
newConstArray[i].setDConst(sqrt(unionArray[i].getDConst()));
|
||||||
break;
|
break;
|
||||||
|
@ -671,6 +676,48 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
break;
|
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<unsigned int>(unionArray[i].getDConst())); break;
|
||||||
|
|
||||||
|
case EOpConvFloatToInt:
|
||||||
|
case EOpConvDoubleToInt:
|
||||||
|
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EOpConvInt8ToBool:
|
case EOpConvInt8ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break;
|
||||||
case EOpConvUint8ToBool:
|
case EOpConvUint8ToBool:
|
||||||
|
@ -679,20 +726,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
newConstArray[i].setBConst(unionArray[i].getI16Const() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getI16Const() != 0); break;
|
||||||
case EOpConvUint16ToBool:
|
case EOpConvUint16ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getU16Const() != 0); break;
|
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:
|
case EOpConvInt64ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
||||||
case EOpConvUint64ToBool:
|
case EOpConvUint64ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
||||||
case EOpConvFloat16ToBool:
|
case EOpConvFloat16ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
|
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:
|
case EOpConvBoolToInt8:
|
||||||
newConstArray[i].setI8Const(unionArray[i].getBConst()); break;
|
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;
|
newConstArray[i].setI16Const(unionArray[i].getBConst()); break;
|
||||||
case EOpConvBoolToUint16:
|
case EOpConvBoolToUint16:
|
||||||
newConstArray[i].setU16Const(unionArray[i].getBConst()); break;
|
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:
|
case EOpConvBoolToInt64:
|
||||||
newConstArray[i].setI64Const(unionArray[i].getBConst()); break;
|
newConstArray[i].setI64Const(unionArray[i].getBConst()); break;
|
||||||
case EOpConvBoolToUint64:
|
case EOpConvBoolToUint64:
|
||||||
newConstArray[i].setU64Const(unionArray[i].getBConst()); break;
|
newConstArray[i].setU64Const(unionArray[i].getBConst()); break;
|
||||||
case EOpConvBoolToFloat16:
|
case EOpConvBoolToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
|
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:
|
case EOpConvInt8ToInt16:
|
||||||
newConstArray[i].setI16Const(unionArray[i].getI8Const()); break;
|
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;
|
newConstArray[i].setU8Const((unsigned char)unionArray[i].getIConst()); break;
|
||||||
case EOpConvIntToUint16:
|
case EOpConvIntToUint16:
|
||||||
newConstArray[i].setU16Const((unsigned char)unionArray[i].getIConst()); break;
|
newConstArray[i].setU16Const((unsigned char)unionArray[i].getIConst()); break;
|
||||||
case EOpConvIntToUint:
|
|
||||||
newConstArray[i].setUConst(unionArray[i].getIConst()); break;
|
|
||||||
case EOpConvIntToUint64:
|
case EOpConvIntToUint64:
|
||||||
newConstArray[i].setU64Const(unionArray[i].getIConst()); break;
|
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;
|
newConstArray[i].setI8Const((signed char)unionArray[i].getUConst()); break;
|
||||||
case EOpConvUintToInt16:
|
case EOpConvUintToInt16:
|
||||||
newConstArray[i].setI16Const((signed short)unionArray[i].getUConst()); break;
|
newConstArray[i].setI16Const((signed short)unionArray[i].getUConst()); break;
|
||||||
case EOpConvUintToInt:
|
|
||||||
newConstArray[i].setIConst(unionArray[i].getUConst()); break;
|
|
||||||
case EOpConvUintToInt64:
|
case EOpConvUintToInt64:
|
||||||
newConstArray[i].setI64Const(unionArray[i].getUConst()); break;
|
newConstArray[i].setI64Const(unionArray[i].getUConst()); break;
|
||||||
case EOpConvUintToUint8:
|
case EOpConvUintToUint8:
|
||||||
|
@ -831,16 +858,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
newConstArray[i].setU64Const(unionArray[i].getUConst()); break;
|
newConstArray[i].setU64Const(unionArray[i].getUConst()); break;
|
||||||
case EOpConvIntToFloat16:
|
case EOpConvIntToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
|
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:
|
case EOpConvUintToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
|
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:
|
case EOpConvInt64ToInt8:
|
||||||
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI64Const())); break;
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI64Const())); break;
|
||||||
case EOpConvInt64ToInt16:
|
case EOpConvInt64ToInt16:
|
||||||
|
@ -905,44 +924,35 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToInt16:
|
case EOpConvFloatToInt16:
|
||||||
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToInt:
|
|
||||||
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
|
|
||||||
case EOpConvFloatToInt64:
|
case EOpConvFloatToInt64:
|
||||||
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToUint8:
|
case EOpConvFloatToUint8:
|
||||||
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToUint16:
|
case EOpConvFloatToUint16:
|
||||||
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToUint:
|
|
||||||
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
|
|
||||||
case EOpConvFloatToUint64:
|
case EOpConvFloatToUint64:
|
||||||
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToFloat16:
|
case EOpConvFloatToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
case EOpConvFloatToDouble:
|
|
||||||
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
|
||||||
case EOpConvDoubleToInt8:
|
case EOpConvDoubleToInt8:
|
||||||
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToInt16:
|
case EOpConvDoubleToInt16:
|
||||||
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToInt:
|
|
||||||
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
|
|
||||||
case EOpConvDoubleToInt64:
|
case EOpConvDoubleToInt64:
|
||||||
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToUint8:
|
case EOpConvDoubleToUint8:
|
||||||
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToUint16:
|
case EOpConvDoubleToUint16:
|
||||||
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToUint:
|
|
||||||
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
|
|
||||||
case EOpConvDoubleToUint64:
|
case EOpConvDoubleToUint64:
|
||||||
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToFloat16:
|
case EOpConvDoubleToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
case EOpConvDoubleToFloat:
|
case EOpConvPtrToUint64:
|
||||||
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
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
|
// 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 EOpInt16BitsToFloat16:
|
||||||
case EOpUint16BitsToFloat16:
|
case EOpUint16BitsToFloat16:
|
||||||
default:
|
default:
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1005,6 +1015,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
case EOpMin:
|
case EOpMin:
|
||||||
case EOpMax:
|
case EOpMax:
|
||||||
case EOpMix:
|
case EOpMix:
|
||||||
|
case EOpMod:
|
||||||
case EOpClamp:
|
case EOpClamp:
|
||||||
case EOpLessThan:
|
case EOpLessThan:
|
||||||
case EOpGreaterThan:
|
case EOpGreaterThan:
|
||||||
|
@ -1067,6 +1078,14 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
case EOpPow:
|
case EOpPow:
|
||||||
newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
||||||
break;
|
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:
|
case EOpMin:
|
||||||
switch(children[0]->getAsTyped()->getBasicType()) {
|
switch(children[0]->getAsTyped()->getBasicType()) {
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
|
@ -1074,6 +1093,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
||||||
break;
|
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:
|
case EbtInt8:
|
||||||
newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
||||||
break;
|
break;
|
||||||
|
@ -1086,18 +1112,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
newConstArray[comp].setU16Const(std::min(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
newConstArray[comp].setU16Const(std::min(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
||||||
break;
|
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:
|
case EbtInt64:
|
||||||
newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
||||||
break;
|
break;
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1108,6 +1129,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
||||||
break;
|
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:
|
case EbtInt8:
|
||||||
newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
||||||
break;
|
break;
|
||||||
|
@ -1120,18 +1148,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
newConstArray[comp].setU16Const(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
newConstArray[comp].setU16Const(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
||||||
break;
|
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:
|
case EbtInt64:
|
||||||
newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
||||||
break;
|
break;
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
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()),
|
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
|
||||||
childConstUnions[2][arg2comp].getDConst()));
|
childConstUnions[2][arg2comp].getDConst()));
|
||||||
break;
|
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:
|
case EbtInt8:
|
||||||
newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()),
|
newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()),
|
||||||
childConstUnions[2][arg2comp].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()),
|
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()),
|
||||||
childConstUnions[2][arg2comp].getIConst()));
|
childConstUnions[2][arg2comp].getIConst()));
|
||||||
break;
|
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:
|
case EbtInt64:
|
||||||
newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()),
|
newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()),
|
||||||
childConstUnions[2][arg2comp].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()),
|
newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()),
|
||||||
childConstUnions[2][arg2comp].getU64Const()));
|
childConstUnions[2][arg2comp].getU64Const()));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1197,12 +1222,17 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
newConstArray[comp].setBConst(childConstUnions[0][arg0comp] != childConstUnions[1][arg1comp]);
|
newConstArray[comp].setBConst(childConstUnions[0][arg0comp] != childConstUnions[1][arg1comp]);
|
||||||
break;
|
break;
|
||||||
case EOpMix:
|
case EOpMix:
|
||||||
if (children[2]->getAsTyped()->getBasicType() == EbtBool)
|
if (!children[0]->getAsTyped()->isFloatingDomain())
|
||||||
newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst() ? childConstUnions[1][arg1comp].getDConst() :
|
return aggrNode;
|
||||||
childConstUnions[0][arg0comp].getDConst());
|
if (children[2]->getAsTyped()->getBasicType() == EbtBool) {
|
||||||
else
|
newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst()
|
||||||
newConstArray[comp].setDConst(childConstUnions[0][arg0comp].getDConst() * (1.0 - childConstUnions[2][arg2comp].getDConst()) +
|
? 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());
|
childConstUnions[1][arg1comp].getDConst() * childConstUnions[2][arg2comp].getDConst());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EOpStep:
|
case EOpStep:
|
||||||
newConstArray[comp].setDConst(childConstUnions[1][arg1comp].getDConst() < childConstUnions[0][arg0comp].getDConst() ? 0.0 : 1.0);
|
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
|
// arrays, vectors, matrices, all use simple multiplicative math
|
||||||
// while structures need to add up heterogeneous members
|
// while structures need to add up heterogeneous members
|
||||||
int start;
|
int start;
|
||||||
if (node->isArray() || ! node->isStruct())
|
if (node->getType().isCoopMat())
|
||||||
|
start = 0;
|
||||||
|
else if (node->isArray() || ! node->isStruct())
|
||||||
start = size * index;
|
start = size * index;
|
||||||
else {
|
else {
|
||||||
// it is a structure
|
// it is a structure
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -91,6 +91,8 @@ public:
|
||||||
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
|
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
|
||||||
|
|
||||||
protected:
|
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 add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
|
||||||
void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile);
|
void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
|
|
|
@ -71,6 +71,13 @@ void TIntermConstantUnion::traverse(TIntermTraverser *it)
|
||||||
it->visitConstantUnion(this);
|
it->visitConstantUnion(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TString& TIntermSymbol::getAccessName() const {
|
||||||
|
if (getBasicType() == EbtBlock)
|
||||||
|
return getType().getTypeName();
|
||||||
|
else
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Traverse a binary node.
|
// Traverse a binary node.
|
||||||
//
|
//
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -74,14 +74,33 @@ public:
|
||||||
for (unsigned int f = 0; f < globals.size(); ++f) {
|
for (unsigned int f = 0; f < globals.size(); ++f) {
|
||||||
TIntermAggregate* candidate = globals[f]->getAsAggregate();
|
TIntermAggregate* candidate = globals[f]->getAsAggregate();
|
||||||
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
|
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
|
||||||
functions.push_back(candidate);
|
destinations.push_back(candidate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::list<TIntermAggregate*> TFunctionStack;
|
void pushGlobalReference(const TString& name)
|
||||||
TFunctionStack functions;
|
{
|
||||||
|
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<TIntermAggregate*> TDestinationStack;
|
||||||
|
TDestinationStack destinations;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// To catch which function calls are not dead, and hence which functions must be visited.
|
// 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.
|
// and only visit each function once.
|
||||||
void addFunctionCall(TIntermAggregate* call)
|
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()) {
|
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
|
||||||
liveFunctions.insert(call->getName());
|
liveFunctions.insert(call->getName());
|
||||||
pushFunction(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;
|
const TIntermediate& intermediate;
|
||||||
typedef std::unordered_set<TString> TLiveFunctions;
|
typedef std::unordered_set<TString> TLiveFunctions;
|
||||||
TLiveFunctions liveFunctions;
|
TLiveFunctions liveFunctions;
|
||||||
|
typedef std::unordered_set<TString> TLiveGlobals;
|
||||||
|
TLiveGlobals liveGlobals;
|
||||||
bool traverseAll;
|
bool traverseAll;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -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,
|
void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...)
|
const char* szExtraInfoFormat, ...)
|
||||||
{
|
{
|
||||||
|
@ -113,6 +115,8 @@ void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReaso
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Both test and if necessary, spit out an error, to see if the node is really
|
// 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.
|
// 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();
|
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;
|
const char* symbol = nullptr;
|
||||||
TIntermSymbol* symNode = node->getAsSymbolNode();
|
TIntermSymbol* symNode = node->getAsSymbolNode();
|
||||||
if (symNode != nullptr)
|
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 EvqConst: message = "can't modify a const"; break;
|
||||||
case EvqConstReadOnly: 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;
|
case EvqUniform: message = "can't modify a uniform"; break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EvqBuffer:
|
case EvqBuffer:
|
||||||
if (node->getQualifier().readonly)
|
if (node->getQualifier().isReadOnly())
|
||||||
message = "can't modify a readonly buffer";
|
message = "can't modify a readonly buffer";
|
||||||
|
if (node->getQualifier().isShaderRecord())
|
||||||
|
message = "can't modify a shaderrecordnv qualified buffer";
|
||||||
break;
|
break;
|
||||||
#ifdef NV_EXTENSIONS
|
case EvqHitAttr:
|
||||||
case EvqHitAttrNV:
|
if (language != EShLangIntersect)
|
||||||
if (language != EShLangIntersectNV)
|
|
||||||
message = "cannot modify hitAttributeNV in this stage";
|
message = "cannot modify hitAttributeNV in this stage";
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -168,16 +158,19 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
message = "can't modify a sampler";
|
message = "can't modify a sampler";
|
||||||
break;
|
break;
|
||||||
case EbtAtomicUint:
|
|
||||||
message = "can't modify an atomic_uint";
|
|
||||||
break;
|
|
||||||
case EbtVoid:
|
case EbtVoid:
|
||||||
message = "can't modify void";
|
message = "can't modify void";
|
||||||
break;
|
break;
|
||||||
#ifdef NV_EXTENSIONS
|
#ifndef GLSLANG_WEB
|
||||||
case EbtAccStructNV:
|
case EbtAtomicUint:
|
||||||
|
message = "can't modify an atomic_uint";
|
||||||
|
break;
|
||||||
|
case EbtAccStruct:
|
||||||
message = "can't modify accelerationStructureNV";
|
message = "can't modify accelerationStructureNV";
|
||||||
break;
|
break;
|
||||||
|
case EbtRayQuery:
|
||||||
|
message = "can't modify rayQueryEXT";
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -194,13 +187,38 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
||||||
// Everything else is okay, no error.
|
// Everything else is okay, no error.
|
||||||
//
|
//
|
||||||
if (message == nullptr)
|
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;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// If we get here, we have an error and a message.
|
// If we get here, we have an error and a message.
|
||||||
//
|
//
|
||||||
|
const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true);
|
||||||
|
|
||||||
if (symNode)
|
if (symNode)
|
||||||
error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
|
error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
|
||||||
|
else
|
||||||
|
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
|
else
|
||||||
error(loc, " l-value required", op, "(%s)", message);
|
error(loc, " l-value required", op, "(%s)", message);
|
||||||
|
|
||||||
|
@ -210,10 +228,28 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
||||||
// Test for and give an error if the node can't be read from.
|
// 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)
|
void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
|
||||||
{
|
{
|
||||||
|
TIntermBinary* binaryNode = node->getAsBinaryNode();
|
||||||
|
const TIntermSymbol* symNode = node->getAsSymbolNode();
|
||||||
|
|
||||||
if (! node)
|
if (! node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TIntermBinary* binaryNode = node->getAsBinaryNode();
|
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) {
|
if (binaryNode) {
|
||||||
switch (binaryNode->getOp()) {
|
switch (binaryNode->getOp()) {
|
||||||
case EOpIndexDirect:
|
case EOpIndexDirect:
|
||||||
|
@ -225,13 +261,8 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
|
||||||
default:
|
default:
|
||||||
break;
|
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
|
// Add 'symbol' to the list of deferred linkage symbols, which
|
||||||
|
@ -250,11 +281,17 @@ void TParseContextBase::trackLinkage(TSymbol& symbol)
|
||||||
// Give an error if not.
|
// Give an error if not.
|
||||||
void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index)
|
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) {
|
if (index < 0) {
|
||||||
error(loc, "", "[", "index out of range '%d'", index);
|
error(loc, "", "[", "index out of range '%d'", index);
|
||||||
index = 0;
|
index = 0;
|
||||||
} else if (type.isArray()) {
|
} 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);
|
error(loc, "", "[", "array index out of range '%d'", index);
|
||||||
index = type.getOuterArraySize() - 1;
|
index = type.getOuterArraySize() - 1;
|
||||||
}
|
}
|
||||||
|
@ -609,6 +646,67 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
|
||||||
++firstNewMember;
|
++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()
|
void TParseContextBase::finish()
|
||||||
{
|
{
|
||||||
if (parsingBuiltins)
|
if (parsingBuiltins)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -67,7 +67,8 @@ struct TPragma {
|
||||||
class TScanContext;
|
class TScanContext;
|
||||||
class TPpContext;
|
class TPpContext;
|
||||||
|
|
||||||
typedef std::set<int> TIdSetType;
|
typedef std::set<long long> TIdSetType;
|
||||||
|
typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sharable code (as well as what's in TParseVersions) across
|
// Sharable code (as well as what's in TParseVersions) across
|
||||||
|
@ -82,20 +83,24 @@ public:
|
||||||
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||||
scopeMangler("::"),
|
scopeMangler("::"),
|
||||||
symbolTable(symbolTable),
|
symbolTable(symbolTable),
|
||||||
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), blockNestingLevel(0), controlFlowNestingLevel(0),
|
||||||
|
currentFunctionType(nullptr),
|
||||||
postEntryPointReturn(false),
|
postEntryPointReturn(false),
|
||||||
contextPragma(true, false),
|
contextPragma(true, false),
|
||||||
|
beginInvocationInterlockCount(0), endInvocationInterlockCount(0),
|
||||||
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
||||||
limits(resources.limits),
|
limits(resources.limits),
|
||||||
globalUniformBlock(nullptr),
|
globalUniformBlock(nullptr),
|
||||||
globalUniformBinding(TQualifier::layoutBindingEnd),
|
globalUniformBinding(TQualifier::layoutBindingEnd),
|
||||||
globalUniformSet(TQualifier::layoutSetEnd)
|
globalUniformSet(TQualifier::layoutSetEnd),
|
||||||
|
atomicCounterBlockSet(TQualifier::layoutSetEnd)
|
||||||
{
|
{
|
||||||
if (entryPoint != nullptr)
|
if (entryPoint != nullptr)
|
||||||
sourceEntryPointName = *entryPoint;
|
sourceEntryPointName = *entryPoint;
|
||||||
}
|
}
|
||||||
virtual ~TParseContextBase() { }
|
virtual ~TParseContextBase() { }
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL)
|
||||||
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...);
|
const char* szExtraInfoFormat, ...);
|
||||||
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
@ -104,6 +109,7 @@ public:
|
||||||
const char* szExtraInfoFormat, ...);
|
const char* szExtraInfoFormat, ...);
|
||||||
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...);
|
const char* szExtraInfoFormat, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual void setLimits(const TBuiltInResource&) = 0;
|
virtual void setLimits(const TBuiltInResource&) = 0;
|
||||||
|
|
||||||
|
@ -152,6 +158,9 @@ public:
|
||||||
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
||||||
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
|
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
|
// Potentially rename shader entry point function
|
||||||
void renameShaderFunction(TString*& name) const
|
void renameShaderFunction(TString*& name) const
|
||||||
{
|
{
|
||||||
|
@ -171,7 +180,8 @@ public:
|
||||||
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
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 statementNestingLevel; // 0 if outside all flow control or compound statements
|
||||||
int loopNestingLevel; // 0 if outside all loops
|
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
|
int controlFlowNestingLevel; // 0 if outside all flow control
|
||||||
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
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
|
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
|
// the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
||||||
TList<int> switchLevel;
|
TList<int> switchLevel;
|
||||||
struct TPragma contextPragma;
|
struct TPragma contextPragma;
|
||||||
|
int beginInvocationInterlockCount;
|
||||||
|
int endInvocationInterlockCount;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TParseContextBase(TParseContextBase&);
|
TParseContextBase(TParseContextBase&);
|
||||||
|
@ -221,6 +233,24 @@ protected:
|
||||||
virtual const char* getGlobalUniformBlockName() const { return ""; }
|
virtual const char* getGlobalUniformBlockName() const { return ""; }
|
||||||
virtual void setUniformBlockDefaults(TType&) const { }
|
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<int, TVariable*> atomicCounterBuffers;
|
||||||
|
unsigned int atomicCounterBlockSet;
|
||||||
|
TMap<int, int> 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,
|
virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, TPrefixType prefix,
|
const char* szExtraInfoFormat, TPrefixType prefix,
|
||||||
va_list args);
|
va_list args);
|
||||||
|
@ -276,13 +306,16 @@ public:
|
||||||
const TString* entryPoint = nullptr);
|
const TString* entryPoint = nullptr);
|
||||||
virtual ~TParseContext();
|
virtual ~TParseContext();
|
||||||
|
|
||||||
bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); };
|
bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); }
|
||||||
void setPrecisionDefaults();
|
void setPrecisionDefaults();
|
||||||
|
|
||||||
void setLimits(const TBuiltInResource&) override;
|
void setLimits(const TBuiltInResource&) override;
|
||||||
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
|
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
|
||||||
void parserError(const char* s); // for bison's yyerror
|
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 reservedErrorCheck(const TSourceLoc&, const TString&);
|
||||||
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
|
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
|
||||||
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
|
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
|
||||||
|
@ -294,18 +327,21 @@ public:
|
||||||
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
||||||
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
void makeEditable(TSymbol*&) override;
|
void makeEditable(TSymbol*&) override;
|
||||||
|
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
|
#endif
|
||||||
bool isIoResizeArray(const TType&) const;
|
bool isIoResizeArray(const TType&) const;
|
||||||
void fixIoArraySize(const TSourceLoc&, TType&);
|
void fixIoArraySize(const TSourceLoc&, TType&);
|
||||||
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
|
||||||
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
|
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
|
||||||
void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false, bool isPerPrimitive = false);
|
void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
|
||||||
int getIoArrayImplicitSize(bool isPerPrimitive = false) const;
|
int getIoArrayImplicitSize(const TQualifier&, TString* featureString = nullptr) const;
|
||||||
void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&);
|
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* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
||||||
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
|
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
|
||||||
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
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);
|
void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName);
|
||||||
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
||||||
|
@ -317,6 +353,7 @@ public:
|
||||||
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||||
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
|
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
|
||||||
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) 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 builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
||||||
void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
|
void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
|
||||||
void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&);
|
void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&);
|
||||||
|
@ -326,6 +363,10 @@ public:
|
||||||
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
|
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
|
||||||
void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode);
|
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 assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||||
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
||||||
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
|
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||||
|
@ -337,7 +378,7 @@ public:
|
||||||
void globalCheck(const TSourceLoc&, const char* token);
|
void globalCheck(const TSourceLoc&, const char* token);
|
||||||
bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&);
|
bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&);
|
||||||
bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&);
|
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 arrayQualifierError(const TSourceLoc&, const TQualifier&);
|
||||||
bool arrayError(const TSourceLoc&, const TType&);
|
bool arrayError(const TSourceLoc&, const TType&);
|
||||||
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
|
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
|
||||||
|
@ -349,10 +390,10 @@ public:
|
||||||
void boolCheck(const TSourceLoc&, const TPublicType&);
|
void boolCheck(const TSourceLoc&, const TPublicType&);
|
||||||
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
|
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
|
||||||
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
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 transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
void memberQualifierCheck(glslang::TPublicType&);
|
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&);
|
void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
|
||||||
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
|
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
|
||||||
void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
|
void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
|
||||||
|
@ -370,6 +411,7 @@ public:
|
||||||
void nestedStructCheck(const TSourceLoc&);
|
void nestedStructCheck(const TSourceLoc&);
|
||||||
void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op);
|
void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op);
|
||||||
void opaqueCheck(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 storage16BitAssignmentCheck(const TSourceLoc&, const TType&, const char* op);
|
||||||
void specializationCheck(const TSourceLoc&, const TType&, const char* op);
|
void specializationCheck(const TSourceLoc&, const TType&, const char* op);
|
||||||
void structTypeCheck(const TSourceLoc&, TPublicType&);
|
void structTypeCheck(const TSourceLoc&, TPublicType&);
|
||||||
|
@ -377,7 +419,7 @@ public:
|
||||||
void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
|
void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
|
||||||
void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature);
|
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 constantIndexExpressionCheck(TIntermNode*);
|
||||||
|
|
||||||
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
|
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
|
||||||
|
@ -400,19 +442,25 @@ public:
|
||||||
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
|
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
|
||||||
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
||||||
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
|
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 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 blockStageIoCheck(const TSourceLoc&, const TQualifier&);
|
||||||
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
|
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
|
||||||
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
||||||
void fixXfbOffsets(TQualifier&, TTypeList&);
|
void fixXfbOffsets(TQualifier&, TTypeList&);
|
||||||
void fixBlockUniformOffsets(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, const TString& identifier);
|
||||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||||
void invariantCheck(const TSourceLoc&, const TQualifier&);
|
void invariantCheck(const TSourceLoc&, const TQualifier&);
|
||||||
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
||||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
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;
|
TAttributeType attributeFromName(const TString& name) const;
|
||||||
TAttributes* makeAttributes(const TString& identifier) const;
|
TAttributes* makeAttributes(const TString& identifier) const;
|
||||||
TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
|
TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
|
||||||
|
@ -421,11 +469,27 @@ public:
|
||||||
// Determine selection control from attributes
|
// Determine selection control from attributes
|
||||||
void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*);
|
void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
|
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
|
|
||||||
// Determine loop control from attributes
|
// Determine loop control from attributes
|
||||||
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
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:
|
protected:
|
||||||
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
||||||
|
@ -437,7 +501,18 @@ protected:
|
||||||
bool isRuntimeLength(const TIntermTyped&) const;
|
bool isRuntimeLength(const TIntermTyped&) const;
|
||||||
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
||||||
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
void finish() override;
|
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:
|
public:
|
||||||
//
|
//
|
||||||
|
@ -463,11 +538,15 @@ protected:
|
||||||
TQualifier globalUniformDefaults;
|
TQualifier globalUniformDefaults;
|
||||||
TQualifier globalInputDefaults;
|
TQualifier globalInputDefaults;
|
||||||
TQualifier globalOutputDefaults;
|
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)
|
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;
|
bool anyIndexLimits;
|
||||||
|
TIdSetType inductiveLoopIds;
|
||||||
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
||||||
|
TStructRecord matrixFixRecord;
|
||||||
|
TStructRecord packingFixRecord;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Geometry shader input arrays:
|
// Geometry shader input arrays:
|
||||||
|
@ -502,6 +581,7 @@ protected:
|
||||||
// array-sizing declarations
|
// array-sizing declarations
|
||||||
//
|
//
|
||||||
TVector<TSymbol*> ioArraySymbolResizeList;
|
TVector<TSymbol*> ioArraySymbolResizeList;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013-2016 LunarG, Inc.
|
// Copyright (C) 2013-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2020 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -51,9 +51,9 @@
|
||||||
#include "ScanContext.h"
|
#include "ScanContext.h"
|
||||||
|
|
||||||
#ifdef ENABLE_HLSL
|
#ifdef ENABLE_HLSL
|
||||||
#include "../../hlsl/hlslParseHelper.h"
|
#include "../HLSL/hlslParseHelper.h"
|
||||||
#include "../../hlsl/hlslParseables.h"
|
#include "../HLSL/hlslParseables.h"
|
||||||
#include "../../hlsl/hlslScanContext.h"
|
#include "../HLSL/hlslScanContext.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../Include/ShHandle.h"
|
#include "../Include/ShHandle.h"
|
||||||
|
@ -72,6 +72,9 @@
|
||||||
// token to print ", but none of that seems appropriate for this file.
|
// token to print ", but none of that seems appropriate for this file.
|
||||||
#include "preprocessor/PpTokens.h"
|
#include "preprocessor/PpTokens.h"
|
||||||
|
|
||||||
|
// Build-time generated includes
|
||||||
|
#include "../Include/build_info.h"
|
||||||
|
|
||||||
namespace { // anonymous namespace for file-local functions and symbols
|
namespace { // anonymous namespace for file-local functions and symbols
|
||||||
|
|
||||||
// Total number of successful initializers of glslang: a refcount
|
// Total number of successful initializers of glslang: a refcount
|
||||||
|
@ -156,7 +159,7 @@ int MapVersionToIndex(int version)
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int SpvVersionCount = 3; // index range in MapSpvVersionToIndex
|
const int SpvVersionCount = 4; // index range in MapSpvVersionToIndex
|
||||||
|
|
||||||
int MapSpvVersionToIndex(const SpvVersion& spvVersion)
|
int MapSpvVersionToIndex(const SpvVersion& spvVersion)
|
||||||
{
|
{
|
||||||
|
@ -164,8 +167,12 @@ int MapSpvVersionToIndex(const SpvVersion& spvVersion)
|
||||||
|
|
||||||
if (spvVersion.openGl > 0)
|
if (spvVersion.openGl > 0)
|
||||||
index = 1;
|
index = 1;
|
||||||
else if (spvVersion.vulkan > 0)
|
else if (spvVersion.vulkan > 0) {
|
||||||
|
if (!spvVersion.vulkanRelaxed)
|
||||||
index = 2;
|
index = 2;
|
||||||
|
else
|
||||||
|
index = 3;
|
||||||
|
}
|
||||||
|
|
||||||
assert(index < SpvVersionCount);
|
assert(index < SpvVersionCount);
|
||||||
|
|
||||||
|
@ -288,6 +295,14 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi
|
||||||
EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable,
|
EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable,
|
||||||
TSymbolTable** symbolTables)
|
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)]);
|
(*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
|
||||||
InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
|
InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
|
||||||
infoSink, *symbolTables[language]);
|
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)
|
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<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
|
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
|
||||||
|
|
||||||
if (builtInParseables == nullptr)
|
if (builtInParseables == nullptr)
|
||||||
|
@ -326,6 +349,7 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// check for tessellation
|
// check for tessellation
|
||||||
if ((profile != EEsProfile && version >= 150) ||
|
if ((profile != EEsProfile && version >= 150) ||
|
||||||
(profile == EEsProfile && version >= 310)) {
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
@ -347,20 +371,20 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifndef GLSLANG_ANGLE
|
||||||
// check for ray tracing stages
|
// check for ray tracing stages
|
||||||
if (profile != EEsProfile && version >= 450) {
|
if (profile != EEsProfile && version >= 450) {
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGen, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersectNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersect, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHitNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHit, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHitNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHit, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMiss, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallableNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallable, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +399,8 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
||||||
(profile == EEsProfile && version >= 320))
|
(profile == EEsProfile && version >= 320))
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
#endif
|
#endif // !GLSLANG_ANGLE
|
||||||
|
#endif // !GLSLANG_WEB
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -474,6 +499,18 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
|
||||||
glslang::ReleaseGlobalLock();
|
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.
|
// Return true if the shader was correctly specified for version/profile/stage.
|
||||||
bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion,
|
bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion,
|
||||||
EShSource source, int& version, EProfile& profile, const SpvVersion& spvVersion)
|
EShSource source, int& version, EProfile& profile, const SpvVersion& spvVersion)
|
||||||
|
@ -569,6 +606,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
// Correct for stage type...
|
// Correct for stage type...
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case EShLangGeometry:
|
case EShLangGeometry:
|
||||||
|
@ -600,13 +638,12 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
||||||
version = profile == EEsProfile ? 310 : 420;
|
version = profile == EEsProfile ? 310 : 420;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef NV_EXTENSIONS
|
case EShLangRayGen:
|
||||||
case EShLangRayGenNV:
|
case EShLangIntersect:
|
||||||
case EShLangIntersectNV:
|
case EShLangAnyHit:
|
||||||
case EShLangAnyHitNV:
|
case EShLangClosestHit:
|
||||||
case EShLangClosestHitNV:
|
case EShLangMiss:
|
||||||
case EShLangMissNV:
|
case EShLangCallable:
|
||||||
case EShLangCallableNV:
|
|
||||||
if (profile == EEsProfile || version < 460) {
|
if (profile == EEsProfile || version < 460) {
|
||||||
correct = false;
|
correct = false;
|
||||||
infoSink.info.message(EPrefixError, "#version: ray tracing shaders require non-es profile with version 460 or above");
|
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");
|
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;
|
version = profile == EEsProfile ? 320 : 450;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -635,14 +671,9 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
||||||
if (spvVersion.spv != 0) {
|
if (spvVersion.spv != 0) {
|
||||||
switch (profile) {
|
switch (profile) {
|
||||||
case EEsProfile:
|
case EEsProfile:
|
||||||
if (spvVersion.vulkan > 0 && version < 310) {
|
if (version < 310) {
|
||||||
correct = false;
|
correct = false;
|
||||||
infoSink.info.message(EPrefixError, "#version: ES shaders for Vulkan SPIR-V require version 310 or higher");
|
infoSink.info.message(EPrefixError, "#version: ES shaders for 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");
|
|
||||||
version = 310;
|
version = 310;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -663,6 +694,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return correct;
|
return correct;
|
||||||
}
|
}
|
||||||
|
@ -695,10 +727,14 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages
|
||||||
break;
|
break;
|
||||||
case EShClientVulkan:
|
case EShClientVulkan:
|
||||||
spvVersion.vulkanGlsl = environment->input.dialectVersion;
|
spvVersion.vulkanGlsl = environment->input.dialectVersion;
|
||||||
|
spvVersion.vulkanRelaxed = environment->input.vulkanRulesRelaxed;
|
||||||
break;
|
break;
|
||||||
case EShClientOpenGL:
|
case EShClientOpenGL:
|
||||||
spvVersion.openGl = environment->input.dialectVersion;
|
spvVersion.openGl = environment->input.dialectVersion;
|
||||||
break;
|
break;
|
||||||
|
case EShClientCount:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
switch (environment->input.languageFamily) {
|
switch (environment->input.languageFamily) {
|
||||||
case EShSourceNone:
|
case EShSourceNone:
|
||||||
|
@ -711,6 +747,9 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages
|
||||||
source = EShSourceHlsl;
|
source = EShSourceHlsl;
|
||||||
messages = static_cast<EShMessages>(messages | EShMsgReadHlsl);
|
messages = static_cast<EShMessages>(messages | EShMsgReadHlsl);
|
||||||
break;
|
break;
|
||||||
|
case EShSourceCount:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,13 +860,17 @@ bool ProcessDeferred(
|
||||||
|
|
||||||
// Get all the stages, languages, clients, and other environment
|
// Get all the stages, languages, clients, and other environment
|
||||||
// stuff sorted out.
|
// stuff sorted out.
|
||||||
EShSource source = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl;
|
EShSource sourceGuess = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl;
|
||||||
SpvVersion spvVersion;
|
SpvVersion spvVersion;
|
||||||
EShLanguage stage = compiler->getLanguage();
|
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)
|
if (environment != nullptr && environment->target.hlslFunctionality1)
|
||||||
intermediate.setHlslFunctionality1();
|
intermediate.setHlslFunctionality1();
|
||||||
|
#else
|
||||||
|
const EShSource source = EShSourceGlsl;
|
||||||
|
#endif
|
||||||
// First, without using the preprocessor or parser, find the #version, so we know what
|
// 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
|
// 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.
|
// outlined above, just the user shader, after the system and user preambles.
|
||||||
|
@ -840,6 +883,7 @@ bool ProcessDeferred(
|
||||||
: userInput.scanVersion(version, profile, versionNotFirstToken);
|
: userInput.scanVersion(version, profile, versionNotFirstToken);
|
||||||
bool versionNotFound = version == 0;
|
bool versionNotFound = version == 0;
|
||||||
if (forceDefaultVersionAndProfile && source == EShSourceGlsl) {
|
if (forceDefaultVersionAndProfile && source == EShSourceGlsl) {
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
|
if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
|
||||||
(version != defaultVersion || profile != defaultProfile)) {
|
(version != defaultVersion || profile != defaultProfile)) {
|
||||||
compiler->infoSink.info << "Warning, (version, profile) forced to be ("
|
compiler->infoSink.info << "Warning, (version, profile) forced to be ("
|
||||||
|
@ -847,7 +891,7 @@ bool ProcessDeferred(
|
||||||
<< "), while in source code it is ("
|
<< "), while in source code it is ("
|
||||||
<< version << ", " << ProfileName(profile) << ")\n";
|
<< version << ", " << ProfileName(profile) << ")\n";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (versionNotFound) {
|
if (versionNotFound) {
|
||||||
versionNotFirstToken = false;
|
versionNotFirstToken = false;
|
||||||
versionNotFirst = false;
|
versionNotFirst = false;
|
||||||
|
@ -859,7 +903,16 @@ bool ProcessDeferred(
|
||||||
|
|
||||||
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
|
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
|
||||||
versionNotFirst, defaultVersion, source, version, profile, spvVersion);
|
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));
|
bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
bool warnVersionNotFirst = false;
|
bool warnVersionNotFirst = false;
|
||||||
if (! versionWillBeError && versionNotFirstToken) {
|
if (! versionWillBeError && versionNotFirstToken) {
|
||||||
if (messages & EShMsgRelaxedErrors)
|
if (messages & EShMsgRelaxedErrors)
|
||||||
|
@ -867,6 +920,7 @@ bool ProcessDeferred(
|
||||||
else
|
else
|
||||||
versionWillBeError = true;
|
versionWillBeError = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
intermediate.setSource(source);
|
intermediate.setSource(source);
|
||||||
intermediate.setVersion(version);
|
intermediate.setVersion(version);
|
||||||
|
@ -875,8 +929,10 @@ bool ProcessDeferred(
|
||||||
RecordProcesses(intermediate, messages, sourceEntryPointName);
|
RecordProcesses(intermediate, messages, sourceEntryPointName);
|
||||||
if (spvVersion.vulkan > 0)
|
if (spvVersion.vulkan > 0)
|
||||||
intermediate.setOriginUpperLeft();
|
intermediate.setOriginUpperLeft();
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl)
|
if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl)
|
||||||
intermediate.setHlslOffsets();
|
intermediate.setHlslOffsets();
|
||||||
|
#endif
|
||||||
if (messages & EShMsgDebugInfo) {
|
if (messages & EShMsgDebugInfo) {
|
||||||
intermediate.setSourceFile(names[numPre]);
|
intermediate.setSourceFile(names[numPre]);
|
||||||
for (int s = 0; s < numStrings; ++s) {
|
for (int s = 0; s < numStrings; ++s) {
|
||||||
|
@ -898,6 +954,9 @@ bool ProcessDeferred(
|
||||||
if (cachedTable)
|
if (cachedTable)
|
||||||
symbolTable->adoptLevels(*cachedTable);
|
symbolTable->adoptLevels(*cachedTable);
|
||||||
|
|
||||||
|
if (intermediate.getUniqueId() != 0)
|
||||||
|
symbolTable->overwriteUniqueId(intermediate.getUniqueId());
|
||||||
|
|
||||||
// Add built-in symbols that are potentially context dependent;
|
// Add built-in symbols that are potentially context dependent;
|
||||||
// they get popped again further down.
|
// they get popped again further down.
|
||||||
if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion,
|
if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion,
|
||||||
|
@ -905,6 +964,9 @@ bool ProcessDeferred(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (messages & EShMsgBuiltinSymbolTable)
|
||||||
|
DumpBuiltinSymbolTable(compiler->infoSink, *symbolTable);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now we can process the full shader under proper symbols and rules.
|
// Now we can process the full shader under proper symbols and rules.
|
||||||
//
|
//
|
||||||
|
@ -923,11 +985,13 @@ bool ProcessDeferred(
|
||||||
parseContext->setLimits(*resources);
|
parseContext->setLimits(*resources);
|
||||||
if (! goodVersion)
|
if (! goodVersion)
|
||||||
parseContext->addError();
|
parseContext->addError();
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
if (warnVersionNotFirst) {
|
if (warnVersionNotFirst) {
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
loc.init();
|
loc.init();
|
||||||
parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", "");
|
parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", "");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
parseContext->initializeExtensionBehavior();
|
parseContext->initializeExtensionBehavior();
|
||||||
|
|
||||||
|
@ -955,9 +1019,12 @@ bool ProcessDeferred(
|
||||||
bool success = processingContext(*parseContext, ppContext, fullInput,
|
bool success = processingContext(*parseContext, ppContext, fullInput,
|
||||||
versionWillBeError, *symbolTable,
|
versionWillBeError, *symbolTable,
|
||||||
intermediate, optLevel, messages);
|
intermediate, optLevel, messages);
|
||||||
|
intermediate.setUniqueId(symbolTable->getMaxSymbolId());
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
// Responsible for keeping track of the most recent source string and line in
|
// Responsible for keeping track of the most recent source string and line in
|
||||||
// the preprocessor and outputting newlines appropriately if the source string
|
// the preprocessor and outputting newlines appropriately if the source string
|
||||||
// or line changes.
|
// or line changes.
|
||||||
|
@ -1154,6 +1221,8 @@ struct DoPreprocessing {
|
||||||
std::string* outputString;
|
std::string* outputString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// DoFullParse is a valid ProcessingConext template argument for fully
|
// DoFullParse is a valid ProcessingConext template argument for fully
|
||||||
// parsing the shader. It populates the "intermediate" with the AST.
|
// parsing the shader. It populates the "intermediate" with the AST.
|
||||||
struct DoFullParse{
|
struct DoFullParse{
|
||||||
|
@ -1177,13 +1246,16 @@ struct DoFullParse{
|
||||||
parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n";
|
parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_ANGLE
|
||||||
if (messages & EShMsgAST)
|
if (messages & EShMsgAST)
|
||||||
intermediate.output(parseContext.infoSink, true);
|
intermediate.output(parseContext.infoSink, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
// Take a single compilation unit, and run the preprocessor on it.
|
// Take a single compilation unit, and run the preprocessor on it.
|
||||||
// Return: True if there were no issues found in preprocessing,
|
// Return: True if there were no issues found in preprocessing,
|
||||||
// False if during preprocessing any unknown version, pragmas or
|
// False if during preprocessing any unknown version, pragmas or
|
||||||
|
@ -1207,15 +1279,17 @@ bool PreprocessDeferred(
|
||||||
EShMessages messages, // warnings/errors/AST; things to print out
|
EShMessages messages, // warnings/errors/AST; things to print out
|
||||||
TShader::Includer& includer,
|
TShader::Includer& includer,
|
||||||
TIntermediate& intermediate, // returned tree, etc.
|
TIntermediate& intermediate, // returned tree, etc.
|
||||||
std::string* outputString)
|
std::string* outputString,
|
||||||
|
TEnvironment* environment = nullptr)
|
||||||
{
|
{
|
||||||
DoPreprocessing parser(outputString);
|
DoPreprocessing parser(outputString);
|
||||||
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
|
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
|
||||||
preamble, optLevel, resources, defaultVersion,
|
preamble, optLevel, resources, defaultVersion,
|
||||||
defaultProfile, forceDefaultVersionAndProfile,
|
defaultProfile, forceDefaultVersionAndProfile,
|
||||||
forwardCompatible, messages, intermediate, parser,
|
forwardCompatible, messages, intermediate, parser,
|
||||||
false, includer);
|
false, includer, "", environment);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// do a partial compile on the given strings for a single compilation unit
|
// 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 {
|
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 QUOTE(s) #s
|
||||||
#define STR(n) QUOTE(n)
|
#define STR(n) QUOTE(n)
|
||||||
|
|
||||||
const char* GetEsslVersionString()
|
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()
|
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()
|
int GetKhronosToolId()
|
||||||
|
@ -1683,6 +1767,7 @@ TShader::TShader(EShLanguage s)
|
||||||
// clear environment (avoid constructors in them for use in a C interface)
|
// clear environment (avoid constructors in them for use in a C interface)
|
||||||
environment.input.languageFamily = EShSourceNone;
|
environment.input.languageFamily = EShSourceNone;
|
||||||
environment.input.dialect = EShClientNone;
|
environment.input.dialect = EShClientNone;
|
||||||
|
environment.input.vulkanRulesRelaxed = false;
|
||||||
environment.client.client = EShClientNone;
|
environment.client.client = EShClientNone;
|
||||||
environment.target.language = EShTargetNone;
|
environment.target.language = EShTargetNone;
|
||||||
environment.target.hlslFunctionality1 = false;
|
environment.target.hlslFunctionality1 = false;
|
||||||
|
@ -1729,11 +1814,23 @@ void TShader::setSourceEntryPoint(const char* name)
|
||||||
sourceEntryPointName = name;
|
sourceEntryPointName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log initial settings and transforms.
|
||||||
|
// See comment for class TProcesses.
|
||||||
void TShader::addProcesses(const std::vector<std::string>& p)
|
void TShader::addProcesses(const std::vector<std::string>& p)
|
||||||
{
|
{
|
||||||
intermediate->addProcesses(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
|
// Set binding base for given resource type
|
||||||
void TShader::setShiftBinding(TResourceType res, unsigned int base) {
|
void TShader::setShiftBinding(TResourceType res, unsigned int base) {
|
||||||
intermediate->setShiftBinding(res, base);
|
intermediate->setShiftBinding(res, base);
|
||||||
|
@ -1761,7 +1858,7 @@ void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSs
|
||||||
// Enables binding automapping using TIoMapper
|
// Enables binding automapping using TIoMapper
|
||||||
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
||||||
// Enables position.Y output negation in vertex shader
|
// 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
|
// Fragile: currently within one stage: simple auto-assignment of location
|
||||||
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
|
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
|
||||||
void TShader::addUniformLocationOverride(const char* name, int loc)
|
void TShader::addUniformLocationOverride(const char* name, int loc)
|
||||||
|
@ -1772,12 +1869,25 @@ void TShader::setUniformLocationBase(int base)
|
||||||
{
|
{
|
||||||
intermediate->setUniformLocationBase(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::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
||||||
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
|
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
|
||||||
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
|
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.
|
// Turn the shader strings into a parse tree in the TIntermediate.
|
||||||
|
@ -1801,6 +1911,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
||||||
&environment);
|
&environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
// Fill in a string with the result of preprocessing ShaderStrings
|
// Fill in a string with the result of preprocessing ShaderStrings
|
||||||
// Returns true if all extensions, pragmas and version strings were valid.
|
// 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,
|
return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
|
||||||
EShOptNone, builtInResources, defaultVersion,
|
EShOptNone, builtInResources, defaultVersion,
|
||||||
defaultProfile, forceDefaultVersionAndProfile,
|
defaultProfile, forceDefaultVersionAndProfile,
|
||||||
forwardCompatible, message, includer, *intermediate, output_string);
|
forwardCompatible, message, includer, *intermediate, output_string,
|
||||||
|
&environment);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const char* TShader::getInfoLog()
|
const char* TShader::getInfoLog()
|
||||||
{
|
{
|
||||||
|
@ -1836,7 +1949,11 @@ const char* TShader::getInfoDebugLog()
|
||||||
return infoSink->debug.c_str();
|
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;
|
pool = new TPoolAllocator;
|
||||||
infoSink = new TInfoSink;
|
infoSink = new TInfoSink;
|
||||||
|
@ -1848,9 +1965,10 @@ TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false)
|
||||||
|
|
||||||
TProgram::~TProgram()
|
TProgram::~TProgram()
|
||||||
{
|
{
|
||||||
delete ioMapper;
|
|
||||||
delete infoSink;
|
delete infoSink;
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
delete reflection;
|
delete reflection;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int s = 0; s < EShLangCount; ++s)
|
for (int s = 0; s < EShLangCount; ++s)
|
||||||
if (newedIntermediate[s])
|
if (newedIntermediate[s])
|
||||||
|
@ -1880,7 +1998,10 @@ bool TProgram::link(EShMessages messages)
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Link: cross-stage error checking
|
if (!error) {
|
||||||
|
if (! crossStageCheck(messages))
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
return ! error;
|
return ! error;
|
||||||
}
|
}
|
||||||
|
@ -1895,6 +2016,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
|
||||||
if (stages[stage].size() == 0)
|
if (stages[stage].size() == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
int numEsShaders = 0, numNonEsShaders = 0;
|
int numEsShaders = 0, numNonEsShaders = 0;
|
||||||
for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) {
|
for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) {
|
||||||
if ((*it)->intermediate->getProfile() == EEsProfile) {
|
if ((*it)->intermediate->getProfile() == EEsProfile) {
|
||||||
|
@ -1923,7 +2045,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
|
||||||
intermediate[stage] = new TIntermediate(stage,
|
intermediate[stage] = new TIntermediate(stage,
|
||||||
firstIntermediate->getVersion(),
|
firstIntermediate->getVersion(),
|
||||||
firstIntermediate->getProfile());
|
firstIntermediate->getProfile());
|
||||||
|
intermediate[stage]->setLimits(firstIntermediate->getLimits());
|
||||||
|
|
||||||
// The new TIntermediate must use the same origin as the original TIntermediates.
|
// The new TIntermediate must use the same origin as the original TIntermediates.
|
||||||
// Otherwise linking will fail due to different coordinate systems.
|
// 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)
|
for (it = stages[stage].begin(); it != stages[stage].end(); ++it)
|
||||||
intermediate[stage]->merge(*infoSink, *(*it)->intermediate);
|
intermediate[stage]->merge(*infoSink, *(*it)->intermediate);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
intermediate[stage] = stages[stage].front()->intermediate;
|
||||||
|
#endif
|
||||||
intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);
|
intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_ANGLE
|
||||||
if (messages & EShMsgAST)
|
if (messages & EShMsgAST)
|
||||||
intermediate[stage]->output(*infoSink, true);
|
intermediate[stage]->output(*infoSink, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
return intermediate[stage]->getNumErrors() == 0;
|
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<TIntermediate*> 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()
|
const char* TProgram::getInfoLog()
|
||||||
{
|
{
|
||||||
return infoSink->info.c_str();
|
return infoSink->info.c_str();
|
||||||
|
@ -1962,16 +2151,33 @@ const char* TProgram::getInfoDebugLog()
|
||||||
return infoSink->debug.c_str();
|
return infoSink->debug.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reflection implementation.
|
// Reflection implementation.
|
||||||
//
|
//
|
||||||
|
|
||||||
bool TProgram::buildReflection()
|
bool TProgram::buildReflection(int opts)
|
||||||
{
|
{
|
||||||
if (! linked || reflection)
|
if (! linked || reflection != nullptr)
|
||||||
return false;
|
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) {
|
for (int s = 0; s < EShLangCount; ++s) {
|
||||||
if (intermediate[s]) {
|
if (intermediate[s]) {
|
||||||
|
@ -1983,48 +2189,50 @@ bool TProgram::buildReflection()
|
||||||
return true;
|
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.
|
// I/O mapping implementation.
|
||||||
//
|
//
|
||||||
bool TProgram::mapIO(TIoMapResolver* resolver)
|
bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper)
|
||||||
{
|
{
|
||||||
if (! linked || ioMapper)
|
if (! linked)
|
||||||
return false;
|
return false;
|
||||||
|
TIoMapper* ioMapper = nullptr;
|
||||||
ioMapper = new TIoMapper;
|
TIoMapper defaultIOMapper;
|
||||||
|
if (pIoMapper == nullptr)
|
||||||
|
ioMapper = &defaultIOMapper;
|
||||||
|
else
|
||||||
|
ioMapper = pIoMapper;
|
||||||
for (int s = 0; s < EShLangCount; ++s) {
|
for (int s = 0; s < EShLangCount; ++s) {
|
||||||
if (intermediate[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 false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return ioMapper->doMap(pResolver, *infoSink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
355
thirdparty/ShaderCompiler/glslang/MachineIndependent/SpirvIntrinsics.cpp
vendored
Normal file
355
thirdparty/ShaderCompiler/glslang/MachineIndependent/SpirvIntrinsics.cpp
vendored
Normal file
|
@ -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<const TIntermConstantUnion*> 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<const TIntermConstantUnion*> 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<const TIntermConstantUnion*> 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<const TIntermConstantUnion*> 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<const TIntermConstantUnion*> 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<float>(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
|
|
@ -3,6 +3,7 @@
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -61,63 +62,70 @@ void TType::buildMangledName(TString& mangledName) const
|
||||||
|
|
||||||
switch (basicType) {
|
switch (basicType) {
|
||||||
case EbtFloat: mangledName += 'f'; break;
|
case EbtFloat: mangledName += 'f'; break;
|
||||||
case EbtDouble: mangledName += 'd'; break;
|
|
||||||
case EbtFloat16: mangledName += "f16"; break;
|
|
||||||
case EbtInt: mangledName += 'i'; break;
|
case EbtInt: mangledName += 'i'; break;
|
||||||
case EbtUint: mangledName += 'u'; 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 EbtInt8: mangledName += "i8"; break;
|
||||||
case EbtUint8: mangledName += "u8"; break;
|
case EbtUint8: mangledName += "u8"; break;
|
||||||
case EbtInt16: mangledName += "i16"; break;
|
case EbtInt16: mangledName += "i16"; break;
|
||||||
case EbtUint16: mangledName += "u16"; break;
|
case EbtUint16: mangledName += "u16"; break;
|
||||||
case EbtInt64: mangledName += "i64"; break;
|
case EbtInt64: mangledName += "i64"; break;
|
||||||
case EbtUint64: mangledName += "u64"; break;
|
case EbtUint64: mangledName += "u64"; break;
|
||||||
case EbtBool: mangledName += 'b'; break;
|
|
||||||
case EbtAtomicUint: mangledName += "au"; break;
|
case EbtAtomicUint: mangledName += "au"; break;
|
||||||
#ifdef NV_EXTENSIONS
|
case EbtAccStruct: mangledName += "as"; break;
|
||||||
case EbtAccStructNV: mangledName += "asnv"; break;
|
case EbtRayQuery: mangledName += "rq"; break;
|
||||||
|
case EbtSpirvType: mangledName += "spv-t"; break;
|
||||||
#endif
|
#endif
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
switch (sampler.type) {
|
switch (sampler.type) {
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifndef GLSLANG_WEB
|
||||||
case EbtFloat16: mangledName += "f16"; break;
|
case EbtFloat16: mangledName += "f16"; break;
|
||||||
#endif
|
#endif
|
||||||
case EbtInt: mangledName += "i"; break;
|
case EbtInt: mangledName += "i"; break;
|
||||||
case EbtUint: mangledName += "u"; break;
|
case EbtUint: mangledName += "u"; break;
|
||||||
|
case EbtInt64: mangledName += "i64"; break;
|
||||||
|
case EbtUint64: mangledName += "u64"; break;
|
||||||
default: break; // some compilers want this
|
default: break; // some compilers want this
|
||||||
}
|
}
|
||||||
if (sampler.image)
|
if (sampler.isImageClass())
|
||||||
mangledName += "I"; // a normal image
|
mangledName += "I"; // a normal image or subpass
|
||||||
else if (sampler.sampler)
|
else if (sampler.isPureSampler())
|
||||||
mangledName += "p"; // a "pure" sampler
|
mangledName += "p"; // a "pure" sampler
|
||||||
else if (!sampler.combined)
|
else if (!sampler.isCombined())
|
||||||
mangledName += "t"; // a "pure" texture
|
mangledName += "t"; // a "pure" texture
|
||||||
else
|
else
|
||||||
mangledName += "s"; // traditional combined sampler
|
mangledName += "s"; // traditional combined sampler
|
||||||
if (sampler.arrayed)
|
if (sampler.isArrayed())
|
||||||
mangledName += "A";
|
mangledName += "A";
|
||||||
if (sampler.shadow)
|
if (sampler.isShadow())
|
||||||
mangledName += "S";
|
mangledName += "S";
|
||||||
if (sampler.external)
|
if (sampler.isExternal())
|
||||||
mangledName += "E";
|
mangledName += "E";
|
||||||
if (sampler.yuv)
|
if (sampler.isYuv())
|
||||||
mangledName += "Y";
|
mangledName += "Y";
|
||||||
switch (sampler.dim) {
|
switch (sampler.dim) {
|
||||||
case Esd1D: mangledName += "1"; break;
|
|
||||||
case Esd2D: mangledName += "2"; break;
|
case Esd2D: mangledName += "2"; break;
|
||||||
case Esd3D: mangledName += "3"; break;
|
case Esd3D: mangledName += "3"; break;
|
||||||
case EsdCube: mangledName += "C"; break;
|
case EsdCube: mangledName += "C"; break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
case Esd1D: mangledName += "1"; break;
|
||||||
case EsdRect: mangledName += "R2"; break;
|
case EsdRect: mangledName += "R2"; break;
|
||||||
case EsdBuffer: mangledName += "B"; break;
|
case EsdBuffer: mangledName += "B"; break;
|
||||||
case EsdSubpass: mangledName += "P"; break;
|
case EsdSubpass: mangledName += "P"; break;
|
||||||
|
#endif
|
||||||
default: break; // some compilers want this
|
default: break; // some compilers want this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
if (sampler.hasReturnStruct()) {
|
if (sampler.hasReturnStruct()) {
|
||||||
// Name mangle for sampler return struct uses struct table index.
|
// Name mangle for sampler return struct uses struct table index.
|
||||||
mangledName += "-tx-struct";
|
mangledName += "-tx-struct";
|
||||||
|
|
||||||
char text[16]; // plenty enough space for the small integers.
|
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;
|
mangledName += text;
|
||||||
} else {
|
} else {
|
||||||
switch (sampler.getVectorSize()) {
|
switch (sampler.getVectorSize()) {
|
||||||
|
@ -127,8 +135,9 @@ void TType::buildMangledName(TString& mangledName) const
|
||||||
case 4: break; // default to prior name mangle behavior
|
case 4: break; // default to prior name mangle behavior
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sampler.ms)
|
if (sampler.isMultiSample())
|
||||||
mangledName += "M";
|
mangledName += "M";
|
||||||
break;
|
break;
|
||||||
case EbtStruct:
|
case EbtStruct:
|
||||||
|
@ -140,6 +149,8 @@ void TType::buildMangledName(TString& mangledName) const
|
||||||
if (typeName)
|
if (typeName)
|
||||||
mangledName += *typeName;
|
mangledName += *typeName;
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
for (unsigned int i = 0; i < structure->size(); ++i) {
|
||||||
|
if ((*structure)[i].type->getBasicType() == EbtVoid)
|
||||||
|
continue;
|
||||||
mangledName += '-';
|
mangledName += '-';
|
||||||
(*structure)[i].type->buildMangledName(mangledName);
|
(*structure)[i].type->buildMangledName(mangledName);
|
||||||
}
|
}
|
||||||
|
@ -160,7 +171,7 @@ void TType::buildMangledName(TString& mangledName) const
|
||||||
for (int i = 0; i < arraySizes->getNumDims(); ++i) {
|
for (int i = 0; i < arraySizes->getNumDims(); ++i) {
|
||||||
if (arraySizes->getDimNode(i)) {
|
if (arraySizes->getDimNode(i)) {
|
||||||
if (arraySizes->getDimNode(i)->getAsSymbolNode())
|
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
|
else
|
||||||
snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i));
|
snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i));
|
||||||
} else
|
} else
|
||||||
|
@ -172,44 +183,88 @@ void TType::buildMangledName(TString& mangledName) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Dump functions.
|
// Dump functions.
|
||||||
//
|
//
|
||||||
|
|
||||||
void TVariable::dump(TInfoSink& infoSink) const
|
void TSymbol::dumpExtensions(TInfoSink& infoSink) const
|
||||||
{
|
{
|
||||||
infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicTypeString();
|
int numExtensions = getNumExtensions();
|
||||||
if (type.isArray()) {
|
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 << "[0]";
|
||||||
}
|
}
|
||||||
|
|
||||||
infoSink.debug << "\n";
|
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 ? "," : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TAnonMember::dump(TInfoSink& TInfoSink) const
|
infoSink.debug << ")";
|
||||||
{
|
dumpExtensions(infoSink);
|
||||||
TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str() << "\n";
|
} else {
|
||||||
|
infoSink.debug << getName().c_str() << ": " << returnType.getBasicTypeString() << " "
|
||||||
|
<< getMangledName().c_str() << "n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void TSymbolTableLevel::dump(TInfoSink &infoSink) const
|
infoSink.debug << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void TAnonMember::dump(TInfoSink& TInfoSink, bool) const
|
||||||
|
{
|
||||||
|
TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str()
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSymbolTableLevel::dump(TInfoSink& infoSink, bool complete) const
|
||||||
{
|
{
|
||||||
tLevel::const_iterator it;
|
tLevel::const_iterator it;
|
||||||
for (it = level.begin(); it != level.end(); ++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) {
|
for (int level = currentLevel(); level >= 0; --level) {
|
||||||
infoSink.debug << "LEVEL " << level << "\n";
|
infoSink.debug << "LEVEL " << level << "\n";
|
||||||
table[level]->dump(infoSink);
|
table[level]->dump(infoSink, complete);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Functions have buried pointers to delete.
|
// Functions have buried pointers to delete.
|
||||||
//
|
//
|
||||||
|
@ -336,6 +391,9 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
|
||||||
implicitThis = copyOf.implicitThis;
|
implicitThis = copyOf.implicitThis;
|
||||||
illegalImplicitThis = copyOf.illegalImplicitThis;
|
illegalImplicitThis = copyOf.illegalImplicitThis;
|
||||||
defaultParamCount = copyOf.defaultParamCount;
|
defaultParamCount = copyOf.defaultParamCount;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
spirvInst = copyOf.spirvInst;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TFunction* TFunction::clone() const
|
TFunction* TFunction::clone() const
|
||||||
|
|
|
@ -104,8 +104,8 @@ public:
|
||||||
virtual const TAnonMember* getAsAnonMember() const { return 0; }
|
virtual const TAnonMember* getAsAnonMember() const { return 0; }
|
||||||
virtual const TType& getType() const = 0;
|
virtual const TType& getType() const = 0;
|
||||||
virtual TType& getWritableType() = 0;
|
virtual TType& getWritableType() = 0;
|
||||||
virtual void setUniqueId(int id) { uniqueId = id; }
|
virtual void setUniqueId(long long id) { uniqueId = id; }
|
||||||
virtual int getUniqueId() const { return uniqueId; }
|
virtual long long getUniqueId() const { return uniqueId; }
|
||||||
virtual void setExtensions(int numExts, const char* const exts[])
|
virtual void setExtensions(int numExts, const char* const exts[])
|
||||||
{
|
{
|
||||||
assert(extensions == 0);
|
assert(extensions == 0);
|
||||||
|
@ -116,7 +116,11 @@ public:
|
||||||
}
|
}
|
||||||
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
|
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
|
||||||
virtual const char** getExtensions() const { return extensions->data(); }
|
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 bool isReadOnly() const { return ! writable; }
|
||||||
virtual void makeReadOnly() { writable = false; }
|
virtual void makeReadOnly() { writable = false; }
|
||||||
|
@ -126,7 +130,7 @@ protected:
|
||||||
TSymbol& operator=(const TSymbol&);
|
TSymbol& operator=(const TSymbol&);
|
||||||
|
|
||||||
const TString *name;
|
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
|
// For tracking what extensions must be present
|
||||||
// (don't use if correct version/profile is 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 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:
|
protected:
|
||||||
explicit TVariable(const TVariable&);
|
explicit TVariable(const TVariable&);
|
||||||
|
@ -313,7 +319,18 @@ public:
|
||||||
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
||||||
virtual const TParameter& operator[](int i) const { 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:
|
protected:
|
||||||
explicit TFunction(const TFunction&);
|
explicit TFunction(const TFunction&);
|
||||||
|
@ -334,6 +351,10 @@ protected:
|
||||||
// This is important for a static member function that has member variables in scope,
|
// 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.
|
// but is not allowed to use them, or see hidden symbols instead.
|
||||||
int defaultParamCount;
|
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 const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
|
||||||
|
|
||||||
virtual int getAnonId() const { return anonId; }
|
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:
|
protected:
|
||||||
explicit TAnonMember(const TAnonMember&);
|
explicit TAnonMember(const TAnonMember&);
|
||||||
|
@ -541,7 +564,9 @@ public:
|
||||||
|
|
||||||
void relateToOperator(const char* name, TOperator op);
|
void relateToOperator(const char* name, TOperator op);
|
||||||
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
|
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;
|
TSymbolTableLevel* clone() const;
|
||||||
void readOnly();
|
void readOnly();
|
||||||
|
|
||||||
|
@ -600,21 +625,28 @@ public:
|
||||||
// 3: user-shader globals
|
// 3: user-shader globals
|
||||||
//
|
//
|
||||||
protected:
|
protected:
|
||||||
|
static const uint32_t LevelFlagBitOffset = 56;
|
||||||
static const int globalLevel = 3;
|
static const int globalLevel = 3;
|
||||||
bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
|
static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
|
||||||
bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
|
static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
|
||||||
bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals
|
static bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals
|
||||||
public:
|
public:
|
||||||
bool isEmpty() { return table.size() == 0; }
|
bool isEmpty() { return table.size() == 0; }
|
||||||
bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
|
bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
|
||||||
bool atGlobalLevel() { return isGlobalLevel(currentLevel()); }
|
bool atGlobalLevel() { return isGlobalLevel(currentLevel()); }
|
||||||
|
static bool isBuiltInSymbol(long long uniqueId) {
|
||||||
|
int level = static_cast<int>(uniqueId >> LevelFlagBitOffset);
|
||||||
|
return isBuiltInLevel(level);
|
||||||
|
}
|
||||||
|
static constexpr uint64_t uniqueIdMask = (1LL << LevelFlagBitOffset) - 1;
|
||||||
|
static const uint32_t MaxLevelInUniqueID = 127;
|
||||||
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
|
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
|
||||||
void setSeparateNameSpaces() { separateNameSpaces = true; }
|
void setSeparateNameSpaces() { separateNameSpaces = true; }
|
||||||
|
|
||||||
void push()
|
void push()
|
||||||
{
|
{
|
||||||
table.push_back(new TSymbolTableLevel);
|
table.push_back(new TSymbolTableLevel);
|
||||||
|
updateUniqueIdLevelFlag();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a new symbol-table level to represent the scope introduced by a structure
|
// Make a new symbol-table level to represent the scope introduced by a structure
|
||||||
|
@ -627,6 +659,7 @@ public:
|
||||||
{
|
{
|
||||||
assert(thisSymbol.getName().size() == 0);
|
assert(thisSymbol.getName().size() == 0);
|
||||||
table.push_back(new TSymbolTableLevel);
|
table.push_back(new TSymbolTableLevel);
|
||||||
|
updateUniqueIdLevelFlag();
|
||||||
table.back()->setThisLevel();
|
table.back()->setThisLevel();
|
||||||
insert(thisSymbol);
|
insert(thisSymbol);
|
||||||
}
|
}
|
||||||
|
@ -636,6 +669,7 @@ public:
|
||||||
table[currentLevel()]->getPreviousDefaultPrecisions(p);
|
table[currentLevel()]->getPreviousDefaultPrecisions(p);
|
||||||
delete table.back();
|
delete table.back();
|
||||||
table.pop_back();
|
table.pop_back();
|
||||||
|
updateUniqueIdLevelFlag();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -673,6 +707,16 @@ public:
|
||||||
return table[currentLevel()]->amend(symbol, firstNewMember);
|
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
|
// To allocate an internal temporary, which will need to be uniquely
|
||||||
// identified by the consumer of the AST, but never need to
|
// identified by the consumer of the AST, but never need to
|
||||||
|
@ -841,8 +885,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMaxSymbolId() { return uniqueId; }
|
long long getMaxSymbolId() { return uniqueId; }
|
||||||
void dump(TInfoSink &infoSink) const;
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
void dump(TInfoSink& infoSink, bool complete = false) const;
|
||||||
|
#endif
|
||||||
void copyTable(const TSymbolTable& copyOf);
|
void copyTable(const TSymbolTable& copyOf);
|
||||||
|
|
||||||
void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }
|
void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }
|
||||||
|
@ -853,14 +899,27 @@ public:
|
||||||
table[level]->readOnly();
|
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:
|
protected:
|
||||||
TSymbolTable(TSymbolTable&);
|
TSymbolTable(TSymbolTable&);
|
||||||
TSymbolTable& operator=(TSymbolTableLevel&);
|
TSymbolTable& operator=(TSymbolTableLevel&);
|
||||||
|
|
||||||
int currentLevel() const { return static_cast<int>(table.size()) - 1; }
|
int currentLevel() const { return static_cast<int>(table.size()) - 1; }
|
||||||
|
|
||||||
std::vector<TSymbolTableLevel*> table;
|
std::vector<TSymbolTableLevel*> table;
|
||||||
int uniqueId; // for unique identification in code generation
|
long long uniqueId; // for unique identification in code generation
|
||||||
bool noBuiltInRedeclarations;
|
bool noBuiltInRedeclarations;
|
||||||
bool separateNameSpaces;
|
bool separateNameSpaces;
|
||||||
unsigned int adoptedLevels;
|
unsigned int adoptedLevels;
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// 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.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -63,6 +64,7 @@
|
||||||
// checkDeprecated()
|
// checkDeprecated()
|
||||||
// requireNotRemoved()
|
// requireNotRemoved()
|
||||||
// requireExtensions()
|
// requireExtensions()
|
||||||
|
// extensionRequires()
|
||||||
//
|
//
|
||||||
// Typically, only the first two calls are needed. They go into a code path that
|
// 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
|
// 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";
|
// const char* const XXX_extension_X = "XXX_extension_X";
|
||||||
//
|
//
|
||||||
// 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(),
|
// 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;
|
// 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():
|
// 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
|
// 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.)
|
// 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 "parseVersions.h"
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize all extensions, almost always to 'disable', as once their features
|
// Initialize all extensions, almost always to 'disable', as once their features
|
||||||
// are incorporated into a core version, their features are supported through allowing that
|
// are incorporated into a core version, their features are supported through allowing that
|
||||||
|
@ -152,6 +160,22 @@ namespace glslang {
|
||||||
//
|
//
|
||||||
void TParseVersions::initializeExtensionBehavior()
|
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_texture_3D] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable;
|
extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_frag_depth] = 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_tessellation_shader] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_enhanced_layouts] = EBhDisable;
|
extensionBehavior[E_GL_ARB_enhanced_layouts] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_texture_cube_map_array] = 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_shader_texture_lod] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_explicit_attrib_location] = 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_image_load_store] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_atomic_counters] = 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_draw_parameters] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_group_vote] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_group_vote] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable;
|
extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable;
|
extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_gpu_shader_int64] = 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_shader_ballot] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable;
|
extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_sparse_texture_clamp] = 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_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_post_depth_coverage] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_viewport_layer_array] = 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_basic] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = 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_scalar_block_layout] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable;
|
extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_buffer_reference] = 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_16bit_storage] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable;
|
||||||
|
|
||||||
// #line and #include
|
// #line and #include
|
||||||
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
||||||
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
|
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable;
|
extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable;
|
extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter] = 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_image_load_store_lod] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable;
|
extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_gpu_shader_half_float_fetch] = 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_GL_NV_sample_mask_override_coverage] = EBhDisable;
|
||||||
extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable;
|
extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_viewport_array2] = 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_shader_subgroup_partitioned] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable;
|
extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_ray_tracing] = 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_fragment_shader_barycentric] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
|
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
|
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_mesh_shader] = 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
|
// AEP
|
||||||
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
|
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_tessellation_point_size] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_texture_buffer] = EBhDisable;
|
extensionBehavior[E_GL_EXT_texture_buffer] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_texture_cube_map_array] = EBhDisable;
|
extensionBehavior[E_GL_EXT_texture_cube_map_array] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_null_initializer] = EBhDisable;
|
||||||
|
|
||||||
// OES matching AEP
|
// OES matching AEP
|
||||||
extensionBehavior[E_GL_OES_geometry_shader] = EBhDisable;
|
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_tessellation_point_size] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_integer_mix] = EBhDisable;
|
||||||
|
|
||||||
// EXT extensions
|
// EXT extensions
|
||||||
extensionBehavior[E_GL_EXT_device_group] = EBhDisable;
|
extensionBehavior[E_GL_EXT_device_group] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_multiview] = 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
|
// OVR extensions
|
||||||
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
|
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_float16] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float32] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float32] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float64] = 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,
|
// 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).
|
// or needed by the preprocessor (which does not use a shared symbol table).
|
||||||
void TParseVersions::getPreamble(std::string& preamble)
|
void TParseVersions::getPreamble(std::string& preamble)
|
||||||
{
|
{
|
||||||
if (profile == EEsProfile) {
|
if (isEsProfile()) {
|
||||||
preamble =
|
preamble =
|
||||||
"#define GL_ES 1\n"
|
"#define GL_ES 1\n"
|
||||||
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
;
|
||||||
|
#else
|
||||||
"#define GL_OES_texture_3D 1\n"
|
"#define GL_OES_texture_3D 1\n"
|
||||||
"#define GL_OES_standard_derivatives 1\n"
|
"#define GL_OES_standard_derivatives 1\n"
|
||||||
"#define GL_EXT_frag_depth 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_YUV_target 1\n"
|
||||||
"#define GL_EXT_shader_texture_lod 1\n"
|
"#define GL_EXT_shader_texture_lod 1\n"
|
||||||
"#define GL_EXT_shadow_samplers 1\n"
|
"#define GL_EXT_shadow_samplers 1\n"
|
||||||
|
"#define GL_EXT_fragment_shading_rate 1\n"
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
"#define GL_ANDROID_extension_pack_es31a 1\n"
|
"#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_sample_variables 1\n"
|
||||||
"#define GL_OES_shader_image_atomic 1\n"
|
"#define GL_OES_shader_image_atomic 1\n"
|
||||||
"#define GL_OES_shader_multisample_interpolation 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_tessellation_point_size 1\n"
|
||||||
"#define GL_EXT_texture_buffer 1\n"
|
"#define GL_EXT_texture_buffer 1\n"
|
||||||
"#define GL_EXT_texture_cube_map_array 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
|
// OES matching AEP
|
||||||
"#define GL_OES_geometry_shader 1\n"
|
"#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"
|
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
if (version >= 300) {
|
||||||
if (profile == EEsProfile && version >= 300) {
|
|
||||||
preamble += "#define GL_NV_shader_noperspective_interpolation 1\n";
|
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 =
|
preamble =
|
||||||
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
||||||
"#define GL_ARB_texture_rectangle 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_tessellation_shader 1\n"
|
||||||
"#define GL_ARB_enhanced_layouts 1\n"
|
"#define GL_ARB_enhanced_layouts 1\n"
|
||||||
"#define GL_ARB_texture_cube_map_array 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_shader_texture_lod 1\n"
|
||||||
"#define GL_ARB_explicit_attrib_location 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_image_load_store 1\n"
|
||||||
"#define GL_ARB_shader_atomic_counters 1\n"
|
"#define GL_ARB_shader_atomic_counters 1\n"
|
||||||
"#define GL_ARB_shader_draw_parameters 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_shader_texture_image_samples 1\n"
|
||||||
"#define GL_ARB_viewport_array 1\n"
|
"#define GL_ARB_viewport_array 1\n"
|
||||||
"#define GL_ARB_gpu_shader_int64 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_shader_ballot 1\n"
|
||||||
"#define GL_ARB_sparse_texture2 1\n"
|
"#define GL_ARB_sparse_texture2 1\n"
|
||||||
"#define GL_ARB_sparse_texture_clamp 1\n"
|
"#define GL_ARB_sparse_texture_clamp 1\n"
|
||||||
"#define GL_ARB_shader_stencil_export 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_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_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_non_constant_global_initializers 1\n"
|
||||||
"#define GL_EXT_shader_image_load_formatted 1\n"
|
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||||
"#define GL_EXT_post_depth_coverage 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_scalar_block_layout 1\n"
|
||||||
"#define GL_EXT_fragment_invocation_density 1\n"
|
"#define GL_EXT_fragment_invocation_density 1\n"
|
||||||
"#define GL_EXT_buffer_reference 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
|
// GL_KHR_shader_subgroup
|
||||||
"#define GL_KHR_shader_subgroup_basic 1\n"
|
"#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_clustered 1\n"
|
||||||
"#define GL_KHR_shader_subgroup_quad 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_ballot 1\n"
|
||||||
"#define GL_AMD_shader_trinary_minmax 1\n"
|
"#define GL_AMD_shader_trinary_minmax 1\n"
|
||||||
"#define GL_AMD_shader_explicit_vertex_parameter 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_image_load_store_lod 1\n"
|
||||||
"#define GL_AMD_shader_fragment_mask 1\n"
|
"#define GL_AMD_shader_fragment_mask 1\n"
|
||||||
"#define GL_AMD_gpu_shader_half_float_fetch 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_sample_mask_override_coverage 1\n"
|
||||||
"#define GL_NV_geometry_shader_passthrough 1\n"
|
"#define GL_NV_geometry_shader_passthrough 1\n"
|
||||||
"#define GL_NV_viewport_array2 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_shader_subgroup_partitioned 1\n"
|
||||||
"#define GL_NV_shading_rate_image 1\n"
|
"#define GL_NV_shading_rate_image 1\n"
|
||||||
"#define GL_NV_ray_tracing 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_fragment_shader_barycentric 1\n"
|
||||||
"#define GL_NV_compute_shader_derivatives 1\n"
|
"#define GL_NV_compute_shader_derivatives 1\n"
|
||||||
"#define GL_NV_shader_texture_footprint 1\n"
|
"#define GL_NV_shader_texture_footprint 1\n"
|
||||||
"#define GL_NV_mesh_shader 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 1\n"
|
||||||
"#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
|
||||||
"#define GL_EXT_shader_explicit_arithmetic_types_int16 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_float16 1\n"
|
||||||
"#define GL_EXT_shader_explicit_arithmetic_types_float32 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_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) {
|
if (version >= 150) {
|
||||||
|
@ -444,13 +555,20 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
if (profile == ECompatibilityProfile)
|
if (profile == ECompatibilityProfile)
|
||||||
preamble += "#define GL_compatibility_profile 1\n";
|
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) ||
|
#ifndef GLSLANG_WEB
|
||||||
(profile == EEsProfile && version >= 310)) {
|
if ((!isEsProfile() && version >= 140) ||
|
||||||
|
(isEsProfile() && version >= 310)) {
|
||||||
preamble +=
|
preamble +=
|
||||||
"#define GL_EXT_device_group 1\n"
|
"#define GL_EXT_device_group 1\n"
|
||||||
"#define GL_EXT_multiview 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 +=
|
preamble +=
|
||||||
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
|
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
|
||||||
"#define GL_GOOGLE_include_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
|
// #define VULKAN XXXX
|
||||||
const int numberBufSize = 12;
|
const int numberBufSize = 12;
|
||||||
char numberBuf[numberBufSize];
|
char numberBuf[numberBufSize];
|
||||||
|
@ -476,6 +601,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
preamble += numberBuf;
|
preamble += numberBuf;
|
||||||
preamble += "\n";
|
preamble += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// #define GL_SPIRV XXXX
|
// #define GL_SPIRV XXXX
|
||||||
if (spvVersion.openGl > 0) {
|
if (spvVersion.openGl > 0) {
|
||||||
preamble += "#define GL_SPIRV ";
|
preamble += "#define GL_SPIRV ";
|
||||||
|
@ -483,22 +610,30 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
preamble += numberBuf;
|
preamble += numberBuf;
|
||||||
preamble += "\n";
|
preamble += "\n";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
// 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -508,18 +643,18 @@ const char* StageName(EShLanguage stage)
|
||||||
{
|
{
|
||||||
switch(stage) {
|
switch(stage) {
|
||||||
case EShLangVertex: return "vertex";
|
case EShLangVertex: return "vertex";
|
||||||
|
case EShLangFragment: return "fragment";
|
||||||
|
case EShLangCompute: return "compute";
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EShLangTessControl: return "tessellation control";
|
case EShLangTessControl: return "tessellation control";
|
||||||
case EShLangTessEvaluation: return "tessellation evaluation";
|
case EShLangTessEvaluation: return "tessellation evaluation";
|
||||||
case EShLangGeometry: return "geometry";
|
case EShLangGeometry: return "geometry";
|
||||||
case EShLangFragment: return "fragment";
|
case EShLangRayGen: return "ray-generation";
|
||||||
case EShLangCompute: return "compute";
|
case EShLangIntersect: return "intersection";
|
||||||
#ifdef NV_EXTENSIONS
|
case EShLangAnyHit: return "any-hit";
|
||||||
case EShLangRayGenNV: return "ray-generation";
|
case EShLangClosestHit: return "closest-hit";
|
||||||
case EShLangIntersectNV: return "intersection";
|
case EShLangMiss: return "miss";
|
||||||
case EShLangAnyHitNV: return "any-hit";
|
case EShLangCallable: return "callable";
|
||||||
case EShLangClosestHitNV: return "closest-hit";
|
|
||||||
case EShLangMissNV: return "miss";
|
|
||||||
case EShLangCallableNV: return "callable";
|
|
||||||
case EShLangMeshNV: return "mesh";
|
case EShLangMeshNV: return "mesh";
|
||||||
case EShLangTaskNV: return "task";
|
case EShLangTaskNV: return "task";
|
||||||
#endif
|
#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()
|
// When to use requireStage()
|
||||||
//
|
//
|
||||||
|
@ -594,6 +682,75 @@ void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, cons
|
||||||
requireStage(loc, static_cast<EShLanguageMask>(1 << stage), featureDesc);
|
requireStage(loc, static_cast<EShLanguageMask>(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
|
// 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.
|
// 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.
|
// 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".
|
// 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)
|
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
|
// Use when there are no profile/version to check, it's just an error if one of the
|
||||||
// extensions is not present.
|
// 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))
|
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
|
||||||
return;
|
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
|
// Use by preprocessor when there are no profile/version to check, it's just an error if one of the
|
||||||
// extensions is not present.
|
// 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))
|
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
|
||||||
return;
|
return;
|
||||||
|
@ -750,10 +904,14 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
|
||||||
error(getCurrentLoc(), "behavior not supported:", "#extension", behaviorString);
|
error(getCurrentLoc(), "behavior not supported:", "#extension", behaviorString);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool on = behavior != EBhDisable;
|
||||||
|
|
||||||
// check if extension is used with correct shader stage
|
// check if extension is used with correct shader stage
|
||||||
checkExtensionStage(getCurrentLoc(), extension);
|
checkExtensionStage(getCurrentLoc(), extension);
|
||||||
|
|
||||||
|
// check if extension has additional requirements
|
||||||
|
extensionRequires(getCurrentLoc(), extension, behaviorString);
|
||||||
|
|
||||||
// update the requested extension
|
// update the requested extension
|
||||||
updateExtensionBehavior(extension, behavior);
|
updateExtensionBehavior(extension, behavior);
|
||||||
|
|
||||||
|
@ -800,10 +958,48 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
|
||||||
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
else if (strcmp(extension, "GL_KHR_shader_subgroup_quad") == 0)
|
else if (strcmp(extension, "GL_KHR_shader_subgroup_quad") == 0)
|
||||||
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
else if (strcmp(extension, "GL_NV_shader_subgroup_partitioned") == 0)
|
else if (strcmp(extension, "GL_NV_shader_subgroup_partitioned") == 0)
|
||||||
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
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)
|
void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
||||||
|
@ -839,7 +1035,7 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe
|
||||||
} else {
|
} else {
|
||||||
if (iter->second == EBhDisablePartial)
|
if (iter->second == EBhDisablePartial)
|
||||||
warn(getCurrentLoc(), "extension is only partially supported:", "#extension", extension);
|
warn(getCurrentLoc(), "extension is only partially supported:", "#extension", extension);
|
||||||
if (behavior == EBhEnable || behavior == EBhRequire)
|
if (behavior != EBhDisable)
|
||||||
intermediate.addRequestedExtension(extension);
|
intermediate.addRequestedExtension(extension);
|
||||||
iter->second = behavior;
|
iter->second = behavior;
|
||||||
}
|
}
|
||||||
|
@ -849,7 +1045,6 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe
|
||||||
// Check if extension is used with correct shader stage.
|
// Check if extension is used with correct shader stage.
|
||||||
void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension)
|
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
|
// GL_NV_mesh_shader extension is only allowed in task/mesh shaders
|
||||||
if (strcmp(extension, "GL_NV_mesh_shader") == 0) {
|
if (strcmp(extension, "GL_NV_mesh_shader") == 0) {
|
||||||
requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask),
|
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, ECoreProfile, 450, 0, "#extension GL_NV_mesh_shader");
|
||||||
profileRequires(loc, EEsProfile, 320, 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.
|
// 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.
|
// Call for any operation needing GLSL double data-type support.
|
||||||
void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
|
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.
|
// 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) {
|
if (!builtIn) {
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
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()
|
bool TParseVersions::float16Arithmetic()
|
||||||
{
|
{
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
||||||
|
@ -902,9 +1115,7 @@ bool TParseVersions::float16Arithmetic()
|
||||||
bool TParseVersions::int16Arithmetic()
|
bool TParseVersions::int16Arithmetic()
|
||||||
{
|
{
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
||||||
|
@ -926,9 +1137,7 @@ void TParseVersions::requireFloat16Arithmetic(const TSourceLoc& loc, const char*
|
||||||
combined += featureDesc;
|
combined += featureDesc;
|
||||||
|
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
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;
|
combined += featureDesc;
|
||||||
|
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
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) {
|
if (!builtIn) {
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_16bit_storage,
|
E_GL_EXT_shader_16bit_storage,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
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
|
// Call for any operation needing GLSL float16 opaque-type support
|
||||||
void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, bool builtIn)
|
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);
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Call for any operation needing GLSL explicit int16 data-type support.
|
// Call for any operation needing GLSL explicit int16 data-type support.
|
||||||
void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
{
|
{
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
||||||
|
@ -1039,9 +1240,7 @@ void TParseVersions::int16ScalarVectorCheck(const TSourceLoc& loc, const char* o
|
||||||
{
|
{
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_16bit_storage,
|
E_GL_EXT_shader_16bit_storage,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
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.
|
// Call for any operation removed because SPIR-V is in use.
|
||||||
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
|
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.
|
// Call for any operation removed because Vulkan SPIR-V is being generated.
|
||||||
void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op)
|
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, "");
|
error(loc, "not allowed when using GLSL for Vulkan", op, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation that requires Vulkan.
|
// Call for any operation that requires Vulkan.
|
||||||
void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op)
|
void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (spvVersion.vulkan == 0)
|
if (spvVersion.vulkan == 0)
|
||||||
error(loc, "only allowed when using GLSL for Vulkan", op, "");
|
error(loc, "only allowed when using GLSL for Vulkan", op, "");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation that requires SPIR-V.
|
// Call for any operation that requires SPIR-V.
|
||||||
void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op)
|
void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (spvVersion.spv == 0)
|
if (spvVersion.spv == 0)
|
||||||
error(loc, "only allowed when generating SPIR-V", op, "");
|
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
|
} // end namespace glslang
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -35,9 +36,12 @@
|
||||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _VERSIONS_INCLUDED_
|
#ifndef _VERSIONS_INCLUDED_
|
||||||
#define _VERSIONS_INCLUDED_
|
#define _VERSIONS_INCLUDED_
|
||||||
|
|
||||||
|
#define LAST_ELEMENT_MARKER(x) x
|
||||||
|
|
||||||
//
|
//
|
||||||
// Help manage multiple profiles, versions, extensions etc.
|
// 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
|
// Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible
|
||||||
// defects from mixing the two different forms.
|
// defects from mixing the two different forms.
|
||||||
//
|
//
|
||||||
typedef enum {
|
typedef enum : unsigned {
|
||||||
EBadProfile = 0,
|
EBadProfile = 0,
|
||||||
ENoProfile = (1 << 0), // only for desktop, before profiles showed up
|
ENoProfile = (1 << 0), // only for desktop, before profiles showed up
|
||||||
ECoreProfile = (1 << 1),
|
ECoreProfile = (1 << 1),
|
||||||
ECompatibilityProfile = (1 << 2),
|
ECompatibilityProfile = (1 << 2),
|
||||||
EEsProfile = (1 << 3)
|
EEsProfile = (1 << 3),
|
||||||
|
LAST_ELEMENT_MARKER(EProfileCount),
|
||||||
} EProfile;
|
} EProfile;
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
@ -82,11 +87,12 @@ inline const char* ProfileName(EProfile profile)
|
||||||
// The union of all requested rule sets will be applied.
|
// The union of all requested rule sets will be applied.
|
||||||
//
|
//
|
||||||
struct SpvVersion {
|
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
|
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 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 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"
|
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_tessellation_shader = "GL_ARB_tessellation_shader";
|
||||||
const char* const E_GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts";
|
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_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_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_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_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_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_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_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_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_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_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_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_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_texture2 = "GL_ARB_sparse_texture2";
|
||||||
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
|
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_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_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_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_basic = "GL_KHR_shader_subgroup_basic";
|
||||||
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
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_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_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_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
|
// 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_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
||||||
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_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_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_trinary_minmax = "GL_AMD_shader_trinary_minmax";
|
||||||
const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter";
|
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_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_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";
|
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_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";
|
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_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_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 = "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_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_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
|
||||||
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";
|
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 char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 };
|
||||||
const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
|
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
|
// AEP
|
||||||
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
|
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_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_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_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
|
// OES matching AEP
|
||||||
const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader";
|
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_buffer = "GL_OES_texture_buffer";
|
||||||
const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array";
|
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 = "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_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";
|
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_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_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
|
// Arrays of extensions for the above AEP duplications
|
||||||
|
|
||||||
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
#include "attribute.h"
|
#include "attribute.h"
|
||||||
#include "../Include/intermediate.h"
|
#include "../Include/intermediate.h"
|
||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
|
@ -52,6 +54,7 @@ bool TAttributeArgs::getInt(int& value, int argNum) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// extract strings out of attribute arguments stored in attribute aggregate.
|
// extract strings out of attribute arguments stored in attribute aggregate.
|
||||||
// convert to lower case if converToLower is true (for case-insensitive compare convenience)
|
// convert to lower case if converToLower is true (for case-insensitive compare convenience)
|
||||||
bool TAttributeArgs::getString(TString& value, int argNum, bool convertToLower) const
|
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())
|
if (argNum >= (int)args->getSequence().size())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
if (args->getSequence()[argNum]->getAsConstantUnion() == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
const TConstUnion* constVal = &args->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
|
const TConstUnion* constVal = &args->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
|
||||||
if (constVal == nullptr || constVal->getType() != basicType)
|
if (constVal == nullptr || constVal->getType() != basicType)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -107,6 +113,18 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
|
||||||
return EatDependencyInfinite;
|
return EatDependencyInfinite;
|
||||||
else if (name == "dependency_length")
|
else if (name == "dependency_length")
|
||||||
return EatDependencyLength;
|
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
|
else
|
||||||
return EatNone;
|
return EatNone;
|
||||||
}
|
}
|
||||||
|
@ -222,29 +240,101 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
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) {
|
switch (it->name) {
|
||||||
case EatUnroll:
|
case EatUnroll:
|
||||||
|
if (noArgument("unroll"))
|
||||||
loop->setUnroll();
|
loop->setUnroll();
|
||||||
break;
|
break;
|
||||||
case EatLoop:
|
case EatLoop:
|
||||||
|
if (noArgument("dont_unroll"))
|
||||||
loop->setDontUnroll();
|
loop->setDontUnroll();
|
||||||
break;
|
break;
|
||||||
case EatDependencyInfinite:
|
case EatDependencyInfinite:
|
||||||
|
if (noArgument("dependency_infinite"))
|
||||||
loop->setLoopDependency(TIntermLoop::dependencyInfinite);
|
loop->setLoopDependency(TIntermLoop::dependencyInfinite);
|
||||||
break;
|
break;
|
||||||
case EatDependencyLength:
|
case EatDependencyLength:
|
||||||
if (it->size() == 1 && it->getInt(value)) {
|
if (positiveSignedArgument("dependency_length", value))
|
||||||
if (value <= 0)
|
|
||||||
error(node->getLoc(), "must be positive", "dependency_length", "");
|
|
||||||
loop->setLoopDependency(value);
|
loop->setLoopDependency(value);
|
||||||
} else
|
break;
|
||||||
warn(node->getLoc(), "expected a single integer argument", "dependency_length", "");
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
warn(node->getLoc(), "attribute does not apply to a loop", "", "");
|
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
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
|
|
|
@ -71,7 +71,55 @@ namespace glslang {
|
||||||
EatPushConstant,
|
EatPushConstant,
|
||||||
EatConstantId,
|
EatConstantId,
|
||||||
EatDependencyInfinite,
|
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;
|
class TIntermAggregate;
|
||||||
|
|
|
@ -49,9 +49,17 @@
|
||||||
#define GL_INT64_VEC4_ARB 0x8FEB
|
#define GL_INT64_VEC4_ARB 0x8FEB
|
||||||
|
|
||||||
#define GL_UNSIGNED_INT64_ARB 0x140F
|
#define GL_UNSIGNED_INT64_ARB 0x140F
|
||||||
#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FE5
|
#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5
|
||||||
#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FE6
|
#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6
|
||||||
#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FE7
|
#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 0x8B56
|
||||||
#define GL_BOOL_VEC2 0x8B57
|
#define GL_BOOL_VEC2 0x8B57
|
||||||
|
@ -78,7 +86,6 @@
|
||||||
#define GL_DOUBLE_MAT4x2 0x8F4D
|
#define GL_DOUBLE_MAT4x2 0x8F4D
|
||||||
#define GL_DOUBLE_MAT4x3 0x8F4E
|
#define GL_DOUBLE_MAT4x3 0x8F4E
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
// Those constants are borrowed from extension NV_gpu_shader5
|
// Those constants are borrowed from extension NV_gpu_shader5
|
||||||
#define GL_FLOAT16_NV 0x8FF8
|
#define GL_FLOAT16_NV 0x8FF8
|
||||||
#define GL_FLOAT16_VEC2_NV 0x8FF9
|
#define GL_FLOAT16_VEC2_NV 0x8FF9
|
||||||
|
@ -94,7 +101,6 @@
|
||||||
#define GL_FLOAT16_MAT3x4_AMD 0x91CB
|
#define GL_FLOAT16_MAT3x4_AMD 0x91CB
|
||||||
#define GL_FLOAT16_MAT4x2_AMD 0x91CC
|
#define GL_FLOAT16_MAT4x2_AMD 0x91CC
|
||||||
#define GL_FLOAT16_MAT4x3_AMD 0x91CD
|
#define GL_FLOAT16_MAT4x3_AMD 0x91CD
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GL_SAMPLER_1D 0x8B5D
|
#define GL_SAMPLER_1D 0x8B5D
|
||||||
#define GL_SAMPLER_2D 0x8B5E
|
#define GL_SAMPLER_2D 0x8B5E
|
||||||
|
@ -117,7 +123,6 @@
|
||||||
#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
|
#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
|
||||||
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
|
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
#define GL_FLOAT16_SAMPLER_1D_AMD 0x91CE
|
#define GL_FLOAT16_SAMPLER_1D_AMD 0x91CE
|
||||||
#define GL_FLOAT16_SAMPLER_2D_AMD 0x91CF
|
#define GL_FLOAT16_SAMPLER_2D_AMD 0x91CF
|
||||||
#define GL_FLOAT16_SAMPLER_3D_AMD 0x91D0
|
#define GL_FLOAT16_SAMPLER_3D_AMD 0x91D0
|
||||||
|
@ -149,7 +154,6 @@
|
||||||
#define GL_FLOAT16_IMAGE_BUFFER_AMD 0x91E8
|
#define GL_FLOAT16_IMAGE_BUFFER_AMD 0x91E8
|
||||||
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD 0x91E9
|
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD 0x91E9
|
||||||
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD 0x91EA
|
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD 0x91EA
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GL_INT_SAMPLER_1D 0x8DC9
|
#define GL_INT_SAMPLER_1D 0x8DC9
|
||||||
#define GL_INT_SAMPLER_2D 0x8DCA
|
#define GL_INT_SAMPLER_2D 0x8DCA
|
||||||
|
|
4398
thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang.m4
vendored
Normal file
4398
thirdparty/ShaderCompiler/glslang/MachineIndependent/glslang.m4
vendored
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -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
|
/* 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
|
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
|
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
|
This special exception was added by the Free Software Foundation in
|
||||||
version 2.2 of Bison. */
|
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
|
#ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED
|
||||||
# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED
|
# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED
|
||||||
/* Debug traces. */
|
/* Debug traces. */
|
||||||
|
@ -40,424 +45,476 @@
|
||||||
extern int yydebug;
|
extern int yydebug;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Token type. */
|
/* Token kinds. */
|
||||||
#ifndef YYTOKENTYPE
|
#ifndef YYTOKENTYPE
|
||||||
# define YYTOKENTYPE
|
# define YYTOKENTYPE
|
||||||
enum yytokentype
|
enum yytokentype
|
||||||
{
|
{
|
||||||
ATTRIBUTE = 258,
|
YYEMPTY = -2,
|
||||||
VARYING = 259,
|
YYEOF = 0, /* "end of file" */
|
||||||
FLOAT16_T = 260,
|
YYerror = 256, /* error */
|
||||||
FLOAT = 261,
|
YYUNDEF = 257, /* "invalid token" */
|
||||||
FLOAT32_T = 262,
|
CONST = 258, /* CONST */
|
||||||
DOUBLE = 263,
|
BOOL = 259, /* BOOL */
|
||||||
FLOAT64_T = 264,
|
INT = 260, /* INT */
|
||||||
CONST = 265,
|
UINT = 261, /* UINT */
|
||||||
BOOL = 266,
|
FLOAT = 262, /* FLOAT */
|
||||||
INT = 267,
|
BVEC2 = 263, /* BVEC2 */
|
||||||
UINT = 268,
|
BVEC3 = 264, /* BVEC3 */
|
||||||
INT64_T = 269,
|
BVEC4 = 265, /* BVEC4 */
|
||||||
UINT64_T = 270,
|
IVEC2 = 266, /* IVEC2 */
|
||||||
INT32_T = 271,
|
IVEC3 = 267, /* IVEC3 */
|
||||||
UINT32_T = 272,
|
IVEC4 = 268, /* IVEC4 */
|
||||||
INT16_T = 273,
|
UVEC2 = 269, /* UVEC2 */
|
||||||
UINT16_T = 274,
|
UVEC3 = 270, /* UVEC3 */
|
||||||
INT8_T = 275,
|
UVEC4 = 271, /* UVEC4 */
|
||||||
UINT8_T = 276,
|
VEC2 = 272, /* VEC2 */
|
||||||
BREAK = 277,
|
VEC3 = 273, /* VEC3 */
|
||||||
CONTINUE = 278,
|
VEC4 = 274, /* VEC4 */
|
||||||
DO = 279,
|
MAT2 = 275, /* MAT2 */
|
||||||
ELSE = 280,
|
MAT3 = 276, /* MAT3 */
|
||||||
FOR = 281,
|
MAT4 = 277, /* MAT4 */
|
||||||
IF = 282,
|
MAT2X2 = 278, /* MAT2X2 */
|
||||||
DISCARD = 283,
|
MAT2X3 = 279, /* MAT2X3 */
|
||||||
RETURN = 284,
|
MAT2X4 = 280, /* MAT2X4 */
|
||||||
SWITCH = 285,
|
MAT3X2 = 281, /* MAT3X2 */
|
||||||
CASE = 286,
|
MAT3X3 = 282, /* MAT3X3 */
|
||||||
DEFAULT = 287,
|
MAT3X4 = 283, /* MAT3X4 */
|
||||||
SUBROUTINE = 288,
|
MAT4X2 = 284, /* MAT4X2 */
|
||||||
BVEC2 = 289,
|
MAT4X3 = 285, /* MAT4X3 */
|
||||||
BVEC3 = 290,
|
MAT4X4 = 286, /* MAT4X4 */
|
||||||
BVEC4 = 291,
|
SAMPLER2D = 287, /* SAMPLER2D */
|
||||||
IVEC2 = 292,
|
SAMPLER3D = 288, /* SAMPLER3D */
|
||||||
IVEC3 = 293,
|
SAMPLERCUBE = 289, /* SAMPLERCUBE */
|
||||||
IVEC4 = 294,
|
SAMPLER2DSHADOW = 290, /* SAMPLER2DSHADOW */
|
||||||
UVEC2 = 295,
|
SAMPLERCUBESHADOW = 291, /* SAMPLERCUBESHADOW */
|
||||||
UVEC3 = 296,
|
SAMPLER2DARRAY = 292, /* SAMPLER2DARRAY */
|
||||||
UVEC4 = 297,
|
SAMPLER2DARRAYSHADOW = 293, /* SAMPLER2DARRAYSHADOW */
|
||||||
I64VEC2 = 298,
|
ISAMPLER2D = 294, /* ISAMPLER2D */
|
||||||
I64VEC3 = 299,
|
ISAMPLER3D = 295, /* ISAMPLER3D */
|
||||||
I64VEC4 = 300,
|
ISAMPLERCUBE = 296, /* ISAMPLERCUBE */
|
||||||
U64VEC2 = 301,
|
ISAMPLER2DARRAY = 297, /* ISAMPLER2DARRAY */
|
||||||
U64VEC3 = 302,
|
USAMPLER2D = 298, /* USAMPLER2D */
|
||||||
U64VEC4 = 303,
|
USAMPLER3D = 299, /* USAMPLER3D */
|
||||||
I32VEC2 = 304,
|
USAMPLERCUBE = 300, /* USAMPLERCUBE */
|
||||||
I32VEC3 = 305,
|
USAMPLER2DARRAY = 301, /* USAMPLER2DARRAY */
|
||||||
I32VEC4 = 306,
|
SAMPLER = 302, /* SAMPLER */
|
||||||
U32VEC2 = 307,
|
SAMPLERSHADOW = 303, /* SAMPLERSHADOW */
|
||||||
U32VEC3 = 308,
|
TEXTURE2D = 304, /* TEXTURE2D */
|
||||||
U32VEC4 = 309,
|
TEXTURE3D = 305, /* TEXTURE3D */
|
||||||
I16VEC2 = 310,
|
TEXTURECUBE = 306, /* TEXTURECUBE */
|
||||||
I16VEC3 = 311,
|
TEXTURE2DARRAY = 307, /* TEXTURE2DARRAY */
|
||||||
I16VEC4 = 312,
|
ITEXTURE2D = 308, /* ITEXTURE2D */
|
||||||
U16VEC2 = 313,
|
ITEXTURE3D = 309, /* ITEXTURE3D */
|
||||||
U16VEC3 = 314,
|
ITEXTURECUBE = 310, /* ITEXTURECUBE */
|
||||||
U16VEC4 = 315,
|
ITEXTURE2DARRAY = 311, /* ITEXTURE2DARRAY */
|
||||||
I8VEC2 = 316,
|
UTEXTURE2D = 312, /* UTEXTURE2D */
|
||||||
I8VEC3 = 317,
|
UTEXTURE3D = 313, /* UTEXTURE3D */
|
||||||
I8VEC4 = 318,
|
UTEXTURECUBE = 314, /* UTEXTURECUBE */
|
||||||
U8VEC2 = 319,
|
UTEXTURE2DARRAY = 315, /* UTEXTURE2DARRAY */
|
||||||
U8VEC3 = 320,
|
ATTRIBUTE = 316, /* ATTRIBUTE */
|
||||||
U8VEC4 = 321,
|
VARYING = 317, /* VARYING */
|
||||||
VEC2 = 322,
|
FLOAT16_T = 318, /* FLOAT16_T */
|
||||||
VEC3 = 323,
|
FLOAT32_T = 319, /* FLOAT32_T */
|
||||||
VEC4 = 324,
|
DOUBLE = 320, /* DOUBLE */
|
||||||
MAT2 = 325,
|
FLOAT64_T = 321, /* FLOAT64_T */
|
||||||
MAT3 = 326,
|
INT64_T = 322, /* INT64_T */
|
||||||
MAT4 = 327,
|
UINT64_T = 323, /* UINT64_T */
|
||||||
CENTROID = 328,
|
INT32_T = 324, /* INT32_T */
|
||||||
IN = 329,
|
UINT32_T = 325, /* UINT32_T */
|
||||||
OUT = 330,
|
INT16_T = 326, /* INT16_T */
|
||||||
INOUT = 331,
|
UINT16_T = 327, /* UINT16_T */
|
||||||
UNIFORM = 332,
|
INT8_T = 328, /* INT8_T */
|
||||||
PATCH = 333,
|
UINT8_T = 329, /* UINT8_T */
|
||||||
SAMPLE = 334,
|
I64VEC2 = 330, /* I64VEC2 */
|
||||||
BUFFER = 335,
|
I64VEC3 = 331, /* I64VEC3 */
|
||||||
SHARED = 336,
|
I64VEC4 = 332, /* I64VEC4 */
|
||||||
NONUNIFORM = 337,
|
U64VEC2 = 333, /* U64VEC2 */
|
||||||
PAYLOADNV = 338,
|
U64VEC3 = 334, /* U64VEC3 */
|
||||||
PAYLOADINNV = 339,
|
U64VEC4 = 335, /* U64VEC4 */
|
||||||
HITATTRNV = 340,
|
I32VEC2 = 336, /* I32VEC2 */
|
||||||
CALLDATANV = 341,
|
I32VEC3 = 337, /* I32VEC3 */
|
||||||
CALLDATAINNV = 342,
|
I32VEC4 = 338, /* I32VEC4 */
|
||||||
COHERENT = 343,
|
U32VEC2 = 339, /* U32VEC2 */
|
||||||
VOLATILE = 344,
|
U32VEC3 = 340, /* U32VEC3 */
|
||||||
RESTRICT = 345,
|
U32VEC4 = 341, /* U32VEC4 */
|
||||||
READONLY = 346,
|
I16VEC2 = 342, /* I16VEC2 */
|
||||||
WRITEONLY = 347,
|
I16VEC3 = 343, /* I16VEC3 */
|
||||||
DEVICECOHERENT = 348,
|
I16VEC4 = 344, /* I16VEC4 */
|
||||||
QUEUEFAMILYCOHERENT = 349,
|
U16VEC2 = 345, /* U16VEC2 */
|
||||||
WORKGROUPCOHERENT = 350,
|
U16VEC3 = 346, /* U16VEC3 */
|
||||||
SUBGROUPCOHERENT = 351,
|
U16VEC4 = 347, /* U16VEC4 */
|
||||||
NONPRIVATE = 352,
|
I8VEC2 = 348, /* I8VEC2 */
|
||||||
DVEC2 = 353,
|
I8VEC3 = 349, /* I8VEC3 */
|
||||||
DVEC3 = 354,
|
I8VEC4 = 350, /* I8VEC4 */
|
||||||
DVEC4 = 355,
|
U8VEC2 = 351, /* U8VEC2 */
|
||||||
DMAT2 = 356,
|
U8VEC3 = 352, /* U8VEC3 */
|
||||||
DMAT3 = 357,
|
U8VEC4 = 353, /* U8VEC4 */
|
||||||
DMAT4 = 358,
|
DVEC2 = 354, /* DVEC2 */
|
||||||
F16VEC2 = 359,
|
DVEC3 = 355, /* DVEC3 */
|
||||||
F16VEC3 = 360,
|
DVEC4 = 356, /* DVEC4 */
|
||||||
F16VEC4 = 361,
|
DMAT2 = 357, /* DMAT2 */
|
||||||
F16MAT2 = 362,
|
DMAT3 = 358, /* DMAT3 */
|
||||||
F16MAT3 = 363,
|
DMAT4 = 359, /* DMAT4 */
|
||||||
F16MAT4 = 364,
|
F16VEC2 = 360, /* F16VEC2 */
|
||||||
F32VEC2 = 365,
|
F16VEC3 = 361, /* F16VEC3 */
|
||||||
F32VEC3 = 366,
|
F16VEC4 = 362, /* F16VEC4 */
|
||||||
F32VEC4 = 367,
|
F16MAT2 = 363, /* F16MAT2 */
|
||||||
F32MAT2 = 368,
|
F16MAT3 = 364, /* F16MAT3 */
|
||||||
F32MAT3 = 369,
|
F16MAT4 = 365, /* F16MAT4 */
|
||||||
F32MAT4 = 370,
|
F32VEC2 = 366, /* F32VEC2 */
|
||||||
F64VEC2 = 371,
|
F32VEC3 = 367, /* F32VEC3 */
|
||||||
F64VEC3 = 372,
|
F32VEC4 = 368, /* F32VEC4 */
|
||||||
F64VEC4 = 373,
|
F32MAT2 = 369, /* F32MAT2 */
|
||||||
F64MAT2 = 374,
|
F32MAT3 = 370, /* F32MAT3 */
|
||||||
F64MAT3 = 375,
|
F32MAT4 = 371, /* F32MAT4 */
|
||||||
F64MAT4 = 376,
|
F64VEC2 = 372, /* F64VEC2 */
|
||||||
NOPERSPECTIVE = 377,
|
F64VEC3 = 373, /* F64VEC3 */
|
||||||
FLAT = 378,
|
F64VEC4 = 374, /* F64VEC4 */
|
||||||
SMOOTH = 379,
|
F64MAT2 = 375, /* F64MAT2 */
|
||||||
LAYOUT = 380,
|
F64MAT3 = 376, /* F64MAT3 */
|
||||||
EXPLICITINTERPAMD = 381,
|
F64MAT4 = 377, /* F64MAT4 */
|
||||||
PERVERTEXNV = 382,
|
DMAT2X2 = 378, /* DMAT2X2 */
|
||||||
PERPRIMITIVENV = 383,
|
DMAT2X3 = 379, /* DMAT2X3 */
|
||||||
PERVIEWNV = 384,
|
DMAT2X4 = 380, /* DMAT2X4 */
|
||||||
PERTASKNV = 385,
|
DMAT3X2 = 381, /* DMAT3X2 */
|
||||||
MAT2X2 = 386,
|
DMAT3X3 = 382, /* DMAT3X3 */
|
||||||
MAT2X3 = 387,
|
DMAT3X4 = 383, /* DMAT3X4 */
|
||||||
MAT2X4 = 388,
|
DMAT4X2 = 384, /* DMAT4X2 */
|
||||||
MAT3X2 = 389,
|
DMAT4X3 = 385, /* DMAT4X3 */
|
||||||
MAT3X3 = 390,
|
DMAT4X4 = 386, /* DMAT4X4 */
|
||||||
MAT3X4 = 391,
|
F16MAT2X2 = 387, /* F16MAT2X2 */
|
||||||
MAT4X2 = 392,
|
F16MAT2X3 = 388, /* F16MAT2X3 */
|
||||||
MAT4X3 = 393,
|
F16MAT2X4 = 389, /* F16MAT2X4 */
|
||||||
MAT4X4 = 394,
|
F16MAT3X2 = 390, /* F16MAT3X2 */
|
||||||
DMAT2X2 = 395,
|
F16MAT3X3 = 391, /* F16MAT3X3 */
|
||||||
DMAT2X3 = 396,
|
F16MAT3X4 = 392, /* F16MAT3X4 */
|
||||||
DMAT2X4 = 397,
|
F16MAT4X2 = 393, /* F16MAT4X2 */
|
||||||
DMAT3X2 = 398,
|
F16MAT4X3 = 394, /* F16MAT4X3 */
|
||||||
DMAT3X3 = 399,
|
F16MAT4X4 = 395, /* F16MAT4X4 */
|
||||||
DMAT3X4 = 400,
|
F32MAT2X2 = 396, /* F32MAT2X2 */
|
||||||
DMAT4X2 = 401,
|
F32MAT2X3 = 397, /* F32MAT2X3 */
|
||||||
DMAT4X3 = 402,
|
F32MAT2X4 = 398, /* F32MAT2X4 */
|
||||||
DMAT4X4 = 403,
|
F32MAT3X2 = 399, /* F32MAT3X2 */
|
||||||
F16MAT2X2 = 404,
|
F32MAT3X3 = 400, /* F32MAT3X3 */
|
||||||
F16MAT2X3 = 405,
|
F32MAT3X4 = 401, /* F32MAT3X4 */
|
||||||
F16MAT2X4 = 406,
|
F32MAT4X2 = 402, /* F32MAT4X2 */
|
||||||
F16MAT3X2 = 407,
|
F32MAT4X3 = 403, /* F32MAT4X3 */
|
||||||
F16MAT3X3 = 408,
|
F32MAT4X4 = 404, /* F32MAT4X4 */
|
||||||
F16MAT3X4 = 409,
|
F64MAT2X2 = 405, /* F64MAT2X2 */
|
||||||
F16MAT4X2 = 410,
|
F64MAT2X3 = 406, /* F64MAT2X3 */
|
||||||
F16MAT4X3 = 411,
|
F64MAT2X4 = 407, /* F64MAT2X4 */
|
||||||
F16MAT4X4 = 412,
|
F64MAT3X2 = 408, /* F64MAT3X2 */
|
||||||
F32MAT2X2 = 413,
|
F64MAT3X3 = 409, /* F64MAT3X3 */
|
||||||
F32MAT2X3 = 414,
|
F64MAT3X4 = 410, /* F64MAT3X4 */
|
||||||
F32MAT2X4 = 415,
|
F64MAT4X2 = 411, /* F64MAT4X2 */
|
||||||
F32MAT3X2 = 416,
|
F64MAT4X3 = 412, /* F64MAT4X3 */
|
||||||
F32MAT3X3 = 417,
|
F64MAT4X4 = 413, /* F64MAT4X4 */
|
||||||
F32MAT3X4 = 418,
|
ATOMIC_UINT = 414, /* ATOMIC_UINT */
|
||||||
F32MAT4X2 = 419,
|
ACCSTRUCTNV = 415, /* ACCSTRUCTNV */
|
||||||
F32MAT4X3 = 420,
|
ACCSTRUCTEXT = 416, /* ACCSTRUCTEXT */
|
||||||
F32MAT4X4 = 421,
|
RAYQUERYEXT = 417, /* RAYQUERYEXT */
|
||||||
F64MAT2X2 = 422,
|
FCOOPMATNV = 418, /* FCOOPMATNV */
|
||||||
F64MAT2X3 = 423,
|
ICOOPMATNV = 419, /* ICOOPMATNV */
|
||||||
F64MAT2X4 = 424,
|
UCOOPMATNV = 420, /* UCOOPMATNV */
|
||||||
F64MAT3X2 = 425,
|
SAMPLERCUBEARRAY = 421, /* SAMPLERCUBEARRAY */
|
||||||
F64MAT3X3 = 426,
|
SAMPLERCUBEARRAYSHADOW = 422, /* SAMPLERCUBEARRAYSHADOW */
|
||||||
F64MAT3X4 = 427,
|
ISAMPLERCUBEARRAY = 423, /* ISAMPLERCUBEARRAY */
|
||||||
F64MAT4X2 = 428,
|
USAMPLERCUBEARRAY = 424, /* USAMPLERCUBEARRAY */
|
||||||
F64MAT4X3 = 429,
|
SAMPLER1D = 425, /* SAMPLER1D */
|
||||||
F64MAT4X4 = 430,
|
SAMPLER1DARRAY = 426, /* SAMPLER1DARRAY */
|
||||||
ATOMIC_UINT = 431,
|
SAMPLER1DARRAYSHADOW = 427, /* SAMPLER1DARRAYSHADOW */
|
||||||
ACCSTRUCTNV = 432,
|
ISAMPLER1D = 428, /* ISAMPLER1D */
|
||||||
SAMPLER1D = 433,
|
SAMPLER1DSHADOW = 429, /* SAMPLER1DSHADOW */
|
||||||
SAMPLER2D = 434,
|
SAMPLER2DRECT = 430, /* SAMPLER2DRECT */
|
||||||
SAMPLER3D = 435,
|
SAMPLER2DRECTSHADOW = 431, /* SAMPLER2DRECTSHADOW */
|
||||||
SAMPLERCUBE = 436,
|
ISAMPLER2DRECT = 432, /* ISAMPLER2DRECT */
|
||||||
SAMPLER1DSHADOW = 437,
|
USAMPLER2DRECT = 433, /* USAMPLER2DRECT */
|
||||||
SAMPLER2DSHADOW = 438,
|
SAMPLERBUFFER = 434, /* SAMPLERBUFFER */
|
||||||
SAMPLERCUBESHADOW = 439,
|
ISAMPLERBUFFER = 435, /* ISAMPLERBUFFER */
|
||||||
SAMPLER1DARRAY = 440,
|
USAMPLERBUFFER = 436, /* USAMPLERBUFFER */
|
||||||
SAMPLER2DARRAY = 441,
|
SAMPLER2DMS = 437, /* SAMPLER2DMS */
|
||||||
SAMPLER1DARRAYSHADOW = 442,
|
ISAMPLER2DMS = 438, /* ISAMPLER2DMS */
|
||||||
SAMPLER2DARRAYSHADOW = 443,
|
USAMPLER2DMS = 439, /* USAMPLER2DMS */
|
||||||
ISAMPLER1D = 444,
|
SAMPLER2DMSARRAY = 440, /* SAMPLER2DMSARRAY */
|
||||||
ISAMPLER2D = 445,
|
ISAMPLER2DMSARRAY = 441, /* ISAMPLER2DMSARRAY */
|
||||||
ISAMPLER3D = 446,
|
USAMPLER2DMSARRAY = 442, /* USAMPLER2DMSARRAY */
|
||||||
ISAMPLERCUBE = 447,
|
SAMPLEREXTERNALOES = 443, /* SAMPLEREXTERNALOES */
|
||||||
ISAMPLER1DARRAY = 448,
|
SAMPLEREXTERNAL2DY2YEXT = 444, /* SAMPLEREXTERNAL2DY2YEXT */
|
||||||
ISAMPLER2DARRAY = 449,
|
ISAMPLER1DARRAY = 445, /* ISAMPLER1DARRAY */
|
||||||
USAMPLER1D = 450,
|
USAMPLER1D = 446, /* USAMPLER1D */
|
||||||
USAMPLER2D = 451,
|
USAMPLER1DARRAY = 447, /* USAMPLER1DARRAY */
|
||||||
USAMPLER3D = 452,
|
F16SAMPLER1D = 448, /* F16SAMPLER1D */
|
||||||
USAMPLERCUBE = 453,
|
F16SAMPLER2D = 449, /* F16SAMPLER2D */
|
||||||
USAMPLER1DARRAY = 454,
|
F16SAMPLER3D = 450, /* F16SAMPLER3D */
|
||||||
USAMPLER2DARRAY = 455,
|
F16SAMPLER2DRECT = 451, /* F16SAMPLER2DRECT */
|
||||||
SAMPLER2DRECT = 456,
|
F16SAMPLERCUBE = 452, /* F16SAMPLERCUBE */
|
||||||
SAMPLER2DRECTSHADOW = 457,
|
F16SAMPLER1DARRAY = 453, /* F16SAMPLER1DARRAY */
|
||||||
ISAMPLER2DRECT = 458,
|
F16SAMPLER2DARRAY = 454, /* F16SAMPLER2DARRAY */
|
||||||
USAMPLER2DRECT = 459,
|
F16SAMPLERCUBEARRAY = 455, /* F16SAMPLERCUBEARRAY */
|
||||||
SAMPLERBUFFER = 460,
|
F16SAMPLERBUFFER = 456, /* F16SAMPLERBUFFER */
|
||||||
ISAMPLERBUFFER = 461,
|
F16SAMPLER2DMS = 457, /* F16SAMPLER2DMS */
|
||||||
USAMPLERBUFFER = 462,
|
F16SAMPLER2DMSARRAY = 458, /* F16SAMPLER2DMSARRAY */
|
||||||
SAMPLERCUBEARRAY = 463,
|
F16SAMPLER1DSHADOW = 459, /* F16SAMPLER1DSHADOW */
|
||||||
SAMPLERCUBEARRAYSHADOW = 464,
|
F16SAMPLER2DSHADOW = 460, /* F16SAMPLER2DSHADOW */
|
||||||
ISAMPLERCUBEARRAY = 465,
|
F16SAMPLER1DARRAYSHADOW = 461, /* F16SAMPLER1DARRAYSHADOW */
|
||||||
USAMPLERCUBEARRAY = 466,
|
F16SAMPLER2DARRAYSHADOW = 462, /* F16SAMPLER2DARRAYSHADOW */
|
||||||
SAMPLER2DMS = 467,
|
F16SAMPLER2DRECTSHADOW = 463, /* F16SAMPLER2DRECTSHADOW */
|
||||||
ISAMPLER2DMS = 468,
|
F16SAMPLERCUBESHADOW = 464, /* F16SAMPLERCUBESHADOW */
|
||||||
USAMPLER2DMS = 469,
|
F16SAMPLERCUBEARRAYSHADOW = 465, /* F16SAMPLERCUBEARRAYSHADOW */
|
||||||
SAMPLER2DMSARRAY = 470,
|
IMAGE1D = 466, /* IMAGE1D */
|
||||||
ISAMPLER2DMSARRAY = 471,
|
IIMAGE1D = 467, /* IIMAGE1D */
|
||||||
USAMPLER2DMSARRAY = 472,
|
UIMAGE1D = 468, /* UIMAGE1D */
|
||||||
SAMPLEREXTERNALOES = 473,
|
IMAGE2D = 469, /* IMAGE2D */
|
||||||
SAMPLEREXTERNAL2DY2YEXT = 474,
|
IIMAGE2D = 470, /* IIMAGE2D */
|
||||||
F16SAMPLER1D = 475,
|
UIMAGE2D = 471, /* UIMAGE2D */
|
||||||
F16SAMPLER2D = 476,
|
IMAGE3D = 472, /* IMAGE3D */
|
||||||
F16SAMPLER3D = 477,
|
IIMAGE3D = 473, /* IIMAGE3D */
|
||||||
F16SAMPLER2DRECT = 478,
|
UIMAGE3D = 474, /* UIMAGE3D */
|
||||||
F16SAMPLERCUBE = 479,
|
IMAGE2DRECT = 475, /* IMAGE2DRECT */
|
||||||
F16SAMPLER1DARRAY = 480,
|
IIMAGE2DRECT = 476, /* IIMAGE2DRECT */
|
||||||
F16SAMPLER2DARRAY = 481,
|
UIMAGE2DRECT = 477, /* UIMAGE2DRECT */
|
||||||
F16SAMPLERCUBEARRAY = 482,
|
IMAGECUBE = 478, /* IMAGECUBE */
|
||||||
F16SAMPLERBUFFER = 483,
|
IIMAGECUBE = 479, /* IIMAGECUBE */
|
||||||
F16SAMPLER2DMS = 484,
|
UIMAGECUBE = 480, /* UIMAGECUBE */
|
||||||
F16SAMPLER2DMSARRAY = 485,
|
IMAGEBUFFER = 481, /* IMAGEBUFFER */
|
||||||
F16SAMPLER1DSHADOW = 486,
|
IIMAGEBUFFER = 482, /* IIMAGEBUFFER */
|
||||||
F16SAMPLER2DSHADOW = 487,
|
UIMAGEBUFFER = 483, /* UIMAGEBUFFER */
|
||||||
F16SAMPLER1DARRAYSHADOW = 488,
|
IMAGE1DARRAY = 484, /* IMAGE1DARRAY */
|
||||||
F16SAMPLER2DARRAYSHADOW = 489,
|
IIMAGE1DARRAY = 485, /* IIMAGE1DARRAY */
|
||||||
F16SAMPLER2DRECTSHADOW = 490,
|
UIMAGE1DARRAY = 486, /* UIMAGE1DARRAY */
|
||||||
F16SAMPLERCUBESHADOW = 491,
|
IMAGE2DARRAY = 487, /* IMAGE2DARRAY */
|
||||||
F16SAMPLERCUBEARRAYSHADOW = 492,
|
IIMAGE2DARRAY = 488, /* IIMAGE2DARRAY */
|
||||||
SAMPLER = 493,
|
UIMAGE2DARRAY = 489, /* UIMAGE2DARRAY */
|
||||||
SAMPLERSHADOW = 494,
|
IMAGECUBEARRAY = 490, /* IMAGECUBEARRAY */
|
||||||
TEXTURE1D = 495,
|
IIMAGECUBEARRAY = 491, /* IIMAGECUBEARRAY */
|
||||||
TEXTURE2D = 496,
|
UIMAGECUBEARRAY = 492, /* UIMAGECUBEARRAY */
|
||||||
TEXTURE3D = 497,
|
IMAGE2DMS = 493, /* IMAGE2DMS */
|
||||||
TEXTURECUBE = 498,
|
IIMAGE2DMS = 494, /* IIMAGE2DMS */
|
||||||
TEXTURE1DARRAY = 499,
|
UIMAGE2DMS = 495, /* UIMAGE2DMS */
|
||||||
TEXTURE2DARRAY = 500,
|
IMAGE2DMSARRAY = 496, /* IMAGE2DMSARRAY */
|
||||||
ITEXTURE1D = 501,
|
IIMAGE2DMSARRAY = 497, /* IIMAGE2DMSARRAY */
|
||||||
ITEXTURE2D = 502,
|
UIMAGE2DMSARRAY = 498, /* UIMAGE2DMSARRAY */
|
||||||
ITEXTURE3D = 503,
|
F16IMAGE1D = 499, /* F16IMAGE1D */
|
||||||
ITEXTURECUBE = 504,
|
F16IMAGE2D = 500, /* F16IMAGE2D */
|
||||||
ITEXTURE1DARRAY = 505,
|
F16IMAGE3D = 501, /* F16IMAGE3D */
|
||||||
ITEXTURE2DARRAY = 506,
|
F16IMAGE2DRECT = 502, /* F16IMAGE2DRECT */
|
||||||
UTEXTURE1D = 507,
|
F16IMAGECUBE = 503, /* F16IMAGECUBE */
|
||||||
UTEXTURE2D = 508,
|
F16IMAGE1DARRAY = 504, /* F16IMAGE1DARRAY */
|
||||||
UTEXTURE3D = 509,
|
F16IMAGE2DARRAY = 505, /* F16IMAGE2DARRAY */
|
||||||
UTEXTURECUBE = 510,
|
F16IMAGECUBEARRAY = 506, /* F16IMAGECUBEARRAY */
|
||||||
UTEXTURE1DARRAY = 511,
|
F16IMAGEBUFFER = 507, /* F16IMAGEBUFFER */
|
||||||
UTEXTURE2DARRAY = 512,
|
F16IMAGE2DMS = 508, /* F16IMAGE2DMS */
|
||||||
TEXTURE2DRECT = 513,
|
F16IMAGE2DMSARRAY = 509, /* F16IMAGE2DMSARRAY */
|
||||||
ITEXTURE2DRECT = 514,
|
I64IMAGE1D = 510, /* I64IMAGE1D */
|
||||||
UTEXTURE2DRECT = 515,
|
U64IMAGE1D = 511, /* U64IMAGE1D */
|
||||||
TEXTUREBUFFER = 516,
|
I64IMAGE2D = 512, /* I64IMAGE2D */
|
||||||
ITEXTUREBUFFER = 517,
|
U64IMAGE2D = 513, /* U64IMAGE2D */
|
||||||
UTEXTUREBUFFER = 518,
|
I64IMAGE3D = 514, /* I64IMAGE3D */
|
||||||
TEXTURECUBEARRAY = 519,
|
U64IMAGE3D = 515, /* U64IMAGE3D */
|
||||||
ITEXTURECUBEARRAY = 520,
|
I64IMAGE2DRECT = 516, /* I64IMAGE2DRECT */
|
||||||
UTEXTURECUBEARRAY = 521,
|
U64IMAGE2DRECT = 517, /* U64IMAGE2DRECT */
|
||||||
TEXTURE2DMS = 522,
|
I64IMAGECUBE = 518, /* I64IMAGECUBE */
|
||||||
ITEXTURE2DMS = 523,
|
U64IMAGECUBE = 519, /* U64IMAGECUBE */
|
||||||
UTEXTURE2DMS = 524,
|
I64IMAGEBUFFER = 520, /* I64IMAGEBUFFER */
|
||||||
TEXTURE2DMSARRAY = 525,
|
U64IMAGEBUFFER = 521, /* U64IMAGEBUFFER */
|
||||||
ITEXTURE2DMSARRAY = 526,
|
I64IMAGE1DARRAY = 522, /* I64IMAGE1DARRAY */
|
||||||
UTEXTURE2DMSARRAY = 527,
|
U64IMAGE1DARRAY = 523, /* U64IMAGE1DARRAY */
|
||||||
F16TEXTURE1D = 528,
|
I64IMAGE2DARRAY = 524, /* I64IMAGE2DARRAY */
|
||||||
F16TEXTURE2D = 529,
|
U64IMAGE2DARRAY = 525, /* U64IMAGE2DARRAY */
|
||||||
F16TEXTURE3D = 530,
|
I64IMAGECUBEARRAY = 526, /* I64IMAGECUBEARRAY */
|
||||||
F16TEXTURE2DRECT = 531,
|
U64IMAGECUBEARRAY = 527, /* U64IMAGECUBEARRAY */
|
||||||
F16TEXTURECUBE = 532,
|
I64IMAGE2DMS = 528, /* I64IMAGE2DMS */
|
||||||
F16TEXTURE1DARRAY = 533,
|
U64IMAGE2DMS = 529, /* U64IMAGE2DMS */
|
||||||
F16TEXTURE2DARRAY = 534,
|
I64IMAGE2DMSARRAY = 530, /* I64IMAGE2DMSARRAY */
|
||||||
F16TEXTURECUBEARRAY = 535,
|
U64IMAGE2DMSARRAY = 531, /* U64IMAGE2DMSARRAY */
|
||||||
F16TEXTUREBUFFER = 536,
|
TEXTURECUBEARRAY = 532, /* TEXTURECUBEARRAY */
|
||||||
F16TEXTURE2DMS = 537,
|
ITEXTURECUBEARRAY = 533, /* ITEXTURECUBEARRAY */
|
||||||
F16TEXTURE2DMSARRAY = 538,
|
UTEXTURECUBEARRAY = 534, /* UTEXTURECUBEARRAY */
|
||||||
SUBPASSINPUT = 539,
|
TEXTURE1D = 535, /* TEXTURE1D */
|
||||||
SUBPASSINPUTMS = 540,
|
ITEXTURE1D = 536, /* ITEXTURE1D */
|
||||||
ISUBPASSINPUT = 541,
|
UTEXTURE1D = 537, /* UTEXTURE1D */
|
||||||
ISUBPASSINPUTMS = 542,
|
TEXTURE1DARRAY = 538, /* TEXTURE1DARRAY */
|
||||||
USUBPASSINPUT = 543,
|
ITEXTURE1DARRAY = 539, /* ITEXTURE1DARRAY */
|
||||||
USUBPASSINPUTMS = 544,
|
UTEXTURE1DARRAY = 540, /* UTEXTURE1DARRAY */
|
||||||
F16SUBPASSINPUT = 545,
|
TEXTURE2DRECT = 541, /* TEXTURE2DRECT */
|
||||||
F16SUBPASSINPUTMS = 546,
|
ITEXTURE2DRECT = 542, /* ITEXTURE2DRECT */
|
||||||
IMAGE1D = 547,
|
UTEXTURE2DRECT = 543, /* UTEXTURE2DRECT */
|
||||||
IIMAGE1D = 548,
|
TEXTUREBUFFER = 544, /* TEXTUREBUFFER */
|
||||||
UIMAGE1D = 549,
|
ITEXTUREBUFFER = 545, /* ITEXTUREBUFFER */
|
||||||
IMAGE2D = 550,
|
UTEXTUREBUFFER = 546, /* UTEXTUREBUFFER */
|
||||||
IIMAGE2D = 551,
|
TEXTURE2DMS = 547, /* TEXTURE2DMS */
|
||||||
UIMAGE2D = 552,
|
ITEXTURE2DMS = 548, /* ITEXTURE2DMS */
|
||||||
IMAGE3D = 553,
|
UTEXTURE2DMS = 549, /* UTEXTURE2DMS */
|
||||||
IIMAGE3D = 554,
|
TEXTURE2DMSARRAY = 550, /* TEXTURE2DMSARRAY */
|
||||||
UIMAGE3D = 555,
|
ITEXTURE2DMSARRAY = 551, /* ITEXTURE2DMSARRAY */
|
||||||
IMAGE2DRECT = 556,
|
UTEXTURE2DMSARRAY = 552, /* UTEXTURE2DMSARRAY */
|
||||||
IIMAGE2DRECT = 557,
|
F16TEXTURE1D = 553, /* F16TEXTURE1D */
|
||||||
UIMAGE2DRECT = 558,
|
F16TEXTURE2D = 554, /* F16TEXTURE2D */
|
||||||
IMAGECUBE = 559,
|
F16TEXTURE3D = 555, /* F16TEXTURE3D */
|
||||||
IIMAGECUBE = 560,
|
F16TEXTURE2DRECT = 556, /* F16TEXTURE2DRECT */
|
||||||
UIMAGECUBE = 561,
|
F16TEXTURECUBE = 557, /* F16TEXTURECUBE */
|
||||||
IMAGEBUFFER = 562,
|
F16TEXTURE1DARRAY = 558, /* F16TEXTURE1DARRAY */
|
||||||
IIMAGEBUFFER = 563,
|
F16TEXTURE2DARRAY = 559, /* F16TEXTURE2DARRAY */
|
||||||
UIMAGEBUFFER = 564,
|
F16TEXTURECUBEARRAY = 560, /* F16TEXTURECUBEARRAY */
|
||||||
IMAGE1DARRAY = 565,
|
F16TEXTUREBUFFER = 561, /* F16TEXTUREBUFFER */
|
||||||
IIMAGE1DARRAY = 566,
|
F16TEXTURE2DMS = 562, /* F16TEXTURE2DMS */
|
||||||
UIMAGE1DARRAY = 567,
|
F16TEXTURE2DMSARRAY = 563, /* F16TEXTURE2DMSARRAY */
|
||||||
IMAGE2DARRAY = 568,
|
SUBPASSINPUT = 564, /* SUBPASSINPUT */
|
||||||
IIMAGE2DARRAY = 569,
|
SUBPASSINPUTMS = 565, /* SUBPASSINPUTMS */
|
||||||
UIMAGE2DARRAY = 570,
|
ISUBPASSINPUT = 566, /* ISUBPASSINPUT */
|
||||||
IMAGECUBEARRAY = 571,
|
ISUBPASSINPUTMS = 567, /* ISUBPASSINPUTMS */
|
||||||
IIMAGECUBEARRAY = 572,
|
USUBPASSINPUT = 568, /* USUBPASSINPUT */
|
||||||
UIMAGECUBEARRAY = 573,
|
USUBPASSINPUTMS = 569, /* USUBPASSINPUTMS */
|
||||||
IMAGE2DMS = 574,
|
F16SUBPASSINPUT = 570, /* F16SUBPASSINPUT */
|
||||||
IIMAGE2DMS = 575,
|
F16SUBPASSINPUTMS = 571, /* F16SUBPASSINPUTMS */
|
||||||
UIMAGE2DMS = 576,
|
SPIRV_INSTRUCTION = 572, /* SPIRV_INSTRUCTION */
|
||||||
IMAGE2DMSARRAY = 577,
|
SPIRV_EXECUTION_MODE = 573, /* SPIRV_EXECUTION_MODE */
|
||||||
IIMAGE2DMSARRAY = 578,
|
SPIRV_EXECUTION_MODE_ID = 574, /* SPIRV_EXECUTION_MODE_ID */
|
||||||
UIMAGE2DMSARRAY = 579,
|
SPIRV_DECORATE = 575, /* SPIRV_DECORATE */
|
||||||
F16IMAGE1D = 580,
|
SPIRV_DECORATE_ID = 576, /* SPIRV_DECORATE_ID */
|
||||||
F16IMAGE2D = 581,
|
SPIRV_DECORATE_STRING = 577, /* SPIRV_DECORATE_STRING */
|
||||||
F16IMAGE3D = 582,
|
SPIRV_TYPE = 578, /* SPIRV_TYPE */
|
||||||
F16IMAGE2DRECT = 583,
|
SPIRV_STORAGE_CLASS = 579, /* SPIRV_STORAGE_CLASS */
|
||||||
F16IMAGECUBE = 584,
|
SPIRV_BY_REFERENCE = 580, /* SPIRV_BY_REFERENCE */
|
||||||
F16IMAGE1DARRAY = 585,
|
SPIRV_LITERAL = 581, /* SPIRV_LITERAL */
|
||||||
F16IMAGE2DARRAY = 586,
|
LEFT_OP = 582, /* LEFT_OP */
|
||||||
F16IMAGECUBEARRAY = 587,
|
RIGHT_OP = 583, /* RIGHT_OP */
|
||||||
F16IMAGEBUFFER = 588,
|
INC_OP = 584, /* INC_OP */
|
||||||
F16IMAGE2DMS = 589,
|
DEC_OP = 585, /* DEC_OP */
|
||||||
F16IMAGE2DMSARRAY = 590,
|
LE_OP = 586, /* LE_OP */
|
||||||
STRUCT = 591,
|
GE_OP = 587, /* GE_OP */
|
||||||
VOID = 592,
|
EQ_OP = 588, /* EQ_OP */
|
||||||
WHILE = 593,
|
NE_OP = 589, /* NE_OP */
|
||||||
IDENTIFIER = 594,
|
AND_OP = 590, /* AND_OP */
|
||||||
TYPE_NAME = 595,
|
OR_OP = 591, /* OR_OP */
|
||||||
FLOATCONSTANT = 596,
|
XOR_OP = 592, /* XOR_OP */
|
||||||
DOUBLECONSTANT = 597,
|
MUL_ASSIGN = 593, /* MUL_ASSIGN */
|
||||||
INT16CONSTANT = 598,
|
DIV_ASSIGN = 594, /* DIV_ASSIGN */
|
||||||
UINT16CONSTANT = 599,
|
ADD_ASSIGN = 595, /* ADD_ASSIGN */
|
||||||
INT32CONSTANT = 600,
|
MOD_ASSIGN = 596, /* MOD_ASSIGN */
|
||||||
UINT32CONSTANT = 601,
|
LEFT_ASSIGN = 597, /* LEFT_ASSIGN */
|
||||||
INTCONSTANT = 602,
|
RIGHT_ASSIGN = 598, /* RIGHT_ASSIGN */
|
||||||
UINTCONSTANT = 603,
|
AND_ASSIGN = 599, /* AND_ASSIGN */
|
||||||
INT64CONSTANT = 604,
|
XOR_ASSIGN = 600, /* XOR_ASSIGN */
|
||||||
UINT64CONSTANT = 605,
|
OR_ASSIGN = 601, /* OR_ASSIGN */
|
||||||
BOOLCONSTANT = 606,
|
SUB_ASSIGN = 602, /* SUB_ASSIGN */
|
||||||
FLOAT16CONSTANT = 607,
|
STRING_LITERAL = 603, /* STRING_LITERAL */
|
||||||
LEFT_OP = 608,
|
LEFT_PAREN = 604, /* LEFT_PAREN */
|
||||||
RIGHT_OP = 609,
|
RIGHT_PAREN = 605, /* RIGHT_PAREN */
|
||||||
INC_OP = 610,
|
LEFT_BRACKET = 606, /* LEFT_BRACKET */
|
||||||
DEC_OP = 611,
|
RIGHT_BRACKET = 607, /* RIGHT_BRACKET */
|
||||||
LE_OP = 612,
|
LEFT_BRACE = 608, /* LEFT_BRACE */
|
||||||
GE_OP = 613,
|
RIGHT_BRACE = 609, /* RIGHT_BRACE */
|
||||||
EQ_OP = 614,
|
DOT = 610, /* DOT */
|
||||||
NE_OP = 615,
|
COMMA = 611, /* COMMA */
|
||||||
AND_OP = 616,
|
COLON = 612, /* COLON */
|
||||||
OR_OP = 617,
|
EQUAL = 613, /* EQUAL */
|
||||||
XOR_OP = 618,
|
SEMICOLON = 614, /* SEMICOLON */
|
||||||
MUL_ASSIGN = 619,
|
BANG = 615, /* BANG */
|
||||||
DIV_ASSIGN = 620,
|
DASH = 616, /* DASH */
|
||||||
ADD_ASSIGN = 621,
|
TILDE = 617, /* TILDE */
|
||||||
MOD_ASSIGN = 622,
|
PLUS = 618, /* PLUS */
|
||||||
LEFT_ASSIGN = 623,
|
STAR = 619, /* STAR */
|
||||||
RIGHT_ASSIGN = 624,
|
SLASH = 620, /* SLASH */
|
||||||
AND_ASSIGN = 625,
|
PERCENT = 621, /* PERCENT */
|
||||||
XOR_ASSIGN = 626,
|
LEFT_ANGLE = 622, /* LEFT_ANGLE */
|
||||||
OR_ASSIGN = 627,
|
RIGHT_ANGLE = 623, /* RIGHT_ANGLE */
|
||||||
SUB_ASSIGN = 628,
|
VERTICAL_BAR = 624, /* VERTICAL_BAR */
|
||||||
LEFT_PAREN = 629,
|
CARET = 625, /* CARET */
|
||||||
RIGHT_PAREN = 630,
|
AMPERSAND = 626, /* AMPERSAND */
|
||||||
LEFT_BRACKET = 631,
|
QUESTION = 627, /* QUESTION */
|
||||||
RIGHT_BRACKET = 632,
|
INVARIANT = 628, /* INVARIANT */
|
||||||
LEFT_BRACE = 633,
|
HIGH_PRECISION = 629, /* HIGH_PRECISION */
|
||||||
RIGHT_BRACE = 634,
|
MEDIUM_PRECISION = 630, /* MEDIUM_PRECISION */
|
||||||
DOT = 635,
|
LOW_PRECISION = 631, /* LOW_PRECISION */
|
||||||
COMMA = 636,
|
PRECISION = 632, /* PRECISION */
|
||||||
COLON = 637,
|
PACKED = 633, /* PACKED */
|
||||||
EQUAL = 638,
|
RESOURCE = 634, /* RESOURCE */
|
||||||
SEMICOLON = 639,
|
SUPERP = 635, /* SUPERP */
|
||||||
BANG = 640,
|
FLOATCONSTANT = 636, /* FLOATCONSTANT */
|
||||||
DASH = 641,
|
INTCONSTANT = 637, /* INTCONSTANT */
|
||||||
TILDE = 642,
|
UINTCONSTANT = 638, /* UINTCONSTANT */
|
||||||
PLUS = 643,
|
BOOLCONSTANT = 639, /* BOOLCONSTANT */
|
||||||
STAR = 644,
|
IDENTIFIER = 640, /* IDENTIFIER */
|
||||||
SLASH = 645,
|
TYPE_NAME = 641, /* TYPE_NAME */
|
||||||
PERCENT = 646,
|
CENTROID = 642, /* CENTROID */
|
||||||
LEFT_ANGLE = 647,
|
IN = 643, /* IN */
|
||||||
RIGHT_ANGLE = 648,
|
OUT = 644, /* OUT */
|
||||||
VERTICAL_BAR = 649,
|
INOUT = 645, /* INOUT */
|
||||||
CARET = 650,
|
STRUCT = 646, /* STRUCT */
|
||||||
AMPERSAND = 651,
|
VOID = 647, /* VOID */
|
||||||
QUESTION = 652,
|
WHILE = 648, /* WHILE */
|
||||||
INVARIANT = 653,
|
BREAK = 649, /* BREAK */
|
||||||
PRECISE = 654,
|
CONTINUE = 650, /* CONTINUE */
|
||||||
HIGH_PRECISION = 655,
|
DO = 651, /* DO */
|
||||||
MEDIUM_PRECISION = 656,
|
ELSE = 652, /* ELSE */
|
||||||
LOW_PRECISION = 657,
|
FOR = 653, /* FOR */
|
||||||
PRECISION = 658,
|
IF = 654, /* IF */
|
||||||
PACKED = 659,
|
DISCARD = 655, /* DISCARD */
|
||||||
RESOURCE = 660,
|
RETURN = 656, /* RETURN */
|
||||||
SUPERP = 661
|
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
|
#endif
|
||||||
|
|
||||||
/* Value type. */
|
/* Value type. */
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
|
|
||||||
union YYSTYPE
|
union YYSTYPE
|
||||||
{
|
{
|
||||||
#line 71 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
#line 97 "MachineIndependent/glslang.y"
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
glslang::TSourceLoc loc;
|
glslang::TSourceLoc loc;
|
||||||
|
@ -480,6 +537,9 @@ union YYSTYPE
|
||||||
glslang::TIntermNodePair nodePair;
|
glslang::TIntermNodePair nodePair;
|
||||||
glslang::TIntermTyped* intermTypedNode;
|
glslang::TIntermTyped* intermTypedNode;
|
||||||
glslang::TAttributes* attributes;
|
glslang::TAttributes* attributes;
|
||||||
|
glslang::TSpirvRequirement* spirvReq;
|
||||||
|
glslang::TSpirvInstruction* spirvInst;
|
||||||
|
glslang::TSpirvTypeParameters* spirvTypeParams;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
glslang::TPublicType type;
|
glslang::TPublicType type;
|
||||||
|
@ -490,11 +550,12 @@ union YYSTYPE
|
||||||
glslang::TArraySizes* arraySizes;
|
glslang::TArraySizes* arraySizes;
|
||||||
glslang::TIdentifierList* identifierList;
|
glslang::TIdentifierList* identifierList;
|
||||||
};
|
};
|
||||||
|
glslang::TArraySizes* typeParameters;
|
||||||
} interm;
|
} interm;
|
||||||
|
|
||||||
#line 496 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
#line 557 "MachineIndependent/glslang_tab.cpp.h"
|
||||||
};
|
|
||||||
|
|
||||||
|
};
|
||||||
typedef union YYSTYPE YYSTYPE;
|
typedef union YYSTYPE YYSTYPE;
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2016 LunarG, Inc.
|
// Copyright (C) 2012-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -35,6 +36,8 @@
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
#include "../Include/InfoSink.h"
|
#include "../Include/InfoSink.h"
|
||||||
|
|
||||||
|
@ -43,6 +46,7 @@
|
||||||
#else
|
#else
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#endif
|
#endif
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -173,7 +177,7 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
||||||
case EOpIndexIndirect: out.debug << "indirect index"; break;
|
case EOpIndexIndirect: out.debug << "indirect index"; break;
|
||||||
case EOpIndexDirectStruct:
|
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();
|
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 << (*members)[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
|
||||||
out.debug << ": direct index for structure"; break;
|
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 EOpLogicalXor: out.debug << "logical-xor"; break;
|
||||||
case EOpLogicalAnd: out.debug << "logical-and"; 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 << "<unknown op>";
|
default: out.debug << "<unknown op>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,6 +247,7 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||||
case EOpPostDecrement: out.debug << "Post-Decrement"; break;
|
case EOpPostDecrement: out.debug << "Post-Decrement"; break;
|
||||||
case EOpPreIncrement: out.debug << "Pre-Increment"; break;
|
case EOpPreIncrement: out.debug << "Pre-Increment"; break;
|
||||||
case EOpPreDecrement: out.debug << "Pre-Decrement"; break;
|
case EOpPreDecrement: out.debug << "Pre-Decrement"; break;
|
||||||
|
case EOpCopyObject: out.debug << "copy object"; break;
|
||||||
|
|
||||||
// * -> bool
|
// * -> bool
|
||||||
case EOpConvInt8ToBool: out.debug << "Convert int8_t to bool"; break;
|
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 EOpConvUint64ToPtr: out.debug << "Convert uint64_t to pointer"; break;
|
||||||
case EOpConvPtrToUint64: out.debug << "Convert pointer to uint64_t"; 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 EOpRadians: out.debug << "radians"; break;
|
||||||
case EOpDegrees: out.debug << "degrees"; break;
|
case EOpDegrees: out.debug << "degrees"; break;
|
||||||
case EOpSin: out.debug << "sine"; 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 EOpFindLSB: out.debug << "findLSB"; break;
|
||||||
case EOpFindMSB: out.debug << "findMSB"; 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 EOpNoise: out.debug << "noise"; break;
|
||||||
|
|
||||||
case EOpBallot: out.debug << "ballot"; 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 EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
||||||
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
||||||
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
||||||
case EOpSubgroupPartitionedMul: out.debug << "subgroupPartitionedMulNV"; 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 EOpSubgroupPartitionedExclusiveAnd: out.debug << "subgroupPartitionedExclusiveAndNV"; break;
|
||||||
case EOpSubgroupPartitionedExclusiveOr: out.debug << "subgroupPartitionedExclusiveOrNV"; break;
|
case EOpSubgroupPartitionedExclusiveOr: out.debug << "subgroupPartitionedExclusiveOrNV"; break;
|
||||||
case EOpSubgroupPartitionedExclusiveXor: out.debug << "subgroupPartitionedExclusiveXorNV"; break;
|
case EOpSubgroupPartitionedExclusiveXor: out.debug << "subgroupPartitionedExclusiveXorNV"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpClip: out.debug << "clip"; break;
|
case EOpClip: out.debug << "clip"; break;
|
||||||
case EOpIsFinite: out.debug << "isfinite"; break;
|
case EOpIsFinite: out.debug << "isfinite"; break;
|
||||||
|
@ -646,7 +662,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||||
|
|
||||||
case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break;
|
case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpMinInvocations: out.debug << "minInvocations"; break;
|
case EOpMinInvocations: out.debug << "minInvocations"; break;
|
||||||
case EOpMaxInvocations: out.debug << "maxInvocations"; break;
|
case EOpMaxInvocations: out.debug << "maxInvocations"; break;
|
||||||
case EOpAddInvocations: out.debug << "addInvocations"; 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 EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break;
|
||||||
case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break;
|
case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
|
|
||||||
case EOpConstructReference: out.debug << "Construct reference type"; 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");
|
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 EOpConstructStruct: out.debug << "Construct structure"; break;
|
||||||
case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
|
case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
|
||||||
case EOpConstructReference: out.debug << "Construct reference"; 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 EOpLessThan: out.debug << "Compare Less Than"; break;
|
||||||
case EOpGreaterThan: out.debug << "Compare Greater 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;
|
case EOpReadInvocation: out.debug << "readInvocation"; break;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpSwizzleInvocations: out.debug << "swizzleInvocations"; break;
|
case EOpSwizzleInvocations: out.debug << "swizzleInvocations"; break;
|
||||||
case EOpSwizzleInvocationsMasked: out.debug << "swizzleInvocationsMasked"; break;
|
case EOpSwizzleInvocationsMasked: out.debug << "swizzleInvocationsMasked"; break;
|
||||||
case EOpWriteInvocation: out.debug << "writeInvocation"; 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 EOpMin3: out.debug << "min3"; break;
|
||||||
case EOpMax3: out.debug << "max3"; break;
|
case EOpMax3: out.debug << "max3"; break;
|
||||||
case EOpMid3: out.debug << "mid3"; break;
|
case EOpMid3: out.debug << "mid3"; break;
|
||||||
|
|
||||||
case EOpTime: out.debug << "time"; break;
|
case EOpTime: out.debug << "time"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpAtomicAdd: out.debug << "AtomicAdd"; break;
|
case EOpAtomicAdd: out.debug << "AtomicAdd"; break;
|
||||||
|
case EOpAtomicSubtract: out.debug << "AtomicSubtract"; break;
|
||||||
case EOpAtomicMin: out.debug << "AtomicMin"; break;
|
case EOpAtomicMin: out.debug << "AtomicMin"; break;
|
||||||
case EOpAtomicMax: out.debug << "AtomicMax"; break;
|
case EOpAtomicMax: out.debug << "AtomicMax"; break;
|
||||||
case EOpAtomicAnd: out.debug << "AtomicAnd"; 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 EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break;
|
||||||
case EOpImageAtomicLoad: out.debug << "imageAtomicLoad"; break;
|
case EOpImageAtomicLoad: out.debug << "imageAtomicLoad"; break;
|
||||||
case EOpImageAtomicStore: out.debug << "imageAtomicStore"; break;
|
case EOpImageAtomicStore: out.debug << "imageAtomicStore"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpImageLoadLod: out.debug << "imageLoadLod"; break;
|
case EOpImageLoadLod: out.debug << "imageLoadLod"; break;
|
||||||
case EOpImageStoreLod: out.debug << "imageStoreLod"; break;
|
case EOpImageStoreLod: out.debug << "imageStoreLod"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpTextureQuerySize: out.debug << "textureSize"; break;
|
case EOpTextureQuerySize: out.debug << "textureSize"; break;
|
||||||
case EOpTextureQueryLod: out.debug << "textureQueryLod"; 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 EOpTextureOffsetClamp: out.debug << "textureOffsetClamp"; break;
|
||||||
case EOpTextureGradClamp: out.debug << "textureGradClamp"; break;
|
case EOpTextureGradClamp: out.debug << "textureGradClamp"; break;
|
||||||
case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break;
|
case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpTextureGatherLod: out.debug << "textureGatherLod"; break;
|
case EOpTextureGatherLod: out.debug << "textureGatherLod"; break;
|
||||||
case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break;
|
case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break;
|
||||||
case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break;
|
case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpSparseTexture: out.debug << "sparseTexture"; break;
|
case EOpSparseTexture: out.debug << "sparseTexture"; break;
|
||||||
case EOpSparseTextureOffset: out.debug << "sparseTextureOffset"; 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 EOpSparseTextureOffsetClamp: out.debug << "sparseTextureOffsetClamp"; break;
|
||||||
case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break;
|
case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break;
|
||||||
case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break;
|
case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break;
|
case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break;
|
||||||
case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break;
|
case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break;
|
||||||
case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break;
|
case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break;
|
||||||
case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break;
|
case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break;
|
||||||
#endif
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EOpImageSampleFootprintNV: out.debug << "imageSampleFootprintNV"; break;
|
case EOpImageSampleFootprintNV: out.debug << "imageSampleFootprintNV"; break;
|
||||||
case EOpImageSampleFootprintClampNV: out.debug << "imageSampleFootprintClampNV"; break;
|
case EOpImageSampleFootprintClampNV: out.debug << "imageSampleFootprintClampNV"; break;
|
||||||
case EOpImageSampleFootprintLodNV: out.debug << "imageSampleFootprintLodNV"; break;
|
case EOpImageSampleFootprintLodNV: out.debug << "imageSampleFootprintLodNV"; break;
|
||||||
case EOpImageSampleFootprintGradNV: out.debug << "imageSampleFootprintGradNV"; break;
|
case EOpImageSampleFootprintGradNV: out.debug << "imageSampleFootprintGradNV"; break;
|
||||||
case EOpImageSampleFootprintGradClampNV: out.debug << "mageSampleFootprintGradClampNV"; break;
|
case EOpImageSampleFootprintGradClampNV: out.debug << "mageSampleFootprintGradClampNV"; break;
|
||||||
#endif
|
|
||||||
case EOpAddCarry: out.debug << "addCarry"; break;
|
case EOpAddCarry: out.debug << "addCarry"; break;
|
||||||
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
||||||
case EOpUMulExtended: out.debug << "uMulExtended"; 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 EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break;
|
||||||
case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break;
|
case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpInterpolateAtVertex: out.debug << "interpolateAtVertex"; break;
|
case EOpInterpolateAtVertex: out.debug << "interpolateAtVertex"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpSinCos: out.debug << "sincos"; break;
|
case EOpSinCos: out.debug << "sincos"; break;
|
||||||
case EOpGenMul: out.debug << "mul"; 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 EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
||||||
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; 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 EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EOpTraceNV: out.debug << "traceNV"; break;
|
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 EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break;
|
||||||
|
case EOpIgnoreIntersectionKHR: out.debug << "ignoreIntersectionKHR"; break;
|
||||||
case EOpTerminateRayNV: out.debug << "terminateRayNV"; break;
|
case EOpTerminateRayNV: out.debug << "terminateRayNV"; break;
|
||||||
|
case EOpTerminateRayKHR: out.debug << "terminateRayKHR"; break;
|
||||||
case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break;
|
case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break;
|
||||||
|
case EOpExecuteCallableKHR: out.debug << "executeCallableKHR"; break;
|
||||||
case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; 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
|
#endif
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
||||||
|
@ -1157,8 +1226,11 @@ static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraO
|
||||||
switch (extra) {
|
switch (extra) {
|
||||||
case TOutputTraverser::BinaryDoubleOutput:
|
case TOutputTraverser::BinaryDoubleOutput:
|
||||||
{
|
{
|
||||||
|
uint64_t b;
|
||||||
|
static_assert(sizeof(b) == sizeof(value), "sizeof(uint64_t) != sizeof(double)");
|
||||||
|
memcpy(&b, &value, sizeof(b));
|
||||||
|
|
||||||
out.debug << " : ";
|
out.debug << " : ";
|
||||||
long long b = *reinterpret_cast<long long*>(&value);
|
|
||||||
for (size_t i = 0; i < 8 * sizeof(value); ++i, ++b) {
|
for (size_t i = 0; i < 8 * sizeof(value); ++i, ++b) {
|
||||||
out.debug << ((b & 0x8000000000000000) != 0 ? "1" : "0");
|
out.debug << ((b & 0x8000000000000000) != 0 ? "1" : "0");
|
||||||
b <<= 1;
|
b <<= 1;
|
||||||
|
@ -1267,6 +1339,9 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
|
||||||
out.debug << buf << "\n";
|
out.debug << buf << "\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EbtString:
|
||||||
|
out.debug << "\"" << constUnion[i].getSConst()->c_str() << "\"\n";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
|
out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
|
||||||
break;
|
break;
|
||||||
|
@ -1353,10 +1428,14 @@ bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node)
|
||||||
|
|
||||||
switch (node->getFlowOp()) {
|
switch (node->getFlowOp()) {
|
||||||
case EOpKill: out.debug << "Branch: Kill"; 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 EOpBreak: out.debug << "Branch: Break"; break;
|
||||||
case EOpContinue: out.debug << "Branch: Continue"; break;
|
case EOpContinue: out.debug << "Branch: Continue"; break;
|
||||||
case EOpReturn: out.debug << "Branch: Return"; break;
|
case EOpReturn: out.debug << "Branch: Return"; break;
|
||||||
case EOpCase: out.debug << "case: "; break;
|
case EOpCase: out.debug << "case: "; break;
|
||||||
|
case EOpDemote: out.debug << "Demote"; break;
|
||||||
case EOpDefault: out.debug << "default: "; break;
|
case EOpDefault: out.debug << "default: "; break;
|
||||||
default: out.debug << "Branch: Unknown Branch"; break;
|
default: out.debug << "Branch: Unknown Branch"; break;
|
||||||
}
|
}
|
||||||
|
@ -1417,6 +1496,9 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
||||||
if (xfbMode)
|
if (xfbMode)
|
||||||
infoSink.debug << "in xfb mode\n";
|
infoSink.debug << "in xfb mode\n";
|
||||||
|
|
||||||
|
if (getSubgroupUniformControlFlow())
|
||||||
|
infoSink.debug << "subgroup_uniform_control_flow\n";
|
||||||
|
|
||||||
switch (language) {
|
switch (language) {
|
||||||
case EShLangVertex:
|
case EShLangVertex:
|
||||||
break;
|
break;
|
||||||
|
@ -1467,18 +1549,17 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
||||||
}
|
}
|
||||||
infoSink.debug << "\n";
|
infoSink.debug << "\n";
|
||||||
}
|
}
|
||||||
|
if (interlockOrdering != EioNone)
|
||||||
|
infoSink.debug << "interlock ordering = " << TQualifier::getInterlockOrderingString(interlockOrdering) << "\n";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EShLangMeshNV:
|
case EShLangMeshNV:
|
||||||
infoSink.debug << "max_vertices = " << vertices << "\n";
|
infoSink.debug << "max_vertices = " << vertices << "\n";
|
||||||
infoSink.debug << "max_primitives = " << primitives << "\n";
|
infoSink.debug << "max_primitives = " << primitives << "\n";
|
||||||
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
|
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
|
||||||
// Fall through
|
// Fall through
|
||||||
|
|
||||||
case EShLangTaskNV:
|
case EShLangTaskNV:
|
||||||
// Fall through
|
// Fall through
|
||||||
#endif
|
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n";
|
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
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -33,11 +33,15 @@
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#ifndef _IOMAPPER_INCLUDED
|
#ifndef _IOMAPPER_INCLUDED
|
||||||
#define _IOMAPPER_INCLUDED
|
#define _IOMAPPER_INCLUDED
|
||||||
|
|
||||||
#include "../Public/ShaderLang.h"
|
#include <cstdint>
|
||||||
|
#include "LiveTraverser.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
//
|
//
|
||||||
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
||||||
//
|
//
|
||||||
|
@ -47,17 +51,288 @@ class TInfoSink;
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
class TIntermediate;
|
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<int> TSlotSet;
|
||||||
|
typedef std::unordered_map<int, TSlotSet> 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<std::string>& 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<TString, int> TVarSlotMap; // <resourceName, location/binding>
|
||||||
|
typedef std::map<int, TVarSlotMap> TSlotMap; // <resourceKey, TVarSlotMap>
|
||||||
|
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<uint32_t>(stage) <= 0x0000ffff && static_cast<uint32_t>(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<TString, TVarEntryInfo> TVarLiveMap;
|
||||||
|
|
||||||
|
// override function "operator=", if a vector<const _Kty, _Ty> 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<const TString, TVarEntryInfo> {
|
||||||
|
TVarLivePair(const std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
|
||||||
|
TVarLivePair& operator=(const TVarLivePair& _Right) {
|
||||||
|
const_cast<TString&>(first) = _Right.first;
|
||||||
|
second = _Right.second;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
TVarLivePair(const TVarLivePair& src) : pair(src) { }
|
||||||
|
};
|
||||||
|
typedef std::vector<TVarLivePair> TVarLiveVector;
|
||||||
|
|
||||||
// I/O mapper
|
// I/O mapper
|
||||||
class TIoMapper {
|
class TIoMapper {
|
||||||
public:
|
public:
|
||||||
TIoMapper() {}
|
TIoMapper() {}
|
||||||
virtual ~TIoMapper() {}
|
virtual ~TIoMapper() {}
|
||||||
|
|
||||||
// grow the reflection stage by stage
|
// 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
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _IOMAPPER_INCLUDED
|
#endif // _IOMAPPER_INCLUDED
|
||||||
|
|
||||||
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|
|
@ -63,14 +63,14 @@ namespace glslang {
|
||||||
|
|
||||||
class TInductiveTraverser : public TIntermTraverser {
|
class TInductiveTraverser : public TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TInductiveTraverser(int id, TSymbolTable& st)
|
TInductiveTraverser(long long id, TSymbolTable& st)
|
||||||
: loopId(id), symbolTable(st), bad(false) { }
|
: loopId(id), symbolTable(st), bad(false) { }
|
||||||
|
|
||||||
virtual bool visitBinary(TVisit, TIntermBinary* node);
|
virtual bool visitBinary(TVisit, TIntermBinary* node);
|
||||||
virtual bool visitUnary(TVisit, TIntermUnary* node);
|
virtual bool visitUnary(TVisit, TIntermUnary* node);
|
||||||
virtual bool visitAggregate(TVisit, TIntermAggregate* 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;
|
TSymbolTable& symbolTable;
|
||||||
bool bad;
|
bool bad;
|
||||||
TSourceLoc badLoc;
|
TSourceLoc badLoc;
|
||||||
|
@ -129,7 +129,7 @@ bool TInductiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* n
|
||||||
//
|
//
|
||||||
// External function to call for loop check.
|
// 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);
|
TInductiveTraverser it(loopId, symbolTable);
|
||||||
|
|
||||||
|
@ -187,12 +187,14 @@ bool TIndexTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
||||||
//
|
//
|
||||||
void TParseContext::constantIndexExpressionCheck(TIntermNode* index)
|
void TParseContext::constantIndexExpressionCheck(TIntermNode* index)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
TIndexTraverser it(inductiveLoopIds);
|
TIndexTraverser it(inductiveLoopIds);
|
||||||
|
|
||||||
index->traverse(&it);
|
index->traverse(&it);
|
||||||
|
|
||||||
if (it.bad)
|
if (it.bad)
|
||||||
error(it.badLoc, "Non-constant-index-expression", "limitations", "");
|
error(it.badLoc, "Non-constant-index-expression", "limitations", "");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -165,27 +165,36 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// matrix from vector
|
// matrix from vector or scalar
|
||||||
int count = 0;
|
|
||||||
const int startIndex = index;
|
|
||||||
int nodeComps = node->getType().computeNumComponents();
|
int nodeComps = node->getType().computeNumComponents();
|
||||||
for (int i = startIndex; i < endIndex; i++) {
|
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)
|
if (i >= instanceSize)
|
||||||
return;
|
return;
|
||||||
if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
|
|
||||||
|
// construct the matrix in column-major order, from
|
||||||
|
// the components provided, in order
|
||||||
leftUnionArray[i] = rightUnionArray[count];
|
leftUnionArray[i] = rightUnionArray[count];
|
||||||
else
|
|
||||||
leftUnionArray[i].setDConst(0.0);
|
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (nodeComps > 1)
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam)
|
bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,26 +57,98 @@ public:
|
||||||
TParseVersions(TIntermediate& interm, int version, EProfile profile,
|
TParseVersions(TIntermediate& interm, int version, EProfile profile,
|
||||||
const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink,
|
const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink,
|
||||||
bool forwardCompatible, EShMessages messages)
|
bool forwardCompatible, EShMessages messages)
|
||||||
: infoSink(infoSink), version(version), profile(profile), language(language),
|
:
|
||||||
spvVersion(spvVersion), forwardCompatible(forwardCompatible),
|
#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) { }
|
intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { }
|
||||||
virtual ~TParseVersions() { }
|
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 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 checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
||||||
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, 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[],
|
||||||
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
const char* featureDesc);
|
||||||
virtual void ppRequireExtensions(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 TExtensionBehavior getExtensionBehavior(const char*);
|
||||||
virtual bool extensionTurnedOn(const char* const extension);
|
virtual bool extensionTurnedOn(const char* const extension);
|
||||||
virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
|
virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
|
||||||
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
|
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 fullIntegerCheck(const TSourceLoc&, const char* op);
|
||||||
|
|
||||||
|
virtual void unimplemented(const TSourceLoc&, const char* featureDesc);
|
||||||
virtual void doubleCheck(const TSourceLoc&, const char* op);
|
virtual void doubleCheck(const TSourceLoc&, const char* op);
|
||||||
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void float16ScalarVectorCheck(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 void int8ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual bool int8Arithmetic();
|
virtual bool int8Arithmetic();
|
||||||
virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc);
|
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);
|
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 int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void explicitInt8Check(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 explicitInt16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void explicitInt32Check(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 explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void explicitFloat64Check(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 spvRemoved(const TSourceLoc&, const char* op);
|
||||||
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
|
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
|
||||||
virtual void requireVulkan(const TSourceLoc&, const char* op);
|
virtual void requireVulkan(const TSourceLoc&, const char* op);
|
||||||
virtual void requireSpv(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 requireSpv(const TSourceLoc&, const char *op, unsigned int version);
|
||||||
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
|
|
||||||
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension);
|
|
||||||
|
|
||||||
|
|
||||||
|
#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,
|
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...) = 0;
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
@ -113,6 +198,7 @@ public:
|
||||||
const char* szExtraInfoFormat, ...) = 0;
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...) = 0;
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
void addError() { ++numErrors; }
|
void addError() { ++numErrors; }
|
||||||
int getNumErrors() const { return numErrors; }
|
int getNumErrors() const { return numErrors; }
|
||||||
|
@ -126,24 +212,25 @@ public:
|
||||||
void setCurrentString(int string) { currentScanner->setString(string); }
|
void setCurrentString(int string) { currentScanner->setString(string); }
|
||||||
|
|
||||||
void getPreamble(std::string&);
|
void getPreamble(std::string&);
|
||||||
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
|
#ifdef ENABLE_HLSL
|
||||||
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
|
|
||||||
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
|
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
|
||||||
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
|
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
|
||||||
bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; }
|
bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; }
|
||||||
|
#else
|
||||||
|
bool isReadingHLSL() const { return false; }
|
||||||
|
#endif
|
||||||
|
|
||||||
TInfoSink& infoSink;
|
TInfoSink& infoSink;
|
||||||
|
|
||||||
// compilation mode
|
// compilation mode
|
||||||
int version; // version, updated by #version in the shader
|
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
|
EShLanguage language; // really the stage
|
||||||
SpvVersion spvVersion;
|
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
|
TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is set to
|
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is
|
||||||
|
TMap<TString, unsigned int> extensionMinSpv; // for each extension string, store minimum spirv required
|
||||||
EShMessages messages; // errors/warnings/rule-sets
|
EShMessages messages; // errors/warnings/rule-sets
|
||||||
int numErrors; // number of compile-time errors encountered
|
int numErrors; // number of compile-time errors encountered
|
||||||
TInputScanner* currentScanner;
|
TInputScanner* currentScanner;
|
||||||
|
|
49
thirdparty/ShaderCompiler/glslang/MachineIndependent/pch.h
vendored
Normal file
49
thirdparty/ShaderCompiler/glslang/MachineIndependent/pch.h
vendored
Normal file
|
@ -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 <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cctype>
|
||||||
|
#include <climits>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <memory>
|
||||||
|
#include "SymbolTable.h"
|
||||||
|
#include "ParseHelper.h"
|
||||||
|
#include "Scan.h"
|
||||||
|
#include "ScanContext.h"
|
||||||
|
|
||||||
|
#endif /* _PCH_H */
|
|
@ -147,6 +147,10 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
token = scanToken(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
|
// record the definition of the macro
|
||||||
|
@ -162,29 +166,43 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
if (existing != nullptr) {
|
if (existing != nullptr) {
|
||||||
if (! existing->undef) {
|
if (! existing->undef) {
|
||||||
// Already defined -- need to make sure they are identical:
|
// 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,
|
// "Two replacement lists are identical if and only if the
|
||||||
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
|
// preprocessing tokens in both have the same number,
|
||||||
if (existing->functionLike != mac.functionLike)
|
// ordering, spelling, and white-space separation, where all
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define", atomStrings.getString(defAtom));
|
// white-space separations are considered identical."
|
||||||
else if (existing->args.size() != mac.args.size())
|
if (existing->functionLike != mac.functionLike) {
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
|
parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define",
|
||||||
else {
|
atomStrings.getString(defAtom));
|
||||||
if (existing->args != mac.args)
|
} else if (existing->args.size() != mac.args.size()) {
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom));
|
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();
|
existing->body.reset();
|
||||||
mac.body.reset();
|
mac.body.reset();
|
||||||
int newToken;
|
int newToken;
|
||||||
|
bool firstToken = true;
|
||||||
do {
|
do {
|
||||||
int oldToken;
|
int oldToken;
|
||||||
TPpToken oldPpToken;
|
TPpToken oldPpToken;
|
||||||
TPpToken newPpToken;
|
TPpToken newPpToken;
|
||||||
oldToken = existing->body.getToken(parseContext, &oldPpToken);
|
oldToken = existing->body.getToken(parseContext, &oldPpToken);
|
||||||
newToken = mac.body.getToken(parseContext, &newPpToken);
|
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) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
} while (newToken > 0);
|
} while (newToken != EndOfInput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*existing = mac;
|
*existing = mac;
|
||||||
|
@ -437,6 +455,7 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
token = tokenPaste(token, *ppToken);
|
||||||
token = evalToToken(token, shortCircuit, res, err, ppToken);
|
token = evalToToken(token, shortCircuit, res, err, ppToken);
|
||||||
return eval(token, precedence, 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:
|
case MacroExpandStarted:
|
||||||
break;
|
break;
|
||||||
case MacroExpandUndef:
|
case MacroExpandUndef:
|
||||||
if (! shortCircuit && parseContext.profile == EEsProfile) {
|
if (! shortCircuit && parseContext.isEsProfile()) {
|
||||||
const char* message = "undefined macro in expression not allowed in es profile";
|
const char* message = "undefined macro in expression not allowed in es profile";
|
||||||
if (parseContext.relaxedErrors())
|
if (parseContext.relaxedErrors())
|
||||||
parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", ppToken->name);
|
parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", ppToken->name);
|
||||||
|
@ -603,14 +622,25 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
const TSourceLoc directiveLoc = ppToken->loc;
|
const TSourceLoc directiveLoc = ppToken->loc;
|
||||||
bool startWithLocalSearch = true; // to additionally include the extra "" paths
|
bool startWithLocalSearch = true; // to additionally include the extra "" paths
|
||||||
int token = scanToken(ppToken);
|
int token;
|
||||||
|
|
||||||
// handle <header-name>-style #include
|
// Find the first non-whitespace char after #include
|
||||||
if (token == '<') {
|
int ch = getChar();
|
||||||
|
while (ch == ' ' || ch == '\t') {
|
||||||
|
ch = getChar();
|
||||||
|
}
|
||||||
|
if (ch == '<') {
|
||||||
|
// <header-name> style
|
||||||
startWithLocalSearch = false;
|
startWithLocalSearch = false;
|
||||||
token = scanHeaderName(ppToken, '>');
|
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) {
|
if (token != PpAtomConstString) {
|
||||||
parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", "");
|
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.
|
const char* sourceName = nullptr; // Optional source file name.
|
||||||
bool lineErr = false;
|
bool lineErr = false;
|
||||||
bool fileErr = false;
|
bool fileErr = false;
|
||||||
|
disableEscapeSequences = true;
|
||||||
token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken);
|
token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken);
|
||||||
|
disableEscapeSequences = false;
|
||||||
if (! lineErr) {
|
if (! lineErr) {
|
||||||
lineToken = lineRes;
|
lineToken = lineRes;
|
||||||
if (token == '\n')
|
if (token == '\n')
|
||||||
|
@ -704,6 +736,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
||||||
parseContext.setCurrentLine(lineRes);
|
parseContext.setCurrentLine(lineRes);
|
||||||
|
|
||||||
if (token != '\n') {
|
if (token != '\n') {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (token == PpAtomConstString) {
|
if (token == PpAtomConstString) {
|
||||||
parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line");
|
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
|
// We need to save a copy of the string instead of pointing
|
||||||
|
@ -713,7 +746,9 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
||||||
parseContext.setCurrentSourceName(sourceName);
|
parseContext.setCurrentSourceName(sourceName);
|
||||||
hasFile = true;
|
hasFile = true;
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
|
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
|
||||||
if (! fileErr) {
|
if (! fileErr) {
|
||||||
parseContext.setCurrentString(fileRes);
|
parseContext.setCurrentString(fileRes);
|
||||||
|
@ -733,7 +768,9 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
||||||
// Handle #error
|
// Handle #error
|
||||||
int TPpContext::CPPerror(TPpToken* ppToken)
|
int TPpContext::CPPerror(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
|
disableEscapeSequences = true;
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
|
disableEscapeSequences = false;
|
||||||
std::string message;
|
std::string message;
|
||||||
TSourceLoc loc = ppToken->loc;
|
TSourceLoc loc = ppToken->loc;
|
||||||
|
|
||||||
|
@ -774,10 +811,8 @@ int TPpContext::CPPpragma(TPpToken* ppToken)
|
||||||
case PpAtomConstUint:
|
case PpAtomConstUint:
|
||||||
case PpAtomConstInt64:
|
case PpAtomConstInt64:
|
||||||
case PpAtomConstUint64:
|
case PpAtomConstUint64:
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case PpAtomConstInt16:
|
case PpAtomConstInt16:
|
||||||
case PpAtomConstUint16:
|
case PpAtomConstUint16:
|
||||||
#endif
|
|
||||||
case PpAtomConstFloat:
|
case PpAtomConstFloat:
|
||||||
case PpAtomConstDouble:
|
case PpAtomConstDouble:
|
||||||
case PpAtomConstFloat16:
|
case PpAtomConstFloat16:
|
||||||
|
@ -862,8 +897,7 @@ int TPpContext::CPPextension(TPpToken* ppToken)
|
||||||
if (token != PpAtomIdentifier)
|
if (token != PpAtomIdentifier)
|
||||||
parseContext.ppError(ppToken->loc, "extension name expected", "#extension", "");
|
parseContext.ppError(ppToken->loc, "extension name expected", "#extension", "");
|
||||||
|
|
||||||
assert(strlen(ppToken->name) <= MaxTokenLength);
|
snprintf(extensionName, sizeof(extensionName), "%s", ppToken->name);
|
||||||
strcpy(extensionName, ppToken->name);
|
|
||||||
|
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token != ':') {
|
if (token != ':') {
|
||||||
|
@ -937,18 +971,20 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
||||||
case PpAtomIfndef:
|
case PpAtomIfndef:
|
||||||
token = CPPifdef(0, ppToken);
|
token = CPPifdef(0, ppToken);
|
||||||
break;
|
break;
|
||||||
|
case PpAtomLine:
|
||||||
|
token = CPPline(ppToken);
|
||||||
|
break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case PpAtomInclude:
|
case PpAtomInclude:
|
||||||
if(!parseContext.isReadingHLSL()) {
|
if(!parseContext.isReadingHLSL()) {
|
||||||
parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
|
parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
|
||||||
}
|
}
|
||||||
token = CPPinclude(ppToken);
|
token = CPPinclude(ppToken);
|
||||||
break;
|
break;
|
||||||
case PpAtomLine:
|
|
||||||
token = CPPline(ppToken);
|
|
||||||
break;
|
|
||||||
case PpAtomPragma:
|
case PpAtomPragma:
|
||||||
token = CPPpragma(ppToken);
|
token = CPPpragma(ppToken);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case PpAtomUndef:
|
case PpAtomUndef:
|
||||||
token = CPPundef(ppToken);
|
token = CPPundef(ppToken);
|
||||||
break;
|
break;
|
||||||
|
@ -1023,7 +1059,9 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken*
|
||||||
case MacroExpandNotStarted:
|
case MacroExpandNotStarted:
|
||||||
break;
|
break;
|
||||||
case MacroExpandError:
|
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;
|
break;
|
||||||
case MacroExpandStarted:
|
case MacroExpandStarted:
|
||||||
case MacroExpandUndef:
|
case MacroExpandUndef:
|
||||||
|
@ -1035,13 +1073,10 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken*
|
||||||
expandedArg->putToken(token, ppToken);
|
expandedArg->putToken(token, ppToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token == EndOfInput) {
|
if (token != tMarkerInput::marker) {
|
||||||
// Error, or MacroExpand ate the marker, so had bad input, recover
|
// Error, or MacroExpand ate the marker, so had bad input, recover
|
||||||
delete expandedArg;
|
delete expandedArg;
|
||||||
expandedArg = nullptr;
|
expandedArg = nullptr;
|
||||||
} else {
|
|
||||||
// remove the marker
|
|
||||||
popInput();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return expandedArg;
|
return expandedArg;
|
||||||
|
@ -1150,6 +1185,8 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b
|
||||||
int macroAtom = atomStrings.getAtom(ppToken->name);
|
int macroAtom = atomStrings.getAtom(ppToken->name);
|
||||||
switch (macroAtom) {
|
switch (macroAtom) {
|
||||||
case PpAtomLineMacro:
|
case PpAtomLineMacro:
|
||||||
|
// Arguments which are macro have been replaced in the first stage.
|
||||||
|
if (ppToken->ival == 0)
|
||||||
ppToken->ival = parseContext.getCurrentLoc().line;
|
ppToken->ival = parseContext.getCurrentLoc().line;
|
||||||
snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
|
snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
|
||||||
UngetToken(PpAtomConstInt, ppToken);
|
UngetToken(PpAtomConstInt, ppToken);
|
||||||
|
@ -1251,6 +1288,11 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b
|
||||||
nestStack.push_back('}');
|
nestStack.push_back('}');
|
||||||
else if (nestStack.size() > 0 && token == nestStack.back())
|
else if (nestStack.size() > 0 && token == nestStack.back())
|
||||||
nestStack.pop_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);
|
in->args[arg]->putToken(token, ppToken);
|
||||||
tokenRecorded = true;
|
tokenRecorded = true;
|
||||||
}
|
}
|
||||||
|
@ -1258,7 +1300,7 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b
|
||||||
|
|
||||||
if (token == ')') {
|
if (token == ')') {
|
||||||
// closing paren of call
|
// closing paren of call
|
||||||
if (in->mac->args.size() == 1 && tokenRecorded == 0)
|
if (in->mac->args.size() == 1 && !tokenRecorded)
|
||||||
break;
|
break;
|
||||||
arg++;
|
arg++;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -87,7 +87,8 @@ namespace glslang {
|
||||||
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
|
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
|
||||||
preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
|
preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
|
||||||
rootFileName(rootFileName),
|
rootFileName(rootFileName),
|
||||||
currentSourceFile(rootFileName)
|
currentSourceFile(rootFileName),
|
||||||
|
disableEscapeSequences(false)
|
||||||
{
|
{
|
||||||
ifdepth = 0;
|
ifdepth = 0;
|
||||||
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
|
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
|
||||||
|
|
|
@ -84,6 +84,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "../ParseHelper.h"
|
#include "../ParseHelper.h"
|
||||||
|
#include "PpTokens.h"
|
||||||
|
|
||||||
/* windows only pragma */
|
/* windows only pragma */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -104,13 +105,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used for comparing macro definitions, so checks what is relevant for that.
|
// 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 &&
|
return space == right.space &&
|
||||||
ival == right.ival && dval == right.dval && i64val == right.i64val &&
|
ival == right.ival && dval == right.dval && i64val == right.i64val &&
|
||||||
strncmp(name, right.name, MaxTokenLength) == 0;
|
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;
|
TSourceLoc loc;
|
||||||
// True if a space (for white space or a removed comment) should also be
|
// True if a space (for white space or a removed comment) should also be
|
||||||
|
@ -213,6 +214,7 @@ public:
|
||||||
virtual int getch() = 0;
|
virtual int getch() = 0;
|
||||||
virtual void ungetch() = 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 endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
|
||||||
virtual bool isMacroInput() { return false; }
|
virtual bool isMacroInput() { return false; }
|
||||||
|
|
||||||
|
@ -243,24 +245,79 @@ public:
|
||||||
// From PpTokens.cpp
|
// From PpTokens.cpp
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// Capture the needed parts of a token stream for macro recording/playback.
|
||||||
class TokenStream {
|
class TokenStream {
|
||||||
public:
|
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);
|
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*);
|
int getToken(TParseContextBase&, TPpToken*);
|
||||||
bool atEnd() { return current >= data.size(); }
|
bool atEnd() { return currentPos >= stream.size(); }
|
||||||
bool peekTokenizedPasting(bool lastTokenPastes);
|
bool peekTokenizedPasting(bool lastTokenPastes);
|
||||||
bool peekUntokenizedPasting();
|
bool peekUntokenizedPasting();
|
||||||
void reset() { current = 0; }
|
void reset() { currentPos = 0; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void putSubtoken(char);
|
TVector<Token> stream;
|
||||||
int getSubtoken();
|
size_t currentPos;
|
||||||
void ungetSubtoken();
|
|
||||||
|
|
||||||
TVector<unsigned char> data;
|
|
||||||
size_t current;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -320,6 +377,10 @@ protected:
|
||||||
int getChar() { return inputStack.back()->getch(); }
|
int getChar() { return inputStack.back()->getch(); }
|
||||||
void ungetChar() { inputStack.back()->ungetch(); }
|
void ungetChar() { inputStack.back()->ungetch(); }
|
||||||
bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
|
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 endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
|
||||||
bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); }
|
bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); }
|
||||||
|
|
||||||
|
@ -344,6 +405,7 @@ protected:
|
||||||
virtual int getch() override { assert(0); return EndOfInput; }
|
virtual int getch() override { assert(0); return EndOfInput; }
|
||||||
virtual void ungetch() override { assert(0); }
|
virtual void ungetch() override { assert(0); }
|
||||||
bool peekPasting() override { return prepaste; }
|
bool peekPasting() override { return prepaste; }
|
||||||
|
bool peekContinuedPasting(int a) override { return mac->body.peekContinuedPasting(a); }
|
||||||
bool endOfReplacementList() override { return mac->body.atEnd(); }
|
bool endOfReplacementList() override { return mac->body.atEnd(); }
|
||||||
bool isMacroInput() override { return true; }
|
bool isMacroInput() override { return true; }
|
||||||
|
|
||||||
|
@ -418,11 +480,15 @@ protected:
|
||||||
|
|
||||||
class tTokenInput : public tInput {
|
class tTokenInput : public tInput {
|
||||||
public:
|
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 scan(TPpToken *ppToken) override { return tokens->getToken(pp->parseContext, ppToken); }
|
||||||
virtual int getch() override { assert(0); return EndOfInput; }
|
virtual int getch() override { assert(0); return EndOfInput; }
|
||||||
virtual void ungetch() override { assert(0); }
|
virtual void ungetch() override { assert(0); }
|
||||||
virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); }
|
virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); }
|
||||||
|
bool peekContinuedPasting(int a) override { return tokens->peekContinuedPasting(a); }
|
||||||
protected:
|
protected:
|
||||||
TokenStream* tokens;
|
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
|
||||||
|
@ -629,6 +695,7 @@ protected:
|
||||||
std::string currentSourceFile;
|
std::string currentSourceFile;
|
||||||
|
|
||||||
std::istringstream strtodStream;
|
std::istringstream strtodStream;
|
||||||
|
bool disableEscapeSequences;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
|
@ -96,12 +96,19 @@ namespace glslang {
|
||||||
/////////////////////////////////// Floating point constants: /////////////////////////////////
|
/////////////////////////////////// Floating point constants: /////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
//
|
||||||
* lFloatConst() - Scan a single- or double-precision floating point constant. Assumes that the scanner
|
// Scan a single- or double-precision floating point constant.
|
||||||
* has seen at least one digit, followed by either a decimal '.' or the
|
// Assumes that the scanner has seen at least one digit,
|
||||||
* letter 'e', or a precision ending (e.g., F or LF).
|
// 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)
|
int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
const auto saveName = [&](int ch) {
|
const auto saveName = [&](int ch) {
|
||||||
|
@ -135,6 +142,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
||||||
ch = getChar();
|
ch = getChar();
|
||||||
int firstDecimal = len;
|
int firstDecimal = len;
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
// 1.#INF or -1.#INF
|
// 1.#INF or -1.#INF
|
||||||
if (ch == '#' && (ifdepth > 0 || parseContext.intermediate.getSource() == EShSourceHlsl)) {
|
if (ch == '#' && (ifdepth > 0 || parseContext.intermediate.getSource() == EShSourceHlsl)) {
|
||||||
if ((len < 2) ||
|
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
|
// Consume leading-zero digits after the decimal point
|
||||||
while (ch == '0') {
|
while (ch == '0') {
|
||||||
|
@ -250,6 +259,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
||||||
// Suffix:
|
// Suffix:
|
||||||
bool isDouble = false;
|
bool isDouble = false;
|
||||||
bool isFloat16 = false;
|
bool isFloat16 = false;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (ch == 'l' || ch == 'L') {
|
if (ch == 'l' || ch == 'L') {
|
||||||
if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl)
|
if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl)
|
||||||
parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
|
parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
|
||||||
|
@ -288,11 +298,15 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
||||||
saveName(ch);
|
saveName(ch);
|
||||||
isFloat16 = true;
|
isFloat16 = true;
|
||||||
}
|
}
|
||||||
} else if (ch == 'f' || ch == 'F') {
|
} else
|
||||||
|
#endif
|
||||||
|
if (ch == 'f' || ch == 'F') {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (ifdepth == 0)
|
if (ifdepth == 0)
|
||||||
parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix");
|
parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix");
|
||||||
if (ifdepth == 0 && !parseContext.relaxedErrors())
|
if (ifdepth == 0 && !parseContext.relaxedErrors())
|
||||||
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix");
|
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix");
|
||||||
|
#endif
|
||||||
if (ifdepth == 0 && !hasDecimalOrExponent)
|
if (ifdepth == 0 && !hasDecimalOrExponent)
|
||||||
parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
|
parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
|
||||||
saveName(ch);
|
saveName(ch);
|
||||||
|
@ -435,6 +449,14 @@ int TPpContext::characterLiteral(TPpToken* ppToken)
|
||||||
//
|
//
|
||||||
// Scanner used to tokenize source stream.
|
// 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 TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int AlreadyComplained = 0;
|
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 int Num_Int64_Extensions = sizeof(Int64_Extensions) / sizeof(Int64_Extensions[0]);
|
||||||
|
|
||||||
static const char* const Int16_Extensions[] = {
|
static const char* const Int16_Extensions[] = {
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16 };
|
E_GL_EXT_shader_explicit_arithmetic_types_int16 };
|
||||||
static const int Num_Int16_Extensions = sizeof(Int16_Extensions) / sizeof(Int16_Extensions[0]);
|
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;
|
ppToken->name[len++] = (char)ch;
|
||||||
isUnsigned = true;
|
isUnsigned = true;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
int nextCh = getch();
|
int nextCh = getch();
|
||||||
if (nextCh == 'l' || nextCh == 'L') {
|
if (nextCh == 'l' || nextCh == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
|
@ -572,7 +593,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
nextCh = getch();
|
nextCh = getch();
|
||||||
if ((nextCh == 's' || nextCh == 'S') &&
|
if ((nextCh == 's' || nextCh == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
|
@ -581,12 +601,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
isInt16 = true;
|
isInt16 = true;
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
#endif
|
|
||||||
} else if (ch == 'l' || ch == 'L') {
|
} else if (ch == 'l' || ch == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isInt64 = true;
|
isInt64 = true;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if ((ch == 's' || ch == 'S') &&
|
} else if ((ch == 's' || ch == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
|
@ -674,6 +692,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isUnsigned = true;
|
isUnsigned = true;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
int nextCh = getch();
|
int nextCh = getch();
|
||||||
if (nextCh == 'l' || nextCh == 'L') {
|
if (nextCh == 'l' || nextCh == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
|
@ -682,7 +701,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
nextCh = getch();
|
nextCh = getch();
|
||||||
if ((nextCh == 's' || nextCh == 'S') &&
|
if ((nextCh == 's' || nextCh == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
|
@ -691,12 +709,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
isInt16 = true;
|
isInt16 = true;
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
#endif
|
|
||||||
} else if (ch == 'l' || ch == 'L') {
|
} else if (ch == 'l' || ch == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isInt64 = true;
|
isInt64 = true;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if ((ch == 's' || ch == 'S') &&
|
} else if ((ch == 's' || ch == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
|
@ -765,6 +781,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isUnsigned = true;
|
isUnsigned = true;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
int nextCh = getch();
|
int nextCh = getch();
|
||||||
if (nextCh == 'l' || nextCh == 'L') {
|
if (nextCh == 'l' || nextCh == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
|
@ -773,7 +790,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
nextCh = getch();
|
nextCh = getch();
|
||||||
if ((nextCh == 's' || nextCh == 'S') &&
|
if ((nextCh == 's' || nextCh == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
|
@ -782,12 +798,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
isInt16 = true;
|
isInt16 = true;
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
#endif
|
|
||||||
} else if (ch == 'l' || ch == 'L') {
|
} else if (ch == 'l' || ch == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isInt64 = true;
|
isInt64 = true;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if ((ch == 's' || ch == 'S') &&
|
} else if ((ch == 's' || ch == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
|
@ -1012,12 +1026,80 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
case '\'':
|
case '\'':
|
||||||
return pp->characterLiteral(ppToken);
|
return pp->characterLiteral(ppToken);
|
||||||
case '"':
|
case '"':
|
||||||
// TODO: If this gets enhanced to handle escape sequences, or
|
// #include uses scanHeaderName() to ignore these escape sequences.
|
||||||
// anything that is different than what #include needs, then
|
|
||||||
// #include needs to use scanHeaderName() for this.
|
|
||||||
ch = getch();
|
ch = getch();
|
||||||
while (ch != '"' && ch != '\n' && ch != EndOfInput) {
|
while (ch != '"' && ch != '\n' && ch != EndOfInput) {
|
||||||
if (len < MaxTokenLength) {
|
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;
|
ppToken->name[len] = (char)ch;
|
||||||
len++;
|
len++;
|
||||||
ch = getch();
|
ch = getch();
|
||||||
|
@ -1106,9 +1188,13 @@ int TPpContext::tokenize(TPpToken& ppToken)
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case PpAtomConstString:
|
case PpAtomConstString:
|
||||||
if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
|
|
||||||
// HLSL allows string literals.
|
// HLSL allows string literals.
|
||||||
parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", "");
|
// GLSL allows string literals with GL_EXT_debug_printf.
|
||||||
|
if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
|
||||||
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1116,7 +1202,7 @@ int TPpContext::tokenize(TPpToken& ppToken)
|
||||||
parseContext.ppError(ppToken.loc, "character literals not supported", "\'", "");
|
parseContext.ppError(ppToken.loc, "character literals not supported", "\'", "");
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
strcpy(ppToken.name, atomStrings.getString(token));
|
snprintf(ppToken.name, sizeof(ppToken.name), "%s", atomStrings.getString(token));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1153,13 +1239,19 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the token after the ##
|
// 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);
|
token = scanToken(&pastedPpToken);
|
||||||
|
|
||||||
// This covers end of argument expansion
|
// This covers end of argument expansion
|
||||||
if (token == tMarkerInput::marker) {
|
if (token == tMarkerInput::marker) {
|
||||||
parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", "");
|
parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", "");
|
||||||
break;
|
return resultToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the token text
|
// get the token text
|
||||||
|
@ -1185,8 +1277,8 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
|
||||||
case PpAtomAnd:
|
case PpAtomAnd:
|
||||||
case PpAtomOr:
|
case PpAtomOr:
|
||||||
case PpAtomXor:
|
case PpAtomXor:
|
||||||
strcpy(ppToken.name, atomStrings.getString(resultToken));
|
snprintf(ppToken.name, sizeof(ppToken.name), "%s", atomStrings.getString(resultToken));
|
||||||
strcpy(pastedPpToken.name, atomStrings.getString(token));
|
snprintf(pastedPpToken.name, sizeof(pastedPpToken.name), "%s", atomStrings.getString(token));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", "");
|
parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", "");
|
||||||
|
@ -1198,7 +1290,8 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
|
||||||
parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", "");
|
parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", "");
|
||||||
return resultToken;
|
return resultToken;
|
||||||
}
|
}
|
||||||
strncat(ppToken.name, pastedPpToken.name, MaxTokenLength - strlen(ppToken.name));
|
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)
|
// correct the kind of token we are making, if needed (identifiers stay identifiers)
|
||||||
if (resultToken != PpAtomIdentifier) {
|
if (resultToken != PpAtomIdentifier) {
|
||||||
|
@ -1208,6 +1301,7 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
|
||||||
else
|
else
|
||||||
parseContext.ppError(ppToken.loc, "combined token is invalid", "##", "");
|
parseContext.ppError(ppToken.loc, "combined token is invalid", "##", "");
|
||||||
}
|
}
|
||||||
|
} while (peekContinuedPasting(resultToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultToken;
|
return resultToken;
|
||||||
|
|
|
@ -99,150 +99,34 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
// Add a token (including backing string) to the end of a macro
|
||||||
namespace {
|
// token stream, for later playback.
|
||||||
|
|
||||||
// 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<unsigned char>(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.
|
|
||||||
void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
|
void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
// save the atom
|
TokenStream::Token streamToken(atom, *ppToken);
|
||||||
assert((atom & ~0xff) == 0);
|
stream.push_back(streamToken);
|
||||||
putSubtoken(static_cast<char>(atom));
|
|
||||||
|
|
||||||
// save the backing name string
|
|
||||||
if (SaveName(atom)) {
|
|
||||||
const char* s = ppToken->name;
|
|
||||||
while (*s)
|
|
||||||
putSubtoken(*s++);
|
|
||||||
putSubtoken(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the numeric value
|
// Read the next token from a macro token stream.
|
||||||
if (SaveValue(atom)) {
|
|
||||||
const char* n = reinterpret_cast<const char*>(&ppToken->i64val);
|
|
||||||
for (size_t i = 0; i < sizeof(ppToken->i64val); ++i)
|
|
||||||
putSubtoken(*n++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the next token from a token stream.
|
|
||||||
// (Not the source stream, but a stream used to hold a tokenized macro).
|
|
||||||
int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken)
|
int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken)
|
||||||
{
|
{
|
||||||
// get the atom
|
if (atEnd())
|
||||||
int atom = getSubtoken();
|
return EndOfInput;
|
||||||
if (atom == EndOfInput)
|
|
||||||
return atom;
|
|
||||||
|
|
||||||
// init the token
|
int atom = stream[currentPos++].get(*ppToken);
|
||||||
ppToken->clear();
|
|
||||||
ppToken->loc = parseContext.getCurrentLoc();
|
ppToken->loc = parseContext.getCurrentLoc();
|
||||||
|
|
||||||
// get the backing name string
|
#ifndef GLSLANG_WEB
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for ##, unless the current # is the last character
|
// Check for ##, unless the current # is the last character
|
||||||
if (atom == '#') {
|
if (atom == '#') {
|
||||||
if (current < data.size()) {
|
if (peekToken('#')) {
|
||||||
if (getSubtoken() == '#') {
|
|
||||||
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
|
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
|
||||||
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
|
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
|
||||||
|
currentPos++;
|
||||||
atom = PpAtomPaste;
|
atom = PpAtomPaste;
|
||||||
} else
|
|
||||||
ungetSubtoken();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// get the numeric value
|
|
||||||
if (SaveValue(atom)) {
|
|
||||||
char* n = reinterpret_cast<char*>(&ppToken->i64val);
|
|
||||||
for (size_t i = 0; i < sizeof(ppToken->i64val); ++i)
|
|
||||||
*n++ = (char)getSubtoken();
|
|
||||||
}
|
|
||||||
|
|
||||||
return atom;
|
return atom;
|
||||||
}
|
}
|
||||||
|
@ -256,15 +140,14 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
|
||||||
{
|
{
|
||||||
// 1. preceding ##?
|
// 1. preceding ##?
|
||||||
|
|
||||||
size_t savePos = current;
|
size_t savePos = currentPos;
|
||||||
int subtoken;
|
|
||||||
// skip white space
|
// skip white space
|
||||||
do {
|
while (peekToken(' '))
|
||||||
subtoken = getSubtoken();
|
++currentPos;
|
||||||
} while (subtoken == ' ');
|
if (peekToken(PpAtomPaste)) {
|
||||||
current = savePos;
|
currentPos = savePos;
|
||||||
if (subtoken == PpAtomPaste)
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// 2. last token and we've been told after this there will be a ##
|
// 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
|
// Getting here means the last token will be pasted, after this
|
||||||
|
|
||||||
// Are we at the last non-whitespace token?
|
// Are we at the last non-whitespace token?
|
||||||
savePos = current;
|
savePos = currentPos;
|
||||||
bool moreTokens = false;
|
bool moreTokens = false;
|
||||||
do {
|
do {
|
||||||
subtoken = getSubtoken();
|
if (atEnd())
|
||||||
if (subtoken == EndOfInput)
|
|
||||||
break;
|
break;
|
||||||
if (subtoken != ' ') {
|
if (!peekToken(' ')) {
|
||||||
moreTokens = true;
|
moreTokens = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
++currentPos;
|
||||||
} while (true);
|
} while (true);
|
||||||
current = savePos;
|
currentPos = savePos;
|
||||||
|
|
||||||
return !moreTokens;
|
return !moreTokens;
|
||||||
}
|
}
|
||||||
|
@ -293,23 +176,21 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
|
||||||
bool TPpContext::TokenStream::peekUntokenizedPasting()
|
bool TPpContext::TokenStream::peekUntokenizedPasting()
|
||||||
{
|
{
|
||||||
// don't return early, have to restore this
|
// don't return early, have to restore this
|
||||||
size_t savePos = current;
|
size_t savePos = currentPos;
|
||||||
|
|
||||||
// skip white-space
|
// skip white-space
|
||||||
int subtoken;
|
while (peekToken(' '))
|
||||||
do {
|
++currentPos;
|
||||||
subtoken = getSubtoken();
|
|
||||||
} while (subtoken == ' ');
|
|
||||||
|
|
||||||
// check for ##
|
// check for ##
|
||||||
bool pasting = false;
|
bool pasting = false;
|
||||||
if (subtoken == '#') {
|
if (peekToken('#')) {
|
||||||
subtoken = getSubtoken();
|
++currentPos;
|
||||||
if (subtoken == '#')
|
if (peekToken('#'))
|
||||||
pasting = true;
|
pasting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = savePos;
|
currentPos = savePos;
|
||||||
|
|
||||||
return pasting;
|
return pasting;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
// propagate the 'noContraction' qualifier.
|
// propagate the 'noContraction' qualifier.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
#include "propagateNoContraction.h"
|
#include "propagateNoContraction.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -79,7 +81,7 @@ typedef std::unordered_set<glslang::TIntermBranch*> ReturnBranchNodeSet;
|
||||||
// the node has 'noContraction' qualifier, otherwise false.
|
// the node has 'noContraction' qualifier, otherwise false.
|
||||||
bool isPreciseObjectNode(glslang::TIntermTyped* node)
|
bool isPreciseObjectNode(glslang::TIntermTyped* node)
|
||||||
{
|
{
|
||||||
return node->getType().getQualifier().noContraction;
|
return node->getType().getQualifier().isNoContraction();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the opcode is a dereferencing one.
|
// Returns true if the opcode is a dereferencing one.
|
||||||
|
@ -864,3 +866,5 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#include "../Include/Common.h"
|
#include "../Include/Common.h"
|
||||||
#include "reflection.h"
|
#include "reflection.h"
|
||||||
#include "LiveTraverser.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.
|
// This is in the glslang namespace directly so it can be a friend of TReflection.
|
||||||
//
|
//
|
||||||
|
|
||||||
class TReflectionTraverser : public TLiveTraverser {
|
class TReflectionTraverser : public TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TReflectionTraverser(const TIntermediate& i, TReflection& r) :
|
TReflectionTraverser(const TIntermediate& i, TReflection& r) :
|
||||||
TLiveTraverser(i), reflection(r) { }
|
TIntermTraverser(), intermediate(i), reflection(r), updateStageMasks(true) { }
|
||||||
|
|
||||||
virtual bool visitBinary(TVisit, TIntermBinary* node);
|
virtual bool visitBinary(TVisit, TIntermBinary* node);
|
||||||
virtual void visitSymbol(TIntermSymbol* base);
|
virtual void visitSymbol(TIntermSymbol* base);
|
||||||
|
@ -90,66 +92,79 @@ public:
|
||||||
if (processedDerefs.find(&base) == processedDerefs.end()) {
|
if (processedDerefs.find(&base) == processedDerefs.end()) {
|
||||||
processedDerefs.insert(&base);
|
processedDerefs.insert(&base);
|
||||||
|
|
||||||
|
int blockIndex = -1;
|
||||||
|
int offset = -1;
|
||||||
|
TList<TIntermBinary*> 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
|
// Use a degenerate (empty) set of dereferences to immediately put as at the end of
|
||||||
// the dereference change expected by blowUpActiveAggregate.
|
// the dereference change expected by blowUpActiveAggregate.
|
||||||
TList<TIntermBinary*> derefs;
|
blowUpActiveAggregate(base.getType(), baseName, derefs, derefs.end(), offset, blockIndex, 0, -1, 0,
|
||||||
blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0);
|
base.getQualifier().storage, updateStageMasks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addAttribute(const TIntermSymbol& base)
|
void addPipeIOVariable(const TIntermSymbol& base)
|
||||||
{
|
{
|
||||||
if (processedDerefs.find(&base) == processedDerefs.end()) {
|
if (processedDerefs.find(&base) == processedDerefs.end()) {
|
||||||
processedDerefs.insert(&base);
|
processedDerefs.insert(&base);
|
||||||
|
|
||||||
const TString &name = base.getName();
|
const TString &name = base.getName();
|
||||||
const TType &type = base.getType();
|
const TType &type = base.getType();
|
||||||
|
const bool input = base.getQualifier().isPipeInput();
|
||||||
|
|
||||||
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
TReflection::TMapIndexToReflection &ioItems =
|
||||||
if (it == reflection.nameToIndex.end()) {
|
input ? reflection.indexToPipeInput : reflection.indexToPipeOutput;
|
||||||
reflection.nameToIndex[name.c_str()] = (int)reflection.indexToAttribute.size();
|
|
||||||
reflection.indexToAttribute.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0));
|
|
||||||
|
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<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<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
||||||
|
} else {
|
||||||
|
EShLanguageMask& stages = ioItems[it->second].stages;
|
||||||
|
stages = static_cast<EShLanguageMask>(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
|
// Lookup or calculate the offset of all block members at once, using the recursively
|
||||||
|
@ -157,16 +172,16 @@ public:
|
||||||
void getOffsets(const TType& type, TVector<int>& offsets)
|
void getOffsets(const TType& type, TVector<int>& offsets)
|
||||||
{
|
{
|
||||||
const TTypeList& memberList = *type.getStruct();
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
int memberSize = 0;
|
int memberSize = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
for (size_t m = 0; m < offsets.size(); ++m) {
|
for (size_t m = 0; m < offsets.size(); ++m) {
|
||||||
// if the user supplied an offset, snap to it now
|
// if the user supplied an offset, snap to it now
|
||||||
if (memberList[m].type->getQualifier().hasOffset())
|
if (memberList[m].type->getQualifier().hasOffset())
|
||||||
offset = memberList[m].type->getQualifier().layoutOffset;
|
offset = memberList[m].type->getQualifier().layoutOffset;
|
||||||
|
|
||||||
// calculate the offset of the next member and align the current offset to this member
|
// 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
|
// save the offset of this member
|
||||||
offsets[m] = offset;
|
offsets[m] = offset;
|
||||||
|
@ -196,21 +211,34 @@ public:
|
||||||
return stride;
|
return stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the block data size.
|
// count the total number of leaf members from iterating out of a block type
|
||||||
// Block arrayness is not taken into account, each element is backed by a separate buffer.
|
int countAggregateMembers(const TType& parentType)
|
||||||
int getBlockSize(const TType& blockType)
|
|
||||||
{
|
{
|
||||||
const TTypeList& memberList = *blockType.getStruct();
|
if (! parentType.isStruct())
|
||||||
int lastIndex = (int)memberList.size() - 1;
|
return 1;
|
||||||
int lastOffset = getOffset(blockType, lastIndex);
|
|
||||||
|
|
||||||
int lastMemberSize;
|
const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix);
|
||||||
int dummyStride;
|
|
||||||
intermediate.getMemberAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride,
|
|
||||||
blockType.getQualifier().layoutPacking,
|
|
||||||
blockType.getQualifier().layoutMatrix == ElmRowMajor);
|
|
||||||
|
|
||||||
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
|
// 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.
|
// 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.
|
// 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<TIntermBinary*>& derefs,
|
void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList<TIntermBinary*>& derefs,
|
||||||
TList<TIntermBinary*>::const_iterator deref, int offset, int blockIndex, int arraySize)
|
TList<TIntermBinary*>::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
|
// process the part of the dereference chain that was explicit in the shader
|
||||||
TString name = baseName;
|
TString name = baseName;
|
||||||
const TType* terminalType = &baseType;
|
const TType* terminalType = &baseType;
|
||||||
|
@ -234,15 +273,21 @@ public:
|
||||||
case EOpIndexIndirect: {
|
case EOpIndexIndirect: {
|
||||||
int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
|
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
|
// 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) {
|
for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
|
||||||
TString newBaseName = name;
|
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) + "]");
|
newBaseName.append(TString("[") + String(i) + "]");
|
||||||
TList<TIntermBinary*>::const_iterator nextDeref = deref;
|
TList<TIntermBinary*>::const_iterator nextDeref = deref;
|
||||||
++nextDeref;
|
++nextDeref;
|
||||||
TType derefType(*terminalType, 0);
|
blowUpActiveAggregate(*terminalType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize,
|
||||||
blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize);
|
topLevelArraySize, topLevelArrayStride, baseStorage, active);
|
||||||
|
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
offset += stride;
|
offset += stride;
|
||||||
|
@ -251,22 +296,42 @@ public:
|
||||||
// it was all completed in the recursive calls above
|
// it was all completed in the recursive calls above
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case EOpIndexDirect:
|
case EOpIndexDirect: {
|
||||||
|
int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
|
||||||
|
|
||||||
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
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) + "]");
|
name.append(TString("[") + String(index) + "]");
|
||||||
|
|
||||||
if (offset >= 0)
|
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;
|
break;
|
||||||
|
}
|
||||||
case EOpIndexDirectStruct:
|
case EOpIndexDirectStruct:
|
||||||
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
offset += getOffset(visitNode->getLeft()->getType(), index);
|
offset += intermediate.getOffset(visitNode->getLeft()->getType(), index);
|
||||||
if (name.size() > 0)
|
if (name.size() > 0)
|
||||||
name.append(".");
|
name.append(".");
|
||||||
name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName());
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -286,13 +351,27 @@ public:
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
stride = getArrayStride(baseType, *terminalType);
|
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;
|
TString newBaseName = name;
|
||||||
|
if (terminalType->getBasicType() != EbtBlock)
|
||||||
newBaseName.append(TString("[") + String(i) + "]");
|
newBaseName.append(TString("[") + String(i) + "]");
|
||||||
TType derefType(*terminalType, 0);
|
TType derefType(*terminalType, 0);
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
offset = baseOffset + stride * i;
|
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 {
|
} else {
|
||||||
// Visit all members of this aggregate, and for each one,
|
// Visit all members of this aggregate, and for each one,
|
||||||
|
@ -308,11 +387,44 @@ public:
|
||||||
|
|
||||||
for (int i = 0; i < (int)typeList.size(); ++i) {
|
for (int i = 0; i < (int)typeList.size(); ++i) {
|
||||||
TString newBaseName = name;
|
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);
|
TType derefType(*terminalType, i);
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
offset = baseOffset + memberOffsets[i];
|
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;
|
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.
|
// 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.
|
// If the dereferenced entity to record is an array, compute the size and update the maximum size.
|
||||||
|
|
||||||
|
@ -327,16 +443,102 @@ public:
|
||||||
if (arraySize == 0)
|
if (arraySize == 0)
|
||||||
arraySize = mapToGlArraySize(*terminalType);
|
arraySize = mapToGlArraySize(*terminalType);
|
||||||
|
|
||||||
|
TReflection::TMapIndexToReflection& variables = reflection.GetVariableMapForStorage(baseStorage);
|
||||||
|
|
||||||
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
||||||
if (it == reflection.nameToIndex.end()) {
|
if (it == reflection.nameToIndex.end()) {
|
||||||
reflection.nameToIndex[name.c_str()] = (int)reflection.indexToUniform.size();
|
int uniformIndex = (int)variables.size();
|
||||||
reflection.indexToUniform.push_back(TObjectReflection(name.c_str(), *terminalType, offset,
|
reflection.nameToIndex[name.c_str()] = uniformIndex;
|
||||||
mapToGlType(*terminalType),
|
variables.push_back(TObjectReflection(name.c_str(), *terminalType, offset, mapToGlType(*terminalType),
|
||||||
arraySize, blockIndex));
|
arraySize, blockIndex));
|
||||||
} else if (arraySize > 1) {
|
if (terminalType->isArray()) {
|
||||||
int& reflectedArraySize = reflection.indexToUniform[it->second].size;
|
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<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (arraySize > 1) {
|
||||||
|
int& reflectedArraySize = variables[it->second].size;
|
||||||
reflectedArraySize = std::max(arraySize, reflectedArraySize);
|
reflectedArraySize = std::max(arraySize, reflectedArraySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((reflection.options & EShReflectionAllBlockVariables) && active) {
|
||||||
|
EShLanguageMask& stages = variables[it->second].stages;
|
||||||
|
stages = static_cast<EShLanguageMask>(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<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
||||||
|
} else {
|
||||||
|
EShLanguageMask& stages = ioItems[it->second].stages;
|
||||||
|
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a uniform dereference where blocks/struct/arrays are involved in the access.
|
// Add a uniform dereference where blocks/struct/arrays are involved in the access.
|
||||||
|
@ -385,16 +587,23 @@ public:
|
||||||
anonymous = IsAnonymous(base->getName());
|
anonymous = IsAnonymous(base->getName());
|
||||||
|
|
||||||
const TString& blockName = base->getType().getTypeName();
|
const TString& blockName = base->getType().getTypeName();
|
||||||
|
TString baseName;
|
||||||
|
|
||||||
if (base->getType().isArray()) {
|
if (! anonymous)
|
||||||
TType derefType(base->getType(), 0);
|
baseName = blockName;
|
||||||
|
|
||||||
assert(! anonymous);
|
blockIndex = addBlockName(blockName, base->getType(), intermediate.getBlockSize(base->getType()));
|
||||||
for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e)
|
|
||||||
blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType,
|
if (reflection.options & EShReflectionAllBlockVariables) {
|
||||||
getBlockSize(base->getType()));
|
// Use a degenerate (empty) set of dereferences to immediately put as at the end of
|
||||||
} else
|
// the dereference change expected by blowUpActiveAggregate.
|
||||||
blockIndex = addBlockName(blockName, base->getType(), getBlockSize(base->getType()));
|
TList<TIntermBinary*> 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.
|
// Process the dereference chain, backward, accumulating the pieces for later forward traversal.
|
||||||
|
@ -424,19 +633,44 @@ public:
|
||||||
else
|
else
|
||||||
baseName = base->getName();
|
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 addBlockName(const TString& name, const TType& type, int size)
|
||||||
{
|
{
|
||||||
int blockIndex;
|
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());
|
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
||||||
if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
|
if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
|
||||||
blockIndex = (int)reflection.indexToUniformBlock.size();
|
blockIndex = (int)blocks.size();
|
||||||
reflection.nameToIndex[name.c_str()] = blockIndex;
|
reflection.nameToIndex[name.c_str()] = blockIndex;
|
||||||
reflection.indexToUniformBlock.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1));
|
blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, blockIndex));
|
||||||
} else
|
|
||||||
|
blocks.back().numMembers = countAggregateMembers(type);
|
||||||
|
|
||||||
|
if (updateStageMasks) {
|
||||||
|
EShLanguageMask& stages = blocks.back().stages;
|
||||||
|
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
blockIndex = it->second;
|
blockIndex = it->second;
|
||||||
|
if (updateStageMasks) {
|
||||||
|
EShLanguageMask& stages = blocks[blockIndex].stages;
|
||||||
|
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return blockIndex;
|
return blockIndex;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +678,7 @@ public:
|
||||||
// Are we at a level in a dereference chain at which individual active uniform queries are made?
|
// Are we at a level in a dereference chain at which individual active uniform queries are made?
|
||||||
bool isReflectionGranularity(const TType& type)
|
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.
|
// For a binary operation indexing into an aggregate, chase down the base of the aggregate.
|
||||||
|
@ -497,7 +731,6 @@ public:
|
||||||
case EsdBuffer:
|
case EsdBuffer:
|
||||||
return GL_SAMPLER_BUFFER;
|
return GL_SAMPLER_BUFFER;
|
||||||
}
|
}
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
switch ((int)sampler.dim) {
|
switch ((int)sampler.dim) {
|
||||||
case Esd1D:
|
case Esd1D:
|
||||||
|
@ -526,7 +759,6 @@ public:
|
||||||
case EsdBuffer:
|
case EsdBuffer:
|
||||||
return GL_FLOAT16_SAMPLER_BUFFER_AMD;
|
return GL_FLOAT16_SAMPLER_BUFFER_AMD;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch ((int)sampler.dim) {
|
switch ((int)sampler.dim) {
|
||||||
case Esd1D:
|
case Esd1D:
|
||||||
|
@ -589,7 +821,6 @@ public:
|
||||||
case EsdBuffer:
|
case EsdBuffer:
|
||||||
return GL_IMAGE_BUFFER;
|
return GL_IMAGE_BUFFER;
|
||||||
}
|
}
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
switch ((int)sampler.dim) {
|
switch ((int)sampler.dim) {
|
||||||
case Esd1D:
|
case Esd1D:
|
||||||
|
@ -608,7 +839,6 @@ public:
|
||||||
case EsdBuffer:
|
case EsdBuffer:
|
||||||
return GL_FLOAT16_IMAGE_BUFFER_AMD;
|
return GL_FLOAT16_IMAGE_BUFFER_AMD;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch ((int)sampler.dim) {
|
switch ((int)sampler.dim) {
|
||||||
case Esd1D:
|
case Esd1D:
|
||||||
|
@ -674,13 +904,11 @@ public:
|
||||||
switch (type.getBasicType()) {
|
switch (type.getBasicType()) {
|
||||||
case EbtFloat: return GL_FLOAT_VEC2 + offset;
|
case EbtFloat: return GL_FLOAT_VEC2 + offset;
|
||||||
case EbtDouble: return GL_DOUBLE_VEC2 + offset;
|
case EbtDouble: return GL_DOUBLE_VEC2 + offset;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16: return GL_FLOAT16_VEC2_NV + offset;
|
case EbtFloat16: return GL_FLOAT16_VEC2_NV + offset;
|
||||||
#endif
|
|
||||||
case EbtInt: return GL_INT_VEC2 + offset;
|
case EbtInt: return GL_INT_VEC2 + offset;
|
||||||
case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset;
|
case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset;
|
||||||
case EbtInt64: return GL_INT64_ARB + offset;
|
case EbtInt64: return GL_INT64_VEC2_ARB + offset;
|
||||||
case EbtUint64: return GL_UNSIGNED_INT64_ARB + offset;
|
case EbtUint64: return GL_UNSIGNED_INT64_VEC2_ARB + offset;
|
||||||
case EbtBool: return GL_BOOL_VEC2 + offset;
|
case EbtBool: return GL_BOOL_VEC2 + offset;
|
||||||
case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset;
|
case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
|
@ -736,7 +964,6 @@ public:
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
switch (type.getMatrixCols()) {
|
switch (type.getMatrixCols()) {
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -761,7 +988,6 @@ public:
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -770,9 +996,7 @@ public:
|
||||||
switch (type.getBasicType()) {
|
switch (type.getBasicType()) {
|
||||||
case EbtFloat: return GL_FLOAT;
|
case EbtFloat: return GL_FLOAT;
|
||||||
case EbtDouble: return GL_DOUBLE;
|
case EbtDouble: return GL_DOUBLE;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16: return GL_FLOAT16_NV;
|
case EbtFloat16: return GL_FLOAT16_NV;
|
||||||
#endif
|
|
||||||
case EbtInt: return GL_INT;
|
case EbtInt: return GL_INT;
|
||||||
case EbtUint: return GL_UNSIGNED_INT;
|
case EbtUint: return GL_UNSIGNED_INT;
|
||||||
case EbtInt64: return GL_INT64_ARB;
|
case EbtInt64: return GL_INT64_ARB;
|
||||||
|
@ -791,8 +1015,10 @@ public:
|
||||||
return type.isArray() ? type.getOuterArraySize() : 1;
|
return type.isArray() ? type.getOuterArraySize() : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TIntermediate& intermediate;
|
||||||
TReflection& reflection;
|
TReflection& reflection;
|
||||||
std::set<const TIntermNode*> processedDerefs;
|
std::set<const TIntermNode*> processedDerefs;
|
||||||
|
bool updateStageMasks;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TReflectionTraverser(TReflectionTraverser&);
|
TReflectionTraverser(TReflectionTraverser&);
|
||||||
|
@ -825,11 +1051,64 @@ bool TReflectionTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
||||||
// To reflect non-dereferenced objects.
|
// To reflect non-dereferenced objects.
|
||||||
void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
|
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);
|
addUniform(*base);
|
||||||
|
|
||||||
if (intermediate.getStage() == EShLangVertex && base->getQualifier().isPipeInput())
|
if ((intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput()) ||
|
||||||
addAttribute(*base);
|
(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
|
// build counter block index associations for buffers
|
||||||
void TReflection::buildCounterIndices(const TIntermediate& intermediate)
|
void TReflection::buildCounterIndices(const TIntermediate& intermediate)
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
// search for ones that have counters
|
// search for ones that have counters
|
||||||
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
|
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
|
||||||
const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str());
|
const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str());
|
||||||
|
@ -858,14 +1138,25 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate)
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
indexToUniformBlock[i].counterIndex = index;
|
indexToUniformBlock[i].counterIndex = index;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)intermediate;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// build Shader Stages mask for all uniforms
|
// build Shader Stages mask for all uniforms
|
||||||
void TReflection::buildUniformStageMask(const TIntermediate& intermediate)
|
void TReflection::buildUniformStageMask(const TIntermediate& intermediate)
|
||||||
{
|
{
|
||||||
|
if (options & EShReflectionAllBlockVariables)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < int(indexToUniform.size()); ++i) {
|
for (int i = 0; i < int(indexToUniform.size()); ++i) {
|
||||||
indexToUniform[i].stages = static_cast<EShLanguageMask>(indexToUniform[i].stages | 1 << intermediate.getStage());
|
indexToUniform[i].stages = static_cast<EShLanguageMask>(indexToUniform[i].stages | 1 << intermediate.getStage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < int(indexToBufferVariable.size()); ++i) {
|
||||||
|
indexToBufferVariable[i].stages =
|
||||||
|
static_cast<EShLanguageMask>(indexToBufferVariable[i].stages | 1 << intermediate.getStage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge live symbols from 'intermediate' into the existing reflection database.
|
// 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);
|
TReflectionTraverser it(intermediate, *this);
|
||||||
|
|
||||||
// put the entry point on the list of functions to process
|
for (auto& sequnence : intermediate.getTreeRoot()->getAsAggregate()->getSequence()) {
|
||||||
it.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
if (sequnence->getAsAggregate() != nullptr) {
|
||||||
|
if (sequnence->getAsAggregate()->getOp() == glslang::EOpLinkerObjects) {
|
||||||
// process all the functions
|
it.updateStageMasks = false;
|
||||||
while (! it.functions.empty()) {
|
TIntermAggregate* linkerObjects = sequnence->getAsAggregate();
|
||||||
TIntermNode* function = it.functions.back();
|
for (auto& sequnence : linkerObjects->getSequence()) {
|
||||||
it.functions.pop_back();
|
auto pNode = sequnence->getAsSymbolNode();
|
||||||
function->traverse(&it);
|
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);
|
buildCounterIndices(intermediate);
|
||||||
buildUniformStageMask(intermediate);
|
buildUniformStageMask(intermediate);
|
||||||
|
@ -910,9 +1233,24 @@ void TReflection::dump()
|
||||||
indexToUniformBlock[i].dump();
|
indexToUniformBlock[i].dump();
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("Vertex attribute reflection:\n");
|
printf("Buffer variable reflection:\n");
|
||||||
for (size_t i = 0; i < indexToAttribute.size(); ++i)
|
for (size_t i = 0; i < indexToBufferVariable.size(); ++i)
|
||||||
indexToAttribute[i].dump();
|
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");
|
printf("\n");
|
||||||
|
|
||||||
if (getLocalSize(0) > 1) {
|
if (getLocalSize(0) > 1) {
|
||||||
|
@ -920,7 +1258,7 @@ void TReflection::dump()
|
||||||
|
|
||||||
for (int dim=0; dim<3; ++dim)
|
for (int dim=0; dim<3; ++dim)
|
||||||
if (getLocalSize(dim) > 1)
|
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");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -932,3 +1270,5 @@ void TReflection::dump()
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#ifndef _REFLECTION_INCLUDED
|
#ifndef _REFLECTION_INCLUDED
|
||||||
#define _REFLECTION_INCLUDED
|
#define _REFLECTION_INCLUDED
|
||||||
|
|
||||||
|
@ -52,51 +54,11 @@ class TIntermediate;
|
||||||
class TIntermAggregate;
|
class TIntermAggregate;
|
||||||
class TReflectionTraverser;
|
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
|
// The full reflection database
|
||||||
class TReflection {
|
class TReflection {
|
||||||
public:
|
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)
|
for (int dim=0; dim<3; ++dim)
|
||||||
localSize[dim] = 0;
|
localSize[dim] = 0;
|
||||||
|
@ -127,17 +89,57 @@ public:
|
||||||
return badReflection;
|
return badReflection;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for mapping an attribute index to the attribute's description
|
// for mapping an pipeline input index to the input's description
|
||||||
int getNumAttributes() { return (int)indexToAttribute.size(); }
|
int getNumPipeInputs() { return (int)indexToPipeInput.size(); }
|
||||||
const TObjectReflection& getAttribute(int i) const
|
const TObjectReflection& getPipeInput(int i) const
|
||||||
{
|
{
|
||||||
if (i >= 0 && i < (int)indexToAttribute.size())
|
if (i >= 0 && i < (int)indexToPipeInput.size())
|
||||||
return indexToAttribute[i];
|
return indexToPipeInput[i];
|
||||||
else
|
else
|
||||||
return badReflection;
|
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
|
int getIndex(const char* name) const
|
||||||
{
|
{
|
||||||
TNameToIndex::const_iterator it = nameToIndex.find(name);
|
TNameToIndex::const_iterator it = nameToIndex.find(name);
|
||||||
|
@ -150,6 +152,20 @@ public:
|
||||||
// see getIndex(const char*)
|
// see getIndex(const char*)
|
||||||
int getIndex(const TString& name) const { return getIndex(name.c_str()); }
|
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
|
// Thread local size
|
||||||
unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
|
unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
|
||||||
|
|
||||||
|
@ -165,12 +181,37 @@ protected:
|
||||||
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
|
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
|
||||||
typedef std::map<std::string, int> TNameToIndex;
|
typedef std::map<std::string, int> TNameToIndex;
|
||||||
typedef std::vector<TObjectReflection> TMapIndexToReflection;
|
typedef std::vector<TObjectReflection> TMapIndexToReflection;
|
||||||
|
typedef std::vector<int> 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
|
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 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 indexToUniform;
|
||||||
TMapIndexToReflection indexToUniformBlock;
|
TMapIndexToReflection indexToUniformBlock;
|
||||||
TMapIndexToReflection indexToAttribute;
|
TMapIndexToReflection indexToBufferVariable;
|
||||||
|
TMapIndexToReflection indexToBufferBlock;
|
||||||
|
TMapIndexToReflection indexToPipeInput;
|
||||||
|
TMapIndexToReflection indexToPipeOutput;
|
||||||
|
TIndices atomicCounterUniformIndices;
|
||||||
|
|
||||||
unsigned int localSize[3];
|
unsigned int localSize[3];
|
||||||
};
|
};
|
||||||
|
@ -178,3 +219,5 @@ protected:
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _REFLECTION_INCLUDED
|
#endif // _REFLECTION_INCLUDED
|
||||||
|
|
||||||
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|
59
thirdparty/ShaderCompiler/glslang/OSDependent/Unix/CMakeLists.txt
vendored
Normal file
59
thirdparty/ShaderCompiler/glslang/OSDependent/Unix/CMakeLists.txt
vendored
Normal file
|
@ -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)
|
71
thirdparty/ShaderCompiler/glslang/OSDependent/Web/CMakeLists.txt
vendored
Normal file
71
thirdparty/ShaderCompiler/glslang/OSDependent/Web/CMakeLists.txt
vendored
Normal file
|
@ -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)
|
26
thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.after.js
vendored
Normal file
26
thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.after.js
vendored
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
})();
|
287
thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.js.cpp
vendored
Normal file
287
thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.js.cpp
vendored
Normal file
|
@ -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 <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
#include <emscripten.h>
|
||||||
|
#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<EShLanguage>(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<uint32_t>* output = new std::vector<uint32_t>;
|
||||||
|
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<std::vector<uint32_t>*>(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__
|
56
thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.pre.js
vendored
Normal file
56
thirdparty/ShaderCompiler/glslang/OSDependent/Web/glslang.pre.js
vendored
Normal file
|
@ -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;
|
||||||
|
};
|
54
thirdparty/ShaderCompiler/glslang/OSDependent/Windows/CMakeLists.txt
vendored
Normal file
54
thirdparty/ShaderCompiler/glslang/OSDependent/Windows/CMakeLists.txt
vendored
Normal file
|
@ -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)
|
|
@ -32,7 +32,7 @@
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Thirdparty/ShaderCompiler/OGLCompilersDLL/InitializeDll.h"
|
#include "InitializeDll.h"
|
||||||
|
|
||||||
#define STRICT
|
#define STRICT
|
||||||
#define VC_EXTRALEAN 1
|
#define VC_EXTRALEAN 1
|
||||||
|
|
|
@ -45,17 +45,26 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define C_DECL __cdecl
|
#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
|
|
||||||
#else
|
#else
|
||||||
#define SH_IMPORT_EXPORT
|
|
||||||
#define C_DECL
|
#define C_DECL
|
||||||
#endif
|
#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
|
||||||
|
|
||||||
//
|
//
|
||||||
// This is the platform independent interface between an OGL driver
|
// This is the platform independent interface between an OGL driver
|
||||||
// and the shading language compiler/linker.
|
// and the shading language compiler/linker.
|
||||||
|
@ -65,22 +74,17 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 before doing any other compiler/linker operations.
|
||||||
//
|
//
|
||||||
// (Call once per process, not once per thread.)
|
// (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.
|
// 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.
|
// Types of languages the compiler can consume.
|
||||||
|
@ -92,32 +96,45 @@ typedef enum {
|
||||||
EShLangGeometry,
|
EShLangGeometry,
|
||||||
EShLangFragment,
|
EShLangFragment,
|
||||||
EShLangCompute,
|
EShLangCompute,
|
||||||
EShLangRayGenNV,
|
EShLangRayGen,
|
||||||
EShLangIntersectNV,
|
EShLangRayGenNV = EShLangRayGen,
|
||||||
EShLangAnyHitNV,
|
EShLangIntersect,
|
||||||
EShLangClosestHitNV,
|
EShLangIntersectNV = EShLangIntersect,
|
||||||
EShLangMissNV,
|
EShLangAnyHit,
|
||||||
EShLangCallableNV,
|
EShLangAnyHitNV = EShLangAnyHit,
|
||||||
|
EShLangClosestHit,
|
||||||
|
EShLangClosestHitNV = EShLangClosestHit,
|
||||||
|
EShLangMiss,
|
||||||
|
EShLangMissNV = EShLangMiss,
|
||||||
|
EShLangCallable,
|
||||||
|
EShLangCallableNV = EShLangCallable,
|
||||||
EShLangTaskNV,
|
EShLangTaskNV,
|
||||||
EShLangMeshNV,
|
EShLangMeshNV,
|
||||||
EShLangCount,
|
LAST_ELEMENT_MARKER(EShLangCount),
|
||||||
} EShLanguage; // would be better as stage, but this is ancient now
|
} EShLanguage; // would be better as stage, but this is ancient now
|
||||||
|
|
||||||
typedef enum {
|
typedef enum : unsigned {
|
||||||
EShLangVertexMask = (1 << EShLangVertex),
|
EShLangVertexMask = (1 << EShLangVertex),
|
||||||
EShLangTessControlMask = (1 << EShLangTessControl),
|
EShLangTessControlMask = (1 << EShLangTessControl),
|
||||||
EShLangTessEvaluationMask = (1 << EShLangTessEvaluation),
|
EShLangTessEvaluationMask = (1 << EShLangTessEvaluation),
|
||||||
EShLangGeometryMask = (1 << EShLangGeometry),
|
EShLangGeometryMask = (1 << EShLangGeometry),
|
||||||
EShLangFragmentMask = (1 << EShLangFragment),
|
EShLangFragmentMask = (1 << EShLangFragment),
|
||||||
EShLangComputeMask = (1 << EShLangCompute),
|
EShLangComputeMask = (1 << EShLangCompute),
|
||||||
EShLangRayGenNVMask = (1 << EShLangRayGenNV),
|
EShLangRayGenMask = (1 << EShLangRayGen),
|
||||||
EShLangIntersectNVMask = (1 << EShLangIntersectNV),
|
EShLangRayGenNVMask = EShLangRayGenMask,
|
||||||
EShLangAnyHitNVMask = (1 << EShLangAnyHitNV),
|
EShLangIntersectMask = (1 << EShLangIntersect),
|
||||||
EShLangClosestHitNVMask = (1 << EShLangClosestHitNV),
|
EShLangIntersectNVMask = EShLangIntersectMask,
|
||||||
EShLangMissNVMask = (1 << EShLangMissNV),
|
EShLangAnyHitMask = (1 << EShLangAnyHit),
|
||||||
EShLangCallableNVMask = (1 << EShLangCallableNV),
|
EShLangAnyHitNVMask = EShLangAnyHitMask,
|
||||||
|
EShLangClosestHitMask = (1 << EShLangClosestHit),
|
||||||
|
EShLangClosestHitNVMask = EShLangClosestHitMask,
|
||||||
|
EShLangMissMask = (1 << EShLangMiss),
|
||||||
|
EShLangMissNVMask = EShLangMissMask,
|
||||||
|
EShLangCallableMask = (1 << EShLangCallable),
|
||||||
|
EShLangCallableNVMask = EShLangCallableMask,
|
||||||
EShLangTaskNVMask = (1 << EShLangTaskNV),
|
EShLangTaskNVMask = (1 << EShLangTaskNV),
|
||||||
EShLangMeshNVMask = (1 << EShLangMeshNV),
|
EShLangMeshNVMask = (1 << EShLangMeshNV),
|
||||||
|
LAST_ELEMENT_MARKER(EShLanguageMaskCount),
|
||||||
} EShLanguageMask;
|
} EShLanguageMask;
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
@ -126,36 +143,43 @@ class TType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShSourceNone,
|
EShSourceNone,
|
||||||
EShSourceGlsl,
|
EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL)
|
||||||
EShSourceHlsl,
|
EShSourceHlsl, // HLSL
|
||||||
|
LAST_ELEMENT_MARKER(EShSourceCount),
|
||||||
} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead
|
} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShClientNone,
|
EShClientNone, // use when there is no client, e.g. for validation
|
||||||
EShClientVulkan,
|
EShClientVulkan,
|
||||||
EShClientOpenGL,
|
EShClientOpenGL,
|
||||||
|
LAST_ELEMENT_MARKER(EShClientCount),
|
||||||
} EShClient;
|
} EShClient;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTargetNone,
|
EShTargetNone,
|
||||||
EShTargetSpv, // preferred spelling
|
EShTargetSpv, // SPIR-V (preferred spelling)
|
||||||
EshTargetSpv = EShTargetSpv, // legacy spelling
|
EshTargetSpv = EShTargetSpv, // legacy spelling
|
||||||
|
LAST_ELEMENT_MARKER(EShTargetCount),
|
||||||
} EShTargetLanguage;
|
} EShTargetLanguage;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTargetVulkan_1_0 = (1 << 22),
|
EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0
|
||||||
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12),
|
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
|
||||||
EShTargetOpenGL_450 = 450,
|
EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
|
||||||
|
EShTargetOpenGL_450 = 450, // OpenGL
|
||||||
|
LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 4),
|
||||||
} EShTargetClientVersion;
|
} EShTargetClientVersion;
|
||||||
|
|
||||||
typedef EShTargetClientVersion EshTargetClientVersion;
|
typedef EShTargetClientVersion EshTargetClientVersion;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTargetSpv_1_0 = (1 << 16),
|
EShTargetSpv_1_0 = (1 << 16), // SPIR-V 1.0
|
||||||
EShTargetSpv_1_1 = (1 << 16) | (1 << 8),
|
EShTargetSpv_1_1 = (1 << 16) | (1 << 8), // SPIR-V 1.1
|
||||||
EShTargetSpv_1_2 = (1 << 16) | (2 << 8),
|
EShTargetSpv_1_2 = (1 << 16) | (2 << 8), // SPIR-V 1.2
|
||||||
EShTargetSpv_1_3 = (1 << 16) | (3 << 8),
|
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
|
||||||
EShTargetSpv_1_4 = (1 << 16) | (4 << 8),
|
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;
|
} EShTargetLanguageVersion;
|
||||||
|
|
||||||
struct TInputLanguage {
|
struct TInputLanguage {
|
||||||
|
@ -163,6 +187,7 @@ struct TInputLanguage {
|
||||||
EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone
|
EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone
|
||||||
EShClient dialect;
|
EShClient dialect;
|
||||||
int dialectVersion; // version of client's language definition, not the client (when not EShClientNone)
|
int dialectVersion; // version of client's language definition, not the client (when not EShClientNone)
|
||||||
|
bool vulkanRulesRelaxed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TClient {
|
struct TClient {
|
||||||
|
@ -185,7 +210,7 @@ struct TEnvironment {
|
||||||
TTarget target; // what to generate
|
TTarget target; // what to generate
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* StageName(EShLanguage);
|
GLSLANG_EXPORT const char* StageName(EShLanguage);
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
@ -205,6 +230,7 @@ typedef enum {
|
||||||
EShOptNone,
|
EShOptNone,
|
||||||
EShOptSimple, // Optimizations that can be done quickly
|
EShOptSimple, // Optimizations that can be done quickly
|
||||||
EShOptFull, // Optimizations that will take more time
|
EShOptFull, // Optimizations that will take more time
|
||||||
|
LAST_ELEMENT_MARKER(EshOptLevelCount),
|
||||||
} EShOptimizationLevel;
|
} EShOptimizationLevel;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -213,12 +239,13 @@ typedef enum {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTexSampTransKeep, // keep textures and samplers as is (default)
|
EShTexSampTransKeep, // keep textures and samplers as is (default)
|
||||||
EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers
|
EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers
|
||||||
|
LAST_ELEMENT_MARKER(EShTexSampTransCount),
|
||||||
} EShTextureSamplerTransformMode;
|
} EShTextureSamplerTransformMode;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Message choices for what errors and warnings are given.
|
// 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
|
EShMsgDefault = 0, // default is to give all required errors and extra warnings
|
||||||
EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input
|
EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input
|
||||||
EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification
|
EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification
|
||||||
|
@ -233,9 +260,28 @@ enum EShMessages {
|
||||||
EShMsgDebugInfo = (1 << 10), // save debug information
|
EShMsgDebugInfo = (1 << 10), // save debug information
|
||||||
EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
|
EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
|
||||||
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
|
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
|
// Build a table for bindings. This can be used for locating
|
||||||
// attributes, uniforms, globals, etc., as needed.
|
// attributes, uniforms, globals, etc., as needed.
|
||||||
|
@ -265,10 +311,10 @@ typedef void* ShHandle;
|
||||||
// Driver calls these to create and destroy compiler/linker
|
// Driver calls these to create and destroy compiler/linker
|
||||||
// objects.
|
// objects.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader
|
GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader
|
||||||
SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair
|
GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair
|
||||||
SH_IMPORT_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object)
|
GLSLANG_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object)
|
||||||
SH_IMPORT_EXPORT void ShDestruct(ShHandle);
|
GLSLANG_EXPORT void ShDestruct(ShHandle);
|
||||||
|
|
||||||
//
|
//
|
||||||
// The return value of ShCompile is boolean, non-zero indicating
|
// 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
|
// The info-log should be written by ShCompile into
|
||||||
// ShHandle, so it can answer future queries.
|
// ShHandle, so it can answer future queries.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT int ShCompile(
|
GLSLANG_EXPORT int ShCompile(
|
||||||
const ShHandle,
|
const ShHandle,
|
||||||
const char* const shaderStrings[],
|
const char* const shaderStrings[],
|
||||||
const int numStrings,
|
const int numStrings,
|
||||||
|
@ -290,7 +336,7 @@ SH_IMPORT_EXPORT int ShCompile(
|
||||||
EShMessages messages = EShMsgDefault // warnings and errors
|
EShMessages messages = EShMsgDefault // warnings and errors
|
||||||
);
|
);
|
||||||
|
|
||||||
SH_IMPORT_EXPORT int ShLinkExt(
|
GLSLANG_EXPORT int ShLinkExt(
|
||||||
const ShHandle, // linker object
|
const ShHandle, // linker object
|
||||||
const ShHandle h[], // compiler objects to link together
|
const ShHandle h[], // compiler objects to link together
|
||||||
const int numHandles);
|
const int numHandles);
|
||||||
|
@ -299,26 +345,26 @@ SH_IMPORT_EXPORT int ShLinkExt(
|
||||||
// ShSetEncrpytionMethod is a place-holder for specifying
|
// ShSetEncrpytionMethod is a place-holder for specifying
|
||||||
// how source code is encrypted.
|
// 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
|
// All the following return 0 if the information is not
|
||||||
// available in the object passed down, or the object is bad.
|
// available in the object passed down, or the object is bad.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle);
|
GLSLANG_EXPORT const char* ShGetInfoLog(const ShHandle);
|
||||||
SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle);
|
GLSLANG_EXPORT const void* ShGetExecutable(const ShHandle);
|
||||||
SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing
|
GLSLANG_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 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
|
// 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 the location ID of the named uniform.
|
||||||
// Returns -1 if error.
|
// 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
|
#ifdef __cplusplus
|
||||||
} // end extern "C"
|
} // end extern "C"
|
||||||
|
@ -349,19 +395,27 @@ class TInfoSink;
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
const char* GetEsslVersionString();
|
struct Version {
|
||||||
const char* GetGlslVersionString();
|
int major;
|
||||||
int GetKhronosToolId();
|
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 TIntermediate;
|
||||||
class TProgram;
|
class TProgram;
|
||||||
class TPoolAllocator;
|
class TPoolAllocator;
|
||||||
|
|
||||||
// Call this exactly once per process before using anything else
|
// Call this exactly once per process before using anything else
|
||||||
bool InitializeProcess();
|
GLSLANG_EXPORT bool InitializeProcess();
|
||||||
|
|
||||||
// Call once per process to tear down everything
|
// Call once per process to tear down everything
|
||||||
void FinalizeProcess();
|
GLSLANG_EXPORT void FinalizeProcess();
|
||||||
|
|
||||||
// Resource type for IO resolver
|
// Resource type for IO resolver
|
||||||
enum TResourceType {
|
enum TResourceType {
|
||||||
|
@ -374,11 +428,22 @@ enum TResourceType {
|
||||||
EResCount
|
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
|
// Make one TShader per shader that you will link into a program. Then
|
||||||
// - provide the shader through setStrings() or setStringsWithLengths()
|
// - provide the shader through setStrings() or setStringsWithLengths()
|
||||||
// - optionally call setEnv*(), see below for more detail
|
// - optionally call setEnv*(), see below for more detail
|
||||||
// - optionally use setPreamble() to set a special shader string that will be
|
// - optionally use setPreamble() to set a special shader string that will be
|
||||||
// processed before all others but won't affect the validity of #version
|
// 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
|
// - call parse(): source language and target environment must be selected
|
||||||
// either by correct setting of EShMessages sent to parse(), or by
|
// either by correct setting of EShMessages sent to parse(), or by
|
||||||
// explicitly calling setEnv*()
|
// explicitly calling setEnv*()
|
||||||
|
@ -391,42 +456,79 @@ enum TResourceType {
|
||||||
//
|
//
|
||||||
class TShader {
|
class TShader {
|
||||||
public:
|
public:
|
||||||
explicit TShader(EShLanguage);
|
GLSLANG_EXPORT explicit TShader(EShLanguage);
|
||||||
virtual ~TShader();
|
GLSLANG_EXPORT virtual ~TShader();
|
||||||
void setStrings(const char* const* s, int n);
|
GLSLANG_EXPORT void setStrings(const char* const* s, int n);
|
||||||
void setStringsWithLengths(const char* const* s, const int* l, int n);
|
GLSLANG_EXPORT void setStringsWithLengths(
|
||||||
void setStringsWithLengthsAndNames(
|
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);
|
const char* const* s, const int* l, const char* const* names, int n);
|
||||||
void setPreamble(const char* s) { preamble = s; }
|
void setPreamble(const char* s) { preamble = s; }
|
||||||
void setEntryPoint(const char* entryPoint);
|
GLSLANG_EXPORT void setEntryPoint(const char* entryPoint);
|
||||||
void setSourceEntryPoint(const char* sourceEntryPointName);
|
GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
|
||||||
void addProcesses(const std::vector<std::string>&);
|
GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
|
||||||
|
GLSLANG_EXPORT void setUniqueId(unsigned long long id);
|
||||||
|
|
||||||
// IO resolver binding data: see comments in ShaderLang.cpp
|
// IO resolver binding data: see comments in ShaderLang.cpp
|
||||||
void setShiftBinding(TResourceType res, unsigned int base);
|
GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
|
||||||
void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
|
GLSLANG_EXPORT void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
|
||||||
void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
|
GLSLANG_EXPORT void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
|
||||||
void setResourceSetBinding(const std::vector<std::string>& base);
|
GLSLANG_EXPORT void setResourceSetBinding(const std::vector<std::string>& base);
|
||||||
void setAutoMapBindings(bool map);
|
GLSLANG_EXPORT void setAutoMapBindings(bool map);
|
||||||
void setAutoMapLocations(bool map);
|
GLSLANG_EXPORT void setAutoMapLocations(bool map);
|
||||||
void addUniformLocationOverride(const char* name, int loc);
|
GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc);
|
||||||
void setUniformLocationBase(int base);
|
GLSLANG_EXPORT void setUniformLocationBase(int base);
|
||||||
void setInvertY(bool invert);
|
GLSLANG_EXPORT void setInvertY(bool invert);
|
||||||
void setHlslIoMapping(bool hlslIoMap);
|
#ifdef ENABLE_HLSL
|
||||||
void setFlattenUniformArrays(bool flatten);
|
GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
|
||||||
void setNoStorageFormat(bool useUnknownFormat);
|
GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
|
||||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
|
#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).
|
// 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
|
// These must be called so that parsing is done for the right source language and
|
||||||
// target environment, either indirectly through TranslateEnvironment() based on
|
// target environment, either indirectly through TranslateEnvironment() based on
|
||||||
// EShMessages et. al., or directly by the user.
|
// 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)
|
void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version)
|
||||||
{
|
{
|
||||||
environment.input.languageFamily = lang;
|
environment.input.languageFamily = lang;
|
||||||
|
@ -444,8 +546,18 @@ public:
|
||||||
environment.target.language = lang;
|
environment.target.language = lang;
|
||||||
environment.target.version = version;
|
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; }
|
void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
|
||||||
bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; }
|
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.
|
// Interface to #include handlers.
|
||||||
//
|
//
|
||||||
|
@ -530,8 +642,10 @@ public:
|
||||||
virtual void releaseInclude(IncludeResult*) override { }
|
virtual void releaseInclude(IncludeResult*) override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
GLSLANG_EXPORT bool parse(
|
||||||
bool forwardCompatible, EShMessages, Includer&);
|
const TBuiltInResource*, int defaultVersion, EProfile defaultProfile,
|
||||||
|
bool forceDefaultVersionAndProfile, bool forwardCompatible,
|
||||||
|
EShMessages, Includer&);
|
||||||
|
|
||||||
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||||
bool forwardCompatible, EShMessages messages)
|
bool forwardCompatible, EShMessages messages)
|
||||||
|
@ -554,13 +668,14 @@ public:
|
||||||
|
|
||||||
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
|
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
|
||||||
// is not an officially supported or fully working path.
|
// is not an officially supported or fully working path.
|
||||||
bool preprocess(const TBuiltInResource* builtInResources,
|
GLSLANG_EXPORT bool preprocess(
|
||||||
int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
const TBuiltInResource* builtInResources, int defaultVersion,
|
||||||
|
EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||||
bool forwardCompatible, EShMessages message, std::string* outputString,
|
bool forwardCompatible, EShMessages message, std::string* outputString,
|
||||||
Includer& includer);
|
Includer& includer);
|
||||||
|
|
||||||
const char* getInfoLog();
|
GLSLANG_EXPORT const char* getInfoLog();
|
||||||
const char* getInfoDebugLog();
|
GLSLANG_EXPORT const char* getInfoDebugLog();
|
||||||
EShLanguage getStage() const { return stage; }
|
EShLanguage getStage() const { return stage; }
|
||||||
TIntermediate* getIntermediate() const { return intermediate; }
|
TIntermediate* getIntermediate() const { return intermediate; }
|
||||||
|
|
||||||
|
@ -579,11 +694,11 @@ protected:
|
||||||
// stringNames is the optional names for all the strings. If stringNames
|
// 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
|
// 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.
|
// 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 int* lengths;
|
||||||
const char* const* stringNames;
|
const char* const* stringNames;
|
||||||
const char* preamble;
|
int numStrings; // size of the above arrays
|
||||||
int numStrings;
|
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.
|
// a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
|
||||||
std::string sourceEntryPointName;
|
std::string sourceEntryPointName;
|
||||||
|
@ -596,8 +711,47 @@ private:
|
||||||
TShader& operator=(TShader&);
|
TShader& operator=(TShader&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#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 TReflection;
|
||||||
class TIoMapper;
|
class TIoMapper;
|
||||||
|
struct TVarEntryInfo;
|
||||||
|
|
||||||
// Allows to customize the binding layout after linking.
|
// Allows to customize the binding layout after linking.
|
||||||
// All used uniform variables will invoke at least validateBinding.
|
// All used uniform variables will invoke at least validateBinding.
|
||||||
|
@ -629,42 +783,54 @@ public:
|
||||||
|
|
||||||
// Should return true if the resulting/current binding would be okay.
|
// Should return true if the resulting/current binding would be okay.
|
||||||
// Basic idea is to do aliasing binding checks with this.
|
// 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;
|
virtual bool validateBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current binding should be overridden.
|
// Should return a value >= 0 if the current binding should be overridden.
|
||||||
// Return -1 if the current binding (including no binding) should be kept.
|
// 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;
|
virtual int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current set should be overridden.
|
// Should return a value >= 0 if the current set should be overridden.
|
||||||
// Return -1 if the current set (including no set) should be kept.
|
// 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;
|
virtual int resolveSet(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current location should be overridden.
|
// Should return a value >= 0 if the current location should be overridden.
|
||||||
// Return -1 if the current location (including no location) should be kept.
|
// 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;
|
virtual int resolveUniformLocation(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return true if the resulting/current setup would be okay.
|
// Should return true if the resulting/current setup would be okay.
|
||||||
// Basic idea is to do aliasing checks and reject invalid semantic names.
|
// 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;
|
virtual bool validateInOut(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current location should be overridden.
|
// Should return a value >= 0 if the current location should be overridden.
|
||||||
// Return -1 if the current location (including no location) should be kept.
|
// 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;
|
virtual int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current component index should be overridden.
|
// 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.
|
// 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;
|
virtual int resolveInOutComponent(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current color index should be overridden.
|
// 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.
|
// 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;
|
virtual int resolveInOutIndex(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Notification of a uniform variable
|
// Notification of a uniform variable
|
||||||
virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual void notifyBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Notification of a in or out variable
|
// Notification of a in or out variable
|
||||||
virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual void notifyInOut(EShLanguage stage, TVarEntryInfo& ent) = 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
|
// Called by mapIO when it starts its notify pass for the given stage
|
||||||
virtual void beginNotifications(EShLanguage stage) = 0;
|
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
|
// Called by mipIO when it starts its resolve pass for the given stage
|
||||||
virtual void beginResolve(EShLanguage stage) = 0;
|
virtual void beginResolve(EShLanguage stage) = 0;
|
||||||
// Called by mapIO when it has finished the resolve pass
|
// Called by mapIO when it has finished the resolve pass
|
||||||
virtual void endResolve(EShLanguage stage) = 0;
|
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
|
// 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()
|
// the shaders that are to be linked together. After calling shader.parse()
|
||||||
// for all shaders, call link().
|
// for all shaders, call link().
|
||||||
|
@ -673,58 +839,125 @@ public:
|
||||||
//
|
//
|
||||||
class TProgram {
|
class TProgram {
|
||||||
public:
|
public:
|
||||||
TProgram();
|
GLSLANG_EXPORT TProgram();
|
||||||
virtual ~TProgram();
|
GLSLANG_EXPORT virtual ~TProgram();
|
||||||
void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
|
void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
|
||||||
|
std::list<TShader*>& getShaders(EShLanguage stage) { return stages[stage]; }
|
||||||
// Link Validation interface
|
// Link Validation interface
|
||||||
bool link(EShMessages);
|
GLSLANG_EXPORT bool link(EShMessages);
|
||||||
const char* getInfoLog();
|
GLSLANG_EXPORT const char* getInfoLog();
|
||||||
const char* getInfoDebugLog();
|
GLSLANG_EXPORT const char* getInfoDebugLog();
|
||||||
|
|
||||||
TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
|
TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
// Reflection Interface
|
// 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
|
// I/O mapping: apply base offsets and map live unbound variables
|
||||||
// If resolver is not provided it uses the previous approach
|
// If resolver is not provided it uses the previous approach
|
||||||
// and respects auto assignment and offsets.
|
// 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:
|
protected:
|
||||||
bool linkStage(EShLanguage, EShMessages);
|
GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages);
|
||||||
|
GLSLANG_EXPORT bool crossStageCheck(EShMessages);
|
||||||
|
|
||||||
TPoolAllocator* pool;
|
TPoolAllocator* pool;
|
||||||
std::list<TShader*> stages[EShLangCount];
|
std::list<TShader*> stages[EShLangCount];
|
||||||
TIntermediate* intermediate[EShLangCount];
|
TIntermediate* intermediate[EShLangCount];
|
||||||
bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage
|
bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage
|
||||||
TInfoSink* infoSink;
|
TInfoSink* infoSink;
|
||||||
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
TReflection* reflection;
|
TReflection* reflection;
|
||||||
TIoMapper* ioMapper;
|
#endif
|
||||||
bool linked;
|
bool linked;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
48
thirdparty/ShaderCompiler/glslang/updateGrammar
vendored
48
thirdparty/ShaderCompiler/glslang/updateGrammar
vendored
|
@ -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
|
bison --defines=MachineIndependent/glslang_tab.cpp.h -t MachineIndependent/glslang.y -o MachineIndependent/glslang_tab.cpp
|
||||||
|
|
|
@ -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_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_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_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
|
#endif // #ifndef GLSLextEXT_H
|
||||||
|
|
13
thirdparty/ShaderCompiler/spirv/GLSL.ext.KHR.h
vendored
13
thirdparty/ShaderCompiler/spirv/GLSL.ext.KHR.h
vendored
|
@ -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
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
** of this software and/or associated documentation files (the "Materials"),
|
** 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_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_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_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
|
#endif // #ifndef GLSLextKHR_H
|
||||||
|
|
|
@ -69,7 +69,16 @@ const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
|
||||||
//SPV_NV_raytracing
|
//SPV_NV_raytracing
|
||||||
const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
|
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
|
//SPV_NV_shading_rate
|
||||||
const char* const E_SPV_NV_shading_rate = "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
|
#endif // #ifndef GLSLextNV_H
|
||||||
|
|
3435
thirdparty/ShaderCompiler/spirv/GlslangToSpv.cpp
vendored
3435
thirdparty/ShaderCompiler/spirv/GlslangToSpv.cpp
vendored
File diff suppressed because it is too large
Load diff
|
@ -61,17 +61,22 @@ namespace {
|
||||||
// Use by calling visit() on the root block.
|
// Use by calling visit() on the root block.
|
||||||
class ReadableOrderTraverser {
|
class ReadableOrderTraverser {
|
||||||
public:
|
public:
|
||||||
explicit ReadableOrderTraverser(std::function<void(Block*)> callback) : callback_(callback) {}
|
ReadableOrderTraverser(std::function<void(Block*, spv::ReachReason, Block*)> callback)
|
||||||
|
: callback_(callback) {}
|
||||||
// Visits the block if it hasn't been visited already and isn't currently
|
// 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
|
// successors. Delays merge-block and continue-block processing until all
|
||||||
// the branches have been completed.
|
// the branches have been completed. If |block| is an unreachable merge block or
|
||||||
void visit(Block* block)
|
// an unreachable continue target, then |header| is the corresponding header block.
|
||||||
|
void visit(Block* block, spv::ReachReason why, Block* header)
|
||||||
{
|
{
|
||||||
assert(block);
|
assert(block);
|
||||||
|
if (why == spv::ReachViaControlFlow) {
|
||||||
|
reachableViaControlFlow_.insert(block);
|
||||||
|
}
|
||||||
if (visited_.count(block) || delayed_.count(block))
|
if (visited_.count(block) || delayed_.count(block))
|
||||||
return;
|
return;
|
||||||
callback_(block);
|
callback_(block, why, header);
|
||||||
visited_.insert(block);
|
visited_.insert(block);
|
||||||
Block* mergeBlock = nullptr;
|
Block* mergeBlock = nullptr;
|
||||||
Block* continueBlock = nullptr;
|
Block* continueBlock = nullptr;
|
||||||
|
@ -87,27 +92,40 @@ public:
|
||||||
delayed_.insert(continueBlock);
|
delayed_.insert(continueBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto successors = block->getSuccessors();
|
if (why == spv::ReachViaControlFlow) {
|
||||||
|
const auto& successors = block->getSuccessors();
|
||||||
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
|
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
|
||||||
visit(*it);
|
visit(*it, why, nullptr);
|
||||||
|
}
|
||||||
if (continueBlock) {
|
if (continueBlock) {
|
||||||
|
const spv::ReachReason continueWhy =
|
||||||
|
(reachableViaControlFlow_.count(continueBlock) > 0)
|
||||||
|
? spv::ReachViaControlFlow
|
||||||
|
: spv::ReachDeadContinue;
|
||||||
delayed_.erase(continueBlock);
|
delayed_.erase(continueBlock);
|
||||||
visit(continueBlock);
|
visit(continueBlock, continueWhy, block);
|
||||||
}
|
}
|
||||||
if (mergeBlock) {
|
if (mergeBlock) {
|
||||||
|
const spv::ReachReason mergeWhy =
|
||||||
|
(reachableViaControlFlow_.count(mergeBlock) > 0)
|
||||||
|
? spv::ReachViaControlFlow
|
||||||
|
: spv::ReachDeadMerge;
|
||||||
delayed_.erase(mergeBlock);
|
delayed_.erase(mergeBlock);
|
||||||
visit(mergeBlock);
|
visit(mergeBlock, mergeWhy, block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void(Block*)> callback_;
|
std::function<void(Block*, spv::ReachReason, Block*)> callback_;
|
||||||
// Whether a block has already been visited or is being delayed.
|
// Whether a block has already been visited or is being delayed.
|
||||||
std::unordered_set<Block *> visited_, delayed_;
|
std::unordered_set<Block *> visited_, delayed_;
|
||||||
|
|
||||||
|
// The set of blocks that actually are reached via control flow.
|
||||||
|
std::unordered_set<Block *> reachableViaControlFlow_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void spv::inReadableOrder(Block* root, std::function<void(Block*)> callback)
|
void spv::inReadableOrder(Block* root, std::function<void(Block*, spv::ReachReason, Block*)> callback)
|
||||||
{
|
{
|
||||||
ReadableOrderTraverser(callback).visit(root);
|
ReadableOrderTraverser(callback).visit(root, spv::ReachViaControlFlow, nullptr);
|
||||||
}
|
}
|
||||||
|
|
4
thirdparty/ShaderCompiler/spirv/Logger.cpp
vendored
4
thirdparty/ShaderCompiler/spirv/Logger.cpp
vendored
|
@ -32,6 +32,8 @@
|
||||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -66,3 +68,5 @@ std::string SpvBuildLogger::getAllMessages() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end spv namespace
|
} // end spv namespace
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
9
thirdparty/ShaderCompiler/spirv/Logger.h
vendored
9
thirdparty/ShaderCompiler/spirv/Logger.h
vendored
|
@ -46,6 +46,14 @@ class SpvBuildLogger {
|
||||||
public:
|
public:
|
||||||
SpvBuildLogger() {}
|
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.
|
// Registers a TBD functionality.
|
||||||
void tbdFunctionality(const std::string& f);
|
void tbdFunctionality(const std::string& f);
|
||||||
// Registers a missing functionality.
|
// Registers a missing functionality.
|
||||||
|
@ -59,6 +67,7 @@ public:
|
||||||
// Returns all messages accumulated in the order of:
|
// Returns all messages accumulated in the order of:
|
||||||
// TBD functionalities, missing functionalities, warnings, errors.
|
// TBD functionalities, missing functionalities, warnings, errors.
|
||||||
std::string getAllMessages() const;
|
std::string getAllMessages() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpvBuildLogger(const SpvBuildLogger&);
|
SpvBuildLogger(const SpvBuildLogger&);
|
||||||
|
|
50
thirdparty/ShaderCompiler/spirv/NonSemanticDebugPrintf.h
vendored
Normal file
50
thirdparty/ShaderCompiler/spirv/NonSemanticDebugPrintf.h
vendored
Normal file
|
@ -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_
|
16
thirdparty/ShaderCompiler/spirv/SPVRemapper.cpp
vendored
16
thirdparty/ShaderCompiler/spirv/SPVRemapper.cpp
vendored
|
@ -544,6 +544,9 @@ namespace spv {
|
||||||
// Extended instructions: currently, assume everything is an ID.
|
// Extended instructions: currently, assume everything is an ID.
|
||||||
// TODO: add whatever data we need for exceptions to that
|
// TODO: add whatever data we need for exceptions to that
|
||||||
if (opCode == spv::OpExtInst) {
|
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
|
word += 2; // instruction set, and instruction from set
|
||||||
numOperands -= 2;
|
numOperands -= 2;
|
||||||
|
|
||||||
|
@ -625,6 +628,9 @@ namespace spv {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case spv::OperandVariableLiteralStrings:
|
||||||
|
return nextInst;
|
||||||
|
|
||||||
// Execution mode might have extra literal operands. Skip them.
|
// Execution mode might have extra literal operands. Skip them.
|
||||||
case spv::OperandExecutionMode:
|
case spv::OperandExecutionMode:
|
||||||
return nextInst;
|
return nextInst;
|
||||||
|
@ -827,7 +833,15 @@ namespace spv {
|
||||||
[&](spv::Id& id) {
|
[&](spv::Id& id) {
|
||||||
if (thisOpCode != spv::OpNop) {
|
if (thisOpCode != spv::OpNop) {
|
||||||
++idCounter;
|
++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<unsigned int>(opCounter[thisOpCode])
|
||||||
|
* thisOpCode
|
||||||
|
* 50047
|
||||||
|
+ idCounter
|
||||||
|
+ static_cast<unsigned int>(fnId) * 117;
|
||||||
|
|
||||||
if (isOldIdUnmapped(id))
|
if (isOldIdUnmapped(id))
|
||||||
localId(id, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
localId(id, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace spv {
|
||||||
|
|
||||||
// MSVC defines __cplusplus as an older value, even when it supports almost all of 11.
|
// MSVC defines __cplusplus as an older value, even when it supports almost all of 11.
|
||||||
// We handle that here by making our own symbol.
|
// 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
|
# define use_cpp11 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ private:
|
||||||
// Header access & set methods
|
// Header access & set methods
|
||||||
spirword_t magic() const { return spv[0]; } // return magic number
|
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() 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() const { return spv[2]; } // generator magic
|
||||||
spirword_t genmagic(spirword_t m) { return spv[2] = m; }
|
spirword_t genmagic(spirword_t m) { return spv[2] = m; }
|
||||||
spirword_t schemaNum() const { return spv[4]; } // schema number from header
|
spirword_t schemaNum() const { return spv[4]; } // schema number from header
|
||||||
|
|
437
thirdparty/ShaderCompiler/spirv/SpvBuilder.cpp
vendored
437
thirdparty/ShaderCompiler/spirv/SpvBuilder.cpp
vendored
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -46,7 +47,9 @@
|
||||||
|
|
||||||
#include "SpvBuilder.h"
|
#include "SpvBuilder.h"
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
#include "hex_float.h"
|
#include "hex_float.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -230,6 +233,11 @@ Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardP
|
||||||
|
|
||||||
Id Builder::makeIntegerType(int width, bool hasSign)
|
Id Builder::makeIntegerType(int width, bool hasSign)
|
||||||
{
|
{
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
assert(width == 32);
|
||||||
|
width = 32;
|
||||||
|
#endif
|
||||||
|
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) {
|
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)
|
Id Builder::makeFloatType(int width)
|
||||||
{
|
{
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
assert(width == 32);
|
||||||
|
width = 32;
|
||||||
|
#endif
|
||||||
|
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) {
|
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();
|
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<Instruction>(type));
|
||||||
|
module.mapInstruction(type);
|
||||||
|
|
||||||
|
return type->getResultId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: performance: track arrays per stride
|
// TODO: performance: track arrays per stride
|
||||||
// If a stride is supplied (non-zero) make an array.
|
// If a stride is supplied (non-zero) make an array.
|
||||||
// If no stride (0), reuse previous array types.
|
// If no stride (0), reuse previous array types.
|
||||||
|
@ -457,7 +497,8 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
|
||||||
return type->getResultId();
|
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);
|
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<Instruction>(type));
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
module.mapInstruction(type);
|
module.mapInstruction(type);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// deal with capabilities
|
// deal with capabilities
|
||||||
switch (dim) {
|
switch (dim) {
|
||||||
case DimBuffer:
|
case DimBuffer:
|
||||||
|
@ -534,6 +576,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
|
||||||
addCapability(CapabilityImageMSArray);
|
addCapability(CapabilityImageMSArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
}
|
}
|
||||||
|
@ -559,22 +602,38 @@ Id Builder::makeSampledImageType(Id imageType)
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifndef GLSLANG_WEB
|
||||||
Id Builder::makeAccelerationStructureNVType()
|
Id Builder::makeAccelerationStructureType()
|
||||||
{
|
{
|
||||||
Instruction *type;
|
Instruction *type;
|
||||||
if (groupedTypes[OpTypeAccelerationStructureNV].size() == 0) {
|
if (groupedTypes[OpTypeAccelerationStructureKHR].size() == 0) {
|
||||||
type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureNV);
|
type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureKHR);
|
||||||
groupedTypes[OpTypeAccelerationStructureNV].push_back(type);
|
groupedTypes[OpTypeAccelerationStructureKHR].push_back(type);
|
||||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
module.mapInstruction(type);
|
module.mapInstruction(type);
|
||||||
} else {
|
} 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<Instruction>(type));
|
||||||
|
module.mapInstruction(type);
|
||||||
|
} else {
|
||||||
|
type = groupedTypes[OpTypeRayQueryKHR].back();
|
||||||
}
|
}
|
||||||
|
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Id Builder::getDerefTypeId(Id resultId) const
|
Id Builder::getDerefTypeId(Id resultId) const
|
||||||
{
|
{
|
||||||
Id typeId = getTypeId(resultId);
|
Id typeId = getTypeId(resultId);
|
||||||
|
@ -623,6 +682,9 @@ int Builder::getNumTypeConstituents(Id typeId) const
|
||||||
}
|
}
|
||||||
case OpTypeStruct:
|
case OpTypeStruct:
|
||||||
return instr->getNumOperands();
|
return instr->getNumOperands();
|
||||||
|
case OpTypeCooperativeMatrixNV:
|
||||||
|
// has only one constituent when used with OpCompositeConstruct.
|
||||||
|
return 1;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -669,6 +731,7 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
|
||||||
case OpTypeMatrix:
|
case OpTypeMatrix:
|
||||||
case OpTypeArray:
|
case OpTypeArray:
|
||||||
case OpTypeRuntimeArray:
|
case OpTypeRuntimeArray:
|
||||||
|
case OpTypeCooperativeMatrixNV:
|
||||||
return instr->getIdOperand(0);
|
return instr->getIdOperand(0);
|
||||||
case OpTypePointer:
|
case OpTypePointer:
|
||||||
return instr->getIdOperand(1);
|
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.
|
// Return the immediately contained type of a given composite type.
|
||||||
Id Builder::getContainedTypeId(Id typeId) const
|
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<Instruction>(c));
|
||||||
|
nullConstants.push_back(c);
|
||||||
|
module.mapInstruction(c);
|
||||||
|
|
||||||
|
return c->getResultId();
|
||||||
|
}
|
||||||
|
|
||||||
Id Builder::makeBoolConstant(bool b, bool specConstant)
|
Id Builder::makeBoolConstant(bool b, bool specConstant)
|
||||||
{
|
{
|
||||||
Id typeId = makeBoolType();
|
Id typeId = makeBoolType();
|
||||||
|
@ -908,6 +1015,10 @@ Id Builder::makeFloatConstant(float f, bool specConstant)
|
||||||
|
|
||||||
Id Builder::makeDoubleConstant(double d, bool specConstant)
|
Id Builder::makeDoubleConstant(double d, bool specConstant)
|
||||||
{
|
{
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
assert(0);
|
||||||
|
return NoResult;
|
||||||
|
#else
|
||||||
Op opcode = specConstant ? OpSpecConstant : OpConstant;
|
Op opcode = specConstant ? OpSpecConstant : OpConstant;
|
||||||
Id typeId = makeFloatType(64);
|
Id typeId = makeFloatType(64);
|
||||||
union { double db; unsigned long long ull; } u;
|
union { double db; unsigned long long ull; } u;
|
||||||
|
@ -932,10 +1043,15 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
|
||||||
module.mapInstruction(c);
|
module.mapInstruction(c);
|
||||||
|
|
||||||
return c->getResultId();
|
return c->getResultId();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Builder::makeFloat16Constant(float f16, bool specConstant)
|
Id Builder::makeFloat16Constant(float f16, bool specConstant)
|
||||||
{
|
{
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
assert(0);
|
||||||
|
return NoResult;
|
||||||
|
#else
|
||||||
Op opcode = specConstant ? OpSpecConstant : OpConstant;
|
Op opcode = specConstant ? OpSpecConstant : OpConstant;
|
||||||
Id typeId = makeFloatType(16);
|
Id typeId = makeFloatType(16);
|
||||||
|
|
||||||
|
@ -960,13 +1076,21 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant)
|
||||||
module.mapInstruction(c);
|
module.mapInstruction(c);
|
||||||
|
|
||||||
return c->getResultId();
|
return c->getResultId();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Builder::makeFpConstant(Id type, double d, bool specConstant)
|
Id Builder::makeFpConstant(Id type, double d, bool specConstant)
|
||||||
{
|
{
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
const int width = 32;
|
||||||
|
assert(width == getScalarTypeWidth(type));
|
||||||
|
#else
|
||||||
|
const int width = getScalarTypeWidth(type);
|
||||||
|
#endif
|
||||||
|
|
||||||
assert(isFloatType(type));
|
assert(isFloatType(type));
|
||||||
|
|
||||||
switch (getScalarTypeWidth(type)) {
|
switch (width) {
|
||||||
case 16:
|
case 16:
|
||||||
return makeFloat16Constant((float)d, specConstant);
|
return makeFloat16Constant((float)d, specConstant);
|
||||||
case 32:
|
case 32:
|
||||||
|
@ -981,15 +1105,14 @@ Id Builder::makeFpConstant(Id type, double d, bool specConstant)
|
||||||
return NoResult;
|
return NoResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Builder::findCompositeConstant(Op typeClass, const std::vector<Id>& comps)
|
Id Builder::findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps)
|
||||||
{
|
{
|
||||||
Instruction* constant = 0;
|
Instruction* constant = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
|
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
|
||||||
constant = groupedConstants[typeClass][i];
|
constant = groupedConstants[typeClass][i];
|
||||||
|
|
||||||
// same shape?
|
if (constant->getTypeId() != typeId)
|
||||||
if (constant->getNumOperands() != (int)comps.size())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// same contents?
|
// same contents?
|
||||||
|
@ -1044,8 +1167,9 @@ Id Builder::makeCompositeConstant(Id typeId, const std::vector<Id>& members, boo
|
||||||
case OpTypeVector:
|
case OpTypeVector:
|
||||||
case OpTypeArray:
|
case OpTypeArray:
|
||||||
case OpTypeMatrix:
|
case OpTypeMatrix:
|
||||||
|
case OpTypeCooperativeMatrixNV:
|
||||||
if (! specConstant) {
|
if (! specConstant) {
|
||||||
Id existing = findCompositeConstant(typeClass, members);
|
Id existing = findCompositeConstant(typeClass, typeId, members);
|
||||||
if (existing)
|
if (existing)
|
||||||
return existing;
|
return existing;
|
||||||
}
|
}
|
||||||
|
@ -1103,6 +1227,28 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int val
|
||||||
executionModes.push_back(std::unique_ptr<Instruction>(instr));
|
executionModes.push_back(std::unique_ptr<Instruction>(instr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const std::vector<unsigned>& 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<Instruction>(instr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const std::vector<Id>& 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<Instruction>(instr));
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::addName(Id id, const char* string)
|
void Builder::addName(Id id, const char* string)
|
||||||
{
|
{
|
||||||
Instruction* name = new Instruction(OpName);
|
Instruction* name = new Instruction(OpName);
|
||||||
|
@ -1141,7 +1287,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s)
|
||||||
if (decoration == spv::DecorationMax)
|
if (decoration == spv::DecorationMax)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Instruction* dec = new Instruction(OpDecorateStringGOOGLE);
|
Instruction* dec = new Instruction(OpDecorateString);
|
||||||
dec->addIdOperand(id);
|
dec->addIdOperand(id);
|
||||||
dec->addImmediateOperand(decoration);
|
dec->addImmediateOperand(decoration);
|
||||||
dec->addStringOperand(s);
|
dec->addStringOperand(s);
|
||||||
|
@ -1149,6 +1295,34 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s)
|
||||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addDecoration(Id id, Decoration decoration, const std::vector<unsigned>& 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<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::addDecoration(Id id, Decoration decoration, const std::vector<const char*>& 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<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
||||||
{
|
{
|
||||||
if (decoration == spv::DecorationMax)
|
if (decoration == spv::DecorationMax)
|
||||||
|
@ -1162,6 +1336,21 @@ void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
||||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addDecorationId(Id id, Decoration decoration, const std::vector<Id>& 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<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
|
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
|
||||||
{
|
{
|
||||||
if (decoration == spv::DecorationMax)
|
if (decoration == spv::DecorationMax)
|
||||||
|
@ -1191,6 +1380,36 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
|
||||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<unsigned>& 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<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<const char*>& 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<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Function* Builder::makeEntryPoint(const char* entryPoint)
|
Function* Builder::makeEntryPoint(const char* entryPoint)
|
||||||
{
|
{
|
||||||
|
@ -1207,7 +1426,8 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
|
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
|
||||||
const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& decorations, Block **entry)
|
const std::vector<Id>& paramTypes,
|
||||||
|
const std::vector<std::vector<Decoration>>& decorations, Block **entry)
|
||||||
{
|
{
|
||||||
// Make the function and initial instructions in it
|
// Make the function and initial instructions in it
|
||||||
Id typeId = makeFunctionType(returnType, paramTypes);
|
Id typeId = makeFunctionType(returnType, paramTypes);
|
||||||
|
@ -1216,9 +1436,12 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
|
||||||
|
|
||||||
// Set up the precisions
|
// Set up the precisions
|
||||||
setPrecision(function->getId(), precision);
|
setPrecision(function->getId(), precision);
|
||||||
|
function->setReturnPrecision(precision);
|
||||||
for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) {
|
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]);
|
addDecoration(firstParamId + p, decorations[p][d]);
|
||||||
|
function->addParamPrecision(p, decorations[p][d]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CFG
|
// CFG
|
||||||
|
@ -1268,18 +1491,20 @@ void Builder::leaveFunction()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::makeDiscard()
|
void Builder::makeStatementTerminator(spv::Op opcode, const char *name)
|
||||||
{
|
{
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(OpKill)));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(opcode)));
|
||||||
createAndSetNoPredecessorBlock("post-discard");
|
createAndSetNoPredecessorBlock(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// 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);
|
Id pointerType = makePointer(storageClass, type);
|
||||||
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
|
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
|
||||||
inst->addImmediateOperand(storageClass);
|
inst->addImmediateOperand(storageClass);
|
||||||
|
if (initializer != NoResult)
|
||||||
|
inst->addIdOperand(initializer);
|
||||||
|
|
||||||
switch (storageClass) {
|
switch (storageClass) {
|
||||||
case StorageClassFunction:
|
case StorageClassFunction:
|
||||||
|
@ -1295,6 +1520,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
addName(inst->getResultId(), name);
|
addName(inst->getResultId(), name);
|
||||||
|
setPrecision(inst->getResultId(), precision);
|
||||||
|
|
||||||
return inst->getResultId();
|
return inst->getResultId();
|
||||||
}
|
}
|
||||||
|
@ -1308,7 +1534,8 @@ Id Builder::createUndefined(Id type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// av/vis/nonprivate are unnecessary and illegal for some storage classes.
|
// 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) {
|
switch (sc) {
|
||||||
case spv::StorageClassUniform:
|
case spv::StorageClassUniform:
|
||||||
|
@ -1327,7 +1554,8 @@ spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// 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);
|
Instruction* store = new Instruction(OpStore);
|
||||||
store->addIdOperand(lValue);
|
store->addIdOperand(lValue);
|
||||||
|
@ -1349,7 +1577,8 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// 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);
|
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
|
||||||
load->addIdOperand(lValue);
|
load->addIdOperand(lValue);
|
||||||
|
@ -1367,6 +1596,7 @@ Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope
|
||||||
}
|
}
|
||||||
|
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
|
||||||
|
setPrecision(load->getResultId(), precision);
|
||||||
|
|
||||||
return load->getResultId();
|
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<Id>& offsets)
|
Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vector<Id>& offsets)
|
||||||
{
|
{
|
||||||
// Figure out the final resulting type.
|
// Figure out the final resulting type.
|
||||||
spv::Id typeId = getTypeId(base);
|
Id typeId = getResultingAccessChainType();
|
||||||
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]);
|
|
||||||
}
|
|
||||||
typeId = makePointer(storageClass, typeId);
|
typeId = makePointer(storageClass, typeId);
|
||||||
|
|
||||||
// Make the instruction
|
// Make the instruction
|
||||||
|
@ -1408,12 +1629,30 @@ Id Builder::createArrayLength(Id base, unsigned int member)
|
||||||
return length->getResultId();
|
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<Id>(1, type), std::vector<Id>());
|
||||||
|
}
|
||||||
|
|
||||||
|
Instruction* length = new Instruction(getUniqueId(), intType, OpCooperativeMatrixLengthNV);
|
||||||
|
length->addIdOperand(type);
|
||||||
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(length));
|
||||||
|
|
||||||
|
return length->getResultId();
|
||||||
|
}
|
||||||
|
|
||||||
Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index)
|
Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index)
|
||||||
{
|
{
|
||||||
// Generate code for spec constants if in spec constant operation
|
// Generate code for spec constants if in spec constant operation
|
||||||
// generation mode.
|
// generation mode.
|
||||||
if (generatingOpCodeForSpecConst) {
|
if (generatingOpCodeForSpecConst) {
|
||||||
return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite), std::vector<Id>(1, index));
|
return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite),
|
||||||
|
std::vector<Id>(1, index));
|
||||||
}
|
}
|
||||||
Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);
|
Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);
|
||||||
extract->addIdOperand(composite);
|
extract->addIdOperand(composite);
|
||||||
|
@ -1615,7 +1854,8 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector<IdImmediate>& opera
|
||||||
return op->getResultId();
|
return op->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands, const std::vector<unsigned>& literals)
|
Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands,
|
||||||
|
const std::vector<unsigned>& literals)
|
||||||
{
|
{
|
||||||
Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);
|
Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);
|
||||||
op->addImmediateOperand((unsigned) opCode);
|
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.
|
// Accept all parameters needed to create a texture instruction.
|
||||||
// Create the correct instruction based on the inputs, and make the call.
|
// 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,
|
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;
|
static const int maxTextureArgs = 10;
|
||||||
Id texArgs[maxTextureArgs] = {};
|
Id texArgs[maxTextureArgs] = {};
|
||||||
|
@ -1775,7 +2015,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
if (parameters.component != NoResult)
|
if (parameters.component != NoResult)
|
||||||
texArgs[numArgs++] = parameters.component;
|
texArgs[numArgs++] = parameters.component;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifndef GLSLANG_WEB
|
||||||
if (parameters.granularity != NoResult)
|
if (parameters.granularity != NoResult)
|
||||||
texArgs[numArgs++] = parameters.granularity;
|
texArgs[numArgs++] = parameters.granularity;
|
||||||
if (parameters.coarse != NoResult)
|
if (parameters.coarse != NoResult)
|
||||||
|
@ -1822,6 +2062,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
|
||||||
texArgs[numArgs++] = parameters.offsets;
|
texArgs[numArgs++] = parameters.offsets;
|
||||||
}
|
}
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (parameters.sample) {
|
if (parameters.sample) {
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
|
||||||
texArgs[numArgs++] = parameters.sample;
|
texArgs[numArgs++] = parameters.sample;
|
||||||
|
@ -1839,6 +2080,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
if (parameters.volatil) {
|
if (parameters.volatil) {
|
||||||
mask = mask | ImageOperandsVolatileTexelKHRMask;
|
mask = mask | ImageOperandsVolatileTexelKHRMask;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
mask = mask | signExtensionMask;
|
||||||
if (mask == ImageOperandsMaskNone)
|
if (mask == ImageOperandsMaskNone)
|
||||||
--numArgs; // undo speculative reservation for the mask argument
|
--numArgs; // undo speculative reservation for the mask argument
|
||||||
else
|
else
|
||||||
|
@ -1853,10 +2096,9 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
opCode = OpImageSparseFetch;
|
opCode = OpImageSparseFetch;
|
||||||
else
|
else
|
||||||
opCode = OpImageFetch;
|
opCode = OpImageFetch;
|
||||||
#ifdef NV_EXTENSIONS
|
#ifndef GLSLANG_WEB
|
||||||
} else if (parameters.granularity && parameters.coarse) {
|
} else if (parameters.granularity && parameters.coarse) {
|
||||||
opCode = OpImageSampleFootprintNV;
|
opCode = OpImageSampleFootprintNV;
|
||||||
#endif
|
|
||||||
} else if (gather) {
|
} else if (gather) {
|
||||||
if (parameters.Dref)
|
if (parameters.Dref)
|
||||||
if (sparse)
|
if (sparse)
|
||||||
|
@ -1868,6 +2110,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
opCode = OpImageSparseGather;
|
opCode = OpImageSparseGather;
|
||||||
else
|
else
|
||||||
opCode = OpImageGather;
|
opCode = OpImageGather;
|
||||||
|
#endif
|
||||||
} else if (explicitLod) {
|
} else if (explicitLod) {
|
||||||
if (parameters.Dref) {
|
if (parameters.Dref) {
|
||||||
if (proj)
|
if (proj)
|
||||||
|
@ -2016,11 +2259,7 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpImageQueryLod:
|
case OpImageQueryLod:
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
resultType = makeVectorType(getScalarTypeId(getTypeId(parameters.coords)), 2);
|
resultType = makeVectorType(getScalarTypeId(getTypeId(parameters.coords)), 2);
|
||||||
#else
|
|
||||||
resultType = makeVectorType(makeFloatType(32), 2);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case OpImageQueryLevels:
|
case OpImageQueryLevels:
|
||||||
case OpImageQuerySamples:
|
case OpImageQuerySamples:
|
||||||
|
@ -2038,6 +2277,7 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter
|
||||||
if (parameters.lod)
|
if (parameters.lod)
|
||||||
query->addIdOperand(parameters.lod);
|
query->addIdOperand(parameters.lod);
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(query));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(query));
|
||||||
|
addCapability(CapabilityImageQuery);
|
||||||
|
|
||||||
return query->getResultId();
|
return query->getResultId();
|
||||||
}
|
}
|
||||||
|
@ -2062,7 +2302,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
|
||||||
Op op;
|
Op op;
|
||||||
switch (getMostBasicTypeClass(valueType)) {
|
switch (getMostBasicTypeClass(valueType)) {
|
||||||
case OpTypeFloat:
|
case OpTypeFloat:
|
||||||
op = equal ? OpFOrdEqual : OpFOrdNotEqual;
|
op = equal ? OpFOrdEqual : OpFUnordNotEqual;
|
||||||
break;
|
break;
|
||||||
case OpTypeInt:
|
case OpTypeInt:
|
||||||
default:
|
default:
|
||||||
|
@ -2105,7 +2345,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
|
||||||
if (constituent == 0)
|
if (constituent == 0)
|
||||||
resultId = subResultId;
|
resultId = subResultId;
|
||||||
else
|
else
|
||||||
resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision);
|
resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId),
|
||||||
|
precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultId;
|
return resultId;
|
||||||
|
@ -2114,7 +2355,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
|
||||||
// OpCompositeConstruct
|
// OpCompositeConstruct
|
||||||
Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& constituents)
|
Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& 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) {
|
if (generatingOpCodeForSpecConst) {
|
||||||
// Sometime, even in spec-constant-op mode, the constant composite to be
|
// Sometime, even in spec-constant-op mode, the constant composite to be
|
||||||
|
@ -2231,7 +2473,12 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
||||||
int numRows = getTypeNumRows(resultTypeId);
|
int numRows = getTypeNumRows(resultTypeId);
|
||||||
|
|
||||||
Instruction* instr = module.getInstruction(componentTypeId);
|
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
|
// Optimize matrix constructed from a bigger matrix
|
||||||
if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {
|
if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {
|
||||||
|
@ -2307,7 +2554,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
||||||
int row = 0;
|
int row = 0;
|
||||||
int col = 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];
|
Id argComp = sources[arg];
|
||||||
for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {
|
for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {
|
||||||
if (getNumComponents(sources[arg]) > 1) {
|
if (getNumComponents(sources[arg]) > 1) {
|
||||||
|
@ -2319,6 +2566,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
||||||
row = 0;
|
row = 0;
|
||||||
col++;
|
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
|
// Comments in header
|
||||||
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
|
||||||
|
AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
||||||
{
|
{
|
||||||
accessChain.coherentFlags |= coherentFlags;
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
accessChain.alignment |= alignment;
|
accessChain.alignment |= alignment;
|
||||||
|
@ -2548,21 +2800,53 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// 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);
|
assert(accessChain.isRValue == false);
|
||||||
|
|
||||||
transferAccessChainSwizzle(true);
|
transferAccessChainSwizzle(true);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
Id base = collapseAccessChain();
|
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);
|
||||||
|
|
||||||
Id source = rvalue;
|
Id source = rvalue;
|
||||||
|
|
||||||
// dynamic component should be gone
|
// dynamic component should be gone
|
||||||
assert(accessChain.component == NoResult);
|
assert(accessChain.component == NoResult);
|
||||||
|
|
||||||
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
|
// 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.
|
// extract and insert elements to perform writeMask and/or swizzle.
|
||||||
if (accessChain.swizzle.size() > 0) {
|
if (accessChain.swizzle.size() > 0) {
|
||||||
Id tempBaseId = createLoad(base);
|
Id tempBaseId = createLoad(base, spv::NoPrecision);
|
||||||
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2574,9 +2858,12 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp
|
||||||
|
|
||||||
createStore(source, base, memoryAccess, scope, alignment);
|
createStore(source, base, memoryAccess, scope, alignment);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Comments in header
|
// 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;
|
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);
|
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
|
||||||
else {
|
setPrecision(id, precision);
|
||||||
// make a new function variable for this r-value
|
} else {
|
||||||
Id lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
|
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
|
// store into it
|
||||||
createStore(accessChain.base, lValue);
|
createStore(accessChain.base, lValue);
|
||||||
|
}
|
||||||
// move base to the new variable
|
// move base to the new variable
|
||||||
accessChain.base = lValue;
|
accessChain.base = lValue;
|
||||||
accessChain.isRValue = false;
|
accessChain.isRValue = false;
|
||||||
|
|
||||||
// load through the access chain
|
// load through the access chain
|
||||||
id = createLoad(collapseAccessChain());
|
id = createLoad(collapseAccessChain(), precision);
|
||||||
}
|
}
|
||||||
setPrecision(id, precision);
|
|
||||||
} else
|
} else
|
||||||
id = accessChain.base; // no precision, it was set when this was defined
|
id = accessChain.base; // no precision, it was set when this was defined
|
||||||
} else {
|
} else {
|
||||||
|
@ -2627,9 +2922,14 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
||||||
}
|
}
|
||||||
|
|
||||||
// load through the access chain
|
// load through the access chain
|
||||||
id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment);
|
id = collapseAccessChain();
|
||||||
setPrecision(id, precision);
|
// Apply nonuniform both to the access chain and the loaded value.
|
||||||
addDecoration(id, nonUniform);
|
// 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
|
// Done, unless there are swizzles to do
|
||||||
|
@ -2650,7 +2950,7 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
||||||
if (accessChain.component != NoResult)
|
if (accessChain.component != NoResult)
|
||||||
id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);
|
id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);
|
||||||
|
|
||||||
addDecoration(id, nonUniform);
|
addDecoration(id, r_nonUniform);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2908,14 +3208,14 @@ void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control)
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
|
void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
|
||||||
unsigned int dependencyLength)
|
const std::vector<unsigned int>& operands)
|
||||||
{
|
{
|
||||||
Instruction* merge = new Instruction(OpLoopMerge);
|
Instruction* merge = new Instruction(OpLoopMerge);
|
||||||
merge->addIdOperand(mergeBlock->getId());
|
merge->addIdOperand(mergeBlock->getId());
|
||||||
merge->addIdOperand(continueBlock->getId());
|
merge->addIdOperand(continueBlock->getId());
|
||||||
merge->addImmediateOperand(control);
|
merge->addImmediateOperand(control);
|
||||||
if ((control & LoopControlDependencyLengthMask) != 0)
|
for (int op = 0; op < (int)operands.size(); ++op)
|
||||||
merge->addImmediateOperand(dependencyLength);
|
merge->addImmediateOperand(operands[op]);
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2981,7 +3281,8 @@ void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
|
||||||
dumpSourceInstructions(iItr->first, *iItr->second, out);
|
dumpSourceInstructions(iItr->first, *iItr->second, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
void Builder::dumpInstructions(std::vector<unsigned int>& out,
|
||||||
|
const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)instructions.size(); ++i) {
|
for (int i = 0; i < (int)instructions.size(); ++i) {
|
||||||
instructions[i]->dump(out);
|
instructions[i]->dump(out);
|
||||||
|
|
207
thirdparty/ShaderCompiler/spirv/SpvBuilder.h
vendored
207
thirdparty/ShaderCompiler/spirv/SpvBuilder.h
vendored
|
@ -1,7 +1,8 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2020 Google, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -61,6 +62,15 @@
|
||||||
|
|
||||||
namespace spv {
|
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 {
|
class Builder {
|
||||||
public:
|
public:
|
||||||
Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
|
Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
|
||||||
|
@ -85,6 +95,7 @@ public:
|
||||||
const char* file_c_str = str.c_str();
|
const char* file_c_str = str.c_str();
|
||||||
fileString->addStringOperand(file_c_str);
|
fileString->addStringOperand(file_c_str);
|
||||||
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
||||||
|
module.mapInstruction(fileString);
|
||||||
stringIds[file_c_str] = strId;
|
stringIds[file_c_str] = strId;
|
||||||
return strId;
|
return strId;
|
||||||
}
|
}
|
||||||
|
@ -97,6 +108,20 @@ public:
|
||||||
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
|
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
|
||||||
void setEmitOpLines() { emitOpLines = true; }
|
void setEmitOpLines() { emitOpLines = true; }
|
||||||
void addExtension(const char* ext) { extensions.insert(ext); }
|
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<unsigned>(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)
|
void addInclude(const std::string& name, const std::string& text)
|
||||||
{
|
{
|
||||||
spv::Id incId = getStringId(name);
|
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 makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
|
||||||
Id makeSamplerType();
|
Id makeSamplerType();
|
||||||
Id makeSampledImageType(Id imageType);
|
Id makeSampledImageType(Id imageType);
|
||||||
|
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
|
||||||
|
|
||||||
// accelerationStructureNV type
|
// accelerationStructureNV type
|
||||||
Id makeAccelerationStructureNVType();
|
Id makeAccelerationStructureType();
|
||||||
|
// rayQueryEXT type
|
||||||
|
Id makeRayQueryType();
|
||||||
|
|
||||||
// For querying about types.
|
// For querying about types.
|
||||||
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
|
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
|
||||||
|
@ -172,26 +200,40 @@ public:
|
||||||
Id getContainedTypeId(Id typeId) const;
|
Id getContainedTypeId(Id typeId) const;
|
||||||
Id getContainedTypeId(Id typeId, int) const;
|
Id getContainedTypeId(Id typeId, int) const;
|
||||||
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
|
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 isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
|
||||||
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
|
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
|
||||||
bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); }
|
bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); }
|
||||||
bool isMatrix(Id resultId) const { return isMatrixType(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 isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
|
||||||
bool isSampledImage(Id resultId) const { return isSampledImageType(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 isBoolType(Id typeId)
|
||||||
bool isIntType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
|
{ return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
|
||||||
bool isUintType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
|
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 isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; }
|
||||||
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
|
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 isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
|
||||||
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
|
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
|
||||||
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
|
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
|
||||||
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
|
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 isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
|
||||||
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
||||||
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
||||||
|
@ -203,9 +245,17 @@ public:
|
||||||
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
|
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
|
||||||
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
|
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
|
||||||
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
|
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)); }
|
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
|
int getScalarTypeWidth(Id typeId) const
|
||||||
{
|
{
|
||||||
Id scalarTypeId = getScalarTypeId(typeId);
|
Id scalarTypeId = getScalarTypeId(typeId);
|
||||||
|
@ -244,15 +294,24 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// For making new constants (will return old constant if the requested one was already made).
|
// 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 makeBoolConstant(bool b, bool specConstant = false);
|
||||||
Id makeInt8Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
|
Id makeInt8Constant(int i, bool specConstant = false)
|
||||||
Id makeUint8Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(8), u, specConstant); }
|
{ return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
|
||||||
Id makeInt16Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
|
Id makeUint8Constant(unsigned u, bool specConstant = false)
|
||||||
Id makeUint16Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(16), u, specConstant); }
|
{ return makeIntConstant(makeUintType(8), u, specConstant); }
|
||||||
Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
|
Id makeInt16Constant(int i, bool specConstant = false)
|
||||||
Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); }
|
{ return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
|
||||||
Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
|
Id makeUint16Constant(unsigned u, bool specConstant = false)
|
||||||
Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); }
|
{ 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 makeFloatConstant(float f, bool specConstant = false);
|
||||||
Id makeDoubleConstant(double d, bool specConstant = false);
|
Id makeDoubleConstant(double d, bool specConstant = false);
|
||||||
Id makeFloat16Constant(float f16, bool specConstant = false);
|
Id makeFloat16Constant(float f16, bool specConstant = false);
|
||||||
|
@ -264,13 +323,20 @@ public:
|
||||||
// Methods for adding information outside the CFG.
|
// Methods for adding information outside the CFG.
|
||||||
Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
|
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, int value1 = -1, int value2 = -1, int value3 = -1);
|
||||||
|
void addExecutionMode(Function*, ExecutionMode mode, const std::vector<unsigned>& literals);
|
||||||
|
void addExecutionModeId(Function*, ExecutionMode mode, const std::vector<Id>& operandIds);
|
||||||
void addName(Id, const char* name);
|
void addName(Id, const char* name);
|
||||||
void addMemberName(Id, int member, const char* name);
|
void addMemberName(Id, int member, const char* name);
|
||||||
void addDecoration(Id, Decoration, int num = -1);
|
void addDecoration(Id, Decoration, int num = -1);
|
||||||
void addDecoration(Id, Decoration, const char*);
|
void addDecoration(Id, Decoration, const char*);
|
||||||
|
void addDecoration(Id, Decoration, const std::vector<unsigned>& literals);
|
||||||
|
void addDecoration(Id, Decoration, const std::vector<const char*>& strings);
|
||||||
void addDecorationId(Id id, Decoration, Id idDecoration);
|
void addDecorationId(Id id, Decoration, Id idDecoration);
|
||||||
|
void addDecorationId(Id id, Decoration, const std::vector<Id>& operandIds);
|
||||||
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
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 char*);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<unsigned>& literals);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<const char*>& strings);
|
||||||
|
|
||||||
// At the end of what block do the next create*() instructions go?
|
// At the end of what block do the next create*() instructions go?
|
||||||
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
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.
|
// Make a shader-style function, and create its entry block if entry is non-zero.
|
||||||
// Return the function, pass back the entry.
|
// Return the function, pass back the entry.
|
||||||
// The returned pointer is only valid for the lifetime of this builder.
|
// The returned pointer is only valid for the lifetime of this builder.
|
||||||
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
|
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
|
||||||
const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
|
const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
|
||||||
|
|
||||||
// Create a return. An 'implicit' return is one not appearing in the source
|
// 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.
|
// 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.
|
// Generate all the code needed to finish up a function.
|
||||||
void leaveFunction();
|
void leaveFunction();
|
||||||
|
|
||||||
// Create a discard.
|
// Create block terminator instruction for certain statements like
|
||||||
void makeDiscard();
|
// discard, terminate-invocation, terminateRayEXT, or ignoreIntersectionEXT
|
||||||
|
void makeStatementTerminator(spv::Op opcode, const char *name);
|
||||||
|
|
||||||
// Create a global or function local or IO variable.
|
// 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.
|
// Create an intermediate with an undefined value.
|
||||||
Id createUndefined(Id type);
|
Id createUndefined(Id type);
|
||||||
|
|
||||||
// Store into an Id and return the l-value
|
// 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
|
// 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
|
// Create an OpAccessChain instruction
|
||||||
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
||||||
|
@ -314,6 +385,9 @@ public:
|
||||||
// Create an OpArrayLength instruction
|
// Create an OpArrayLength instruction
|
||||||
Id createArrayLength(Id base, unsigned int member);
|
Id createArrayLength(Id base, unsigned int member);
|
||||||
|
|
||||||
|
// Create an OpCooperativeMatrixLengthNV instruction
|
||||||
|
Id createCooperativeMatrixLength(Id type);
|
||||||
|
|
||||||
// Create an OpCompositeExtract instruction
|
// Create an OpCompositeExtract instruction
|
||||||
Id createCompositeExtract(Id composite, Id typeId, unsigned index);
|
Id createCompositeExtract(Id composite, Id typeId, unsigned index);
|
||||||
Id createCompositeExtract(Id composite, Id typeId, const std::vector<unsigned>& indexes);
|
Id createCompositeExtract(Id composite, Id typeId, const std::vector<unsigned>& indexes);
|
||||||
|
@ -402,7 +476,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
// 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.
|
// Emit the OpTextureQuery* instruction that was passed in.
|
||||||
// Figure out the right return value and type, and return it.
|
// Figure out the right return value and type, and return it.
|
||||||
|
@ -461,7 +536,7 @@ public:
|
||||||
// recursion stack can hold the memory for it.
|
// recursion stack can hold the memory for it.
|
||||||
//
|
//
|
||||||
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
|
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
|
||||||
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
|
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB);
|
||||||
|
|
||||||
// Add a branch to the innermost switch's merge block.
|
// Add a branch to the innermost switch's merge block.
|
||||||
void addSwitchBreak();
|
void addSwitchBreak();
|
||||||
|
@ -478,7 +553,7 @@ public:
|
||||||
Block &head, &body, &merge, &continue_target;
|
Block &head, &body, &merge, &continue_target;
|
||||||
private:
|
private:
|
||||||
LoopBlocks();
|
LoopBlocks();
|
||||||
LoopBlocks& operator=(const LoopBlocks&);
|
LoopBlocks& operator=(const LoopBlocks&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start a new loop and prepare the builder to generate code for it. Until
|
// Start a new loop and prepare the builder to generate code for it. Until
|
||||||
|
@ -535,21 +610,39 @@ public:
|
||||||
std::vector<Id> indexChain;
|
std::vector<Id> indexChain;
|
||||||
Id instr; // cache the instruction that generates this access chain
|
Id instr; // cache the instruction that generates this access chain
|
||||||
std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
|
std::vector<unsigned> 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 component; // a dynamic component index, can coexist with a swizzle,
|
||||||
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
|
// 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
|
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.
|
// Accumulate whether anything in the chain of structures has coherent decorations.
|
||||||
struct CoherentFlags {
|
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 coherent : 1;
|
||||||
unsigned devicecoherent : 1;
|
unsigned devicecoherent : 1;
|
||||||
unsigned queuefamilycoherent : 1;
|
unsigned queuefamilycoherent : 1;
|
||||||
unsigned workgroupcoherent : 1;
|
unsigned workgroupcoherent : 1;
|
||||||
unsigned subgroupcoherent : 1;
|
unsigned subgroupcoherent : 1;
|
||||||
|
unsigned shadercallcoherent : 1;
|
||||||
unsigned nonprivate : 1;
|
unsigned nonprivate : 1;
|
||||||
unsigned volatil : 1;
|
unsigned volatil : 1;
|
||||||
unsigned isImage : 1;
|
unsigned isImage : 1;
|
||||||
|
unsigned nonUniform : 1;
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
coherent = 0;
|
coherent = 0;
|
||||||
|
@ -557,23 +650,27 @@ public:
|
||||||
queuefamilycoherent = 0;
|
queuefamilycoherent = 0;
|
||||||
workgroupcoherent = 0;
|
workgroupcoherent = 0;
|
||||||
subgroupcoherent = 0;
|
subgroupcoherent = 0;
|
||||||
|
shadercallcoherent = 0;
|
||||||
nonprivate = 0;
|
nonprivate = 0;
|
||||||
volatil = 0;
|
volatil = 0;
|
||||||
isImage = 0;
|
isImage = 0;
|
||||||
|
nonUniform = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoherentFlags() { clear(); }
|
|
||||||
CoherentFlags operator |=(const CoherentFlags &other) {
|
CoherentFlags operator |=(const CoherentFlags &other) {
|
||||||
coherent |= other.coherent;
|
coherent |= other.coherent;
|
||||||
devicecoherent |= other.devicecoherent;
|
devicecoherent |= other.devicecoherent;
|
||||||
queuefamilycoherent |= other.queuefamilycoherent;
|
queuefamilycoherent |= other.queuefamilycoherent;
|
||||||
workgroupcoherent |= other.workgroupcoherent;
|
workgroupcoherent |= other.workgroupcoherent;
|
||||||
subgroupcoherent |= other.subgroupcoherent;
|
subgroupcoherent |= other.subgroupcoherent;
|
||||||
|
shadercallcoherent |= other.shadercallcoherent;
|
||||||
nonprivate |= other.nonprivate;
|
nonprivate |= other.nonprivate;
|
||||||
volatil |= other.volatil;
|
volatil |= other.volatil;
|
||||||
isImage |= other.isImage;
|
isImage |= other.isImage;
|
||||||
|
nonUniform |= other.nonUniform;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
CoherentFlags coherentFlags;
|
CoherentFlags coherentFlags;
|
||||||
};
|
};
|
||||||
|
@ -613,11 +710,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
||||||
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
|
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
|
||||||
|
AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
|
||||||
|
|
||||||
// push a dynamic component selection onto the access chain, only applicable with a
|
// push a dynamic component selection onto the access chain, only applicable with a
|
||||||
// non-trivial swizzle or no swizzle
|
// 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) {
|
if (accessChain.swizzle.size() != 1) {
|
||||||
accessChain.component = component;
|
accessChain.component = component;
|
||||||
|
@ -629,10 +728,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// use accessChain and swizzle to store value
|
// 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
|
// 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
|
// get the direct pointer for an l-value
|
||||||
Id accessChainGetLValue();
|
Id accessChainGetLValue();
|
||||||
|
@ -645,18 +753,24 @@ public:
|
||||||
// based on the resulting SPIR-V.
|
// based on the resulting SPIR-V.
|
||||||
void postProcess();
|
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
|
// Hook to visit each instruction in a block in a function
|
||||||
void postProcess(Instruction&);
|
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.
|
// Hook to visit each non-32-bit sized float/int operation in a block.
|
||||||
void postProcessType(const Instruction&, spv::Id typeId);
|
void postProcessType(const Instruction&, spv::Id typeId);
|
||||||
|
#endif
|
||||||
|
|
||||||
void dump(std::vector<unsigned int>&) const;
|
void dump(std::vector<unsigned int>&) const;
|
||||||
|
|
||||||
void createBranch(Block* block);
|
void createBranch(Block* block);
|
||||||
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
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<unsigned int>& operands);
|
||||||
|
|
||||||
// Sets to generate opcode for specialization constants.
|
// Sets to generate opcode for specialization constants.
|
||||||
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
|
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
|
||||||
|
@ -670,7 +784,7 @@ public:
|
||||||
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
|
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 value);
|
||||||
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2);
|
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2);
|
||||||
Id findCompositeConstant(Op typeClass, const std::vector<Id>& comps);
|
Id findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps);
|
||||||
Id findStructConstant(Id typeId, const std::vector<Id>& comps);
|
Id findStructConstant(Id typeId, const std::vector<Id>& comps);
|
||||||
Id collapseAccessChain();
|
Id collapseAccessChain();
|
||||||
void remapDynamicSwizzle();
|
void remapDynamicSwizzle();
|
||||||
|
@ -682,7 +796,8 @@ public:
|
||||||
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
|
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
|
||||||
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||||
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
void dumpModuleProcesses(std::vector<unsigned int>&) 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
|
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
||||||
SourceLanguage source;
|
SourceLanguage source;
|
||||||
|
@ -718,9 +833,15 @@ public:
|
||||||
std::vector<std::unique_ptr<Function> > functions;
|
std::vector<std::unique_ptr<Function> > functions;
|
||||||
|
|
||||||
// not output, internally used for quick & dirty canonical (unique) creation
|
// not output, internally used for quick & dirty canonical (unique) creation
|
||||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants; // map type opcodes to constant inst.
|
|
||||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants; // map struct-id to constant instructions
|
// map type opcodes to constant inst.
|
||||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes; // map type opcodes to type instructions
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants;
|
||||||
|
// map struct-id to constant instructions
|
||||||
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
|
||||||
|
// map type opcodes to type instructions
|
||||||
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
|
||||||
|
// list of OpConstantNull instructions
|
||||||
|
std::vector<Instruction*> nullConstants;
|
||||||
|
|
||||||
// stack of switches
|
// stack of switches
|
||||||
std::stack<Block*> switchMerges;
|
std::stack<Block*> switchMerges;
|
||||||
|
|
168
thirdparty/ShaderCompiler/spirv/SpvPostProcess.cpp
vendored
168
thirdparty/ShaderCompiler/spirv/SpvPostProcess.cpp
vendored
|
@ -39,6 +39,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -51,16 +52,13 @@ namespace spv {
|
||||||
#include "GLSL.std.450.h"
|
#include "GLSL.std.450.h"
|
||||||
#include "GLSL.ext.KHR.h"
|
#include "GLSL.ext.KHR.h"
|
||||||
#include "GLSL.ext.EXT.h"
|
#include "GLSL.ext.EXT.h"
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
#include "GLSL.ext.AMD.h"
|
#include "GLSL.ext.AMD.h"
|
||||||
#endif
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
#include "GLSL.ext.NV.h"
|
#include "GLSL.ext.NV.h"
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// Hook to visit each operand type and result type of an instruction.
|
// Hook to visit each operand type and result type of an instruction.
|
||||||
// Will be called multiple times for one instruction, once for each typed
|
// Will be called multiple times for one instruction, once for each typed
|
||||||
// operand and the result.
|
// operand and the result.
|
||||||
|
@ -118,12 +116,48 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
|
||||||
case OpAccessChain:
|
case OpAccessChain:
|
||||||
case OpPtrAccessChain:
|
case OpPtrAccessChain:
|
||||||
case OpCopyObject:
|
case OpCopyObject:
|
||||||
|
break;
|
||||||
case OpFConvert:
|
case OpFConvert:
|
||||||
case OpSConvert:
|
case OpSConvert:
|
||||||
case OpUConvert:
|
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;
|
break;
|
||||||
case OpExtInst:
|
case OpExtInst:
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
switch (inst.getImmediateOperand(1)) {
|
switch (inst.getImmediateOperand(1)) {
|
||||||
case GLSLstd450Frexp:
|
case GLSLstd450Frexp:
|
||||||
case GLSLstd450FrexpStruct:
|
case GLSLstd450FrexpStruct:
|
||||||
|
@ -139,7 +173,6 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (basicTypeOp == OpTypeFloat && width == 16)
|
if (basicTypeOp == OpTypeFloat && width == 16)
|
||||||
|
@ -185,12 +218,10 @@ void Builder::postProcess(Instruction& inst)
|
||||||
addCapability(CapabilityImageQuery);
|
addCapability(CapabilityImageQuery);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case OpGroupNonUniformPartitionNV:
|
case OpGroupNonUniformPartitionNV:
|
||||||
addExtension(E_SPV_NV_shader_subgroup_partitioned);
|
addExtension(E_SPV_NV_shader_subgroup_partitioned);
|
||||||
addCapability(CapabilityGroupNonUniformPartitionedNV);
|
addCapability(CapabilityGroupNonUniformPartitionedNV);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case OpLoad:
|
case OpLoad:
|
||||||
case OpStore:
|
case OpStore:
|
||||||
|
@ -258,10 +289,9 @@ void Builder::postProcess(Instruction& inst)
|
||||||
assert(inst.getNumOperands() >= 3);
|
assert(inst.getNumOperands() >= 3);
|
||||||
unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1);
|
unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1);
|
||||||
assert(memoryAccess & MemoryAccessAlignedMask);
|
assert(memoryAccess & MemoryAccessAlignedMask);
|
||||||
|
static_cast<void>(memoryAccess);
|
||||||
// Compute the index of the alignment operand.
|
// Compute the index of the alignment operand.
|
||||||
int alignmentIdx = 2;
|
int alignmentIdx = 2;
|
||||||
if (memoryAccess & MemoryAccessVolatileMask)
|
|
||||||
alignmentIdx++;
|
|
||||||
if (inst.getOpCode() == OpStore)
|
if (inst.getOpCode() == OpStore)
|
||||||
alignmentIdx++;
|
alignmentIdx++;
|
||||||
// Merge new and old (mis)alignment
|
// Merge new and old (mis)alignment
|
||||||
|
@ -290,17 +320,16 @@ void Builder::postProcess(Instruction& inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// comment in header
|
// 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<const Block*> reachableBlocks;
|
std::unordered_set<const Block*> reachableBlocks;
|
||||||
|
std::unordered_map<Block*, Block*> headerForUnreachableContinue;
|
||||||
|
std::unordered_set<Block*> unreachableMerges;
|
||||||
std::unordered_set<Id> unreachableDefinitions;
|
std::unordered_set<Id> unreachableDefinitions;
|
||||||
// Collect IDs defined in unreachable blocks. For each function, label the
|
// Collect IDs defined in unreachable blocks. For each function, label the
|
||||||
// reachable blocks first. Then for each unreachable block, collect 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++) {
|
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
|
||||||
Function* f = *fi;
|
Function* f = *fi;
|
||||||
Block* entry = f->getEntryBlock();
|
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++) {
|
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
|
||||||
Block* b = *bi;
|
Block* b = *bi;
|
||||||
if (reachableBlocks.count(b) == 0) {
|
if (unreachableMerges.count(b) != 0 || headerForUnreachableContinue.count(b) != 0) {
|
||||||
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
|
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());
|
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
|
// Remove unneeded decorations, for unreachable instructions
|
||||||
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
|
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
|
||||||
[&unreachableDefinitions](std::unique_ptr<Instruction>& I) -> bool {
|
[&unreachableDefinitions](std::unique_ptr<Instruction>& I) -> bool {
|
||||||
|
@ -325,14 +379,29 @@ void Builder::postProcess()
|
||||||
return unreachableDefinitions.count(decoration_id) != 0;
|
return unreachableDefinitions.count(decoration_id) != 0;
|
||||||
}),
|
}),
|
||||||
decorations.end());
|
decorations.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
// comment in header
|
||||||
|
void Builder::postProcessFeatures() {
|
||||||
// Add per-instruction capabilities, extensions, etc.,
|
// Add per-instruction capabilities, extensions, etc.,
|
||||||
|
|
||||||
// process all reachable instructions...
|
// Look for any 8/16 bit type in physical storage buffer class, and set the
|
||||||
for (auto bi = reachableBlocks.cbegin(); bi != reachableBlocks.cend(); ++bi) {
|
// appropriate capability. This happens in createSpvVariable for other storage
|
||||||
const Block* block = *bi;
|
// classes, but there isn't always a variable for physical storage buffer.
|
||||||
const auto function = [this](const std::unique_ptr<Instruction>& inst) { postProcessReachable(*inst.get()); };
|
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
|
||||||
std::for_each(block->getInstructions().begin(), block->getInstructions().end(), function);
|
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
|
// 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
|
// If any Vulkan memory model-specific functionality is used, update the
|
||||||
// appropriate capability. This happens in createSpvVariable for other storage
|
// OpMemoryModel to match.
|
||||||
// classes, but there isn't always a variable for physical storage buffer.
|
if (capabilities.find(spv::CapabilityVulkanMemoryModelKHR) != capabilities.end()) {
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
|
memoryModel = spv::MemoryModelVulkanKHR;
|
||||||
Instruction* type = groupedTypes[OpTypePointer][t];
|
addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
|
||||||
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)) {
|
// Add Aliased decoration if there's more than one Workgroup Block variable.
|
||||||
addExtension(spv::E_SPV_KHR_16bit_storage);
|
if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
|
||||||
addCapability(spv::CapabilityStorageBuffer16BitAccess);
|
assert(entryPoints.size() == 1);
|
||||||
|
auto &ep = entryPoints[0];
|
||||||
|
|
||||||
|
std::vector<Id> 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
|
}; // end spv namespace
|
||||||
|
|
181
thirdparty/ShaderCompiler/spirv/SpvTools.cpp
vendored
181
thirdparty/ShaderCompiler/spirv/SpvTools.cpp
vendored
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014-2016 LunarG, Inc.
|
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2018 Google, Inc.
|
// Copyright (C) 2018-2020 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -44,7 +44,6 @@
|
||||||
|
|
||||||
#include "SpvTools.h"
|
#include "SpvTools.h"
|
||||||
#include "spirv-tools/optimizer.hpp"
|
#include "spirv-tools/optimizer.hpp"
|
||||||
#include "spirv-tools/libspirv.h"
|
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
@ -52,8 +51,23 @@ namespace glslang {
|
||||||
spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger)
|
spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger)
|
||||||
{
|
{
|
||||||
switch (spvVersion.vulkan) {
|
switch (spvVersion.vulkan) {
|
||||||
case glslang::EShTargetVulkan_1_0: return spv_target_env::SPV_ENV_VULKAN_1_0;
|
case glslang::EShTargetVulkan_1_0:
|
||||||
case glslang::EShTargetVulkan_1_1: return spv_target_env::SPV_ENV_VULKAN_1_1;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -65,63 +79,10 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
|
||||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
|
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Callback passed to spvtools::Optimizer::SetMessageConsumer
|
||||||
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
void OptimizerMesssageConsumer(spv_message_level_t level, const char *source,
|
||||||
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
|
const spv_position_t &position, const char *message)
|
||||||
{
|
{
|
||||||
// disassemble
|
|
||||||
spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3);
|
|
||||||
spv_text text;
|
|
||||||
spv_diagnostic diagnostic = nullptr;
|
|
||||||
spvBinaryToText(context, spirv.data(), spirv.size(),
|
|
||||||
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT,
|
|
||||||
&text, &diagnostic);
|
|
||||||
|
|
||||||
// dump
|
|
||||||
if (diagnostic == nullptr)
|
|
||||||
out << text->str;
|
|
||||||
else
|
|
||||||
spvDiagnosticPrint(diagnostic);
|
|
||||||
|
|
||||||
// teardown
|
|
||||||
spvDiagnosticDestroy(diagnostic);
|
|
||||||
spvContextDestroy(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
|
||||||
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
|
||||||
spv::SpvBuildLogger* logger)
|
|
||||||
{
|
|
||||||
// validate
|
|
||||||
spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
|
|
||||||
spv_const_binary_t binary = { spirv.data(), spirv.size() };
|
|
||||||
spv_diagnostic diagnostic = nullptr;
|
|
||||||
spv_validator_options options = spvValidatorOptionsCreate();
|
|
||||||
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
|
|
||||||
spvValidateWithOptions(context, options, &binary, &diagnostic);
|
|
||||||
|
|
||||||
// report
|
|
||||||
if (diagnostic != nullptr) {
|
|
||||||
logger->error("SPIRV-Tools Validation Errors");
|
|
||||||
logger->error(diagnostic->error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// tear down
|
|
||||||
spvValidatorOptionsDestroy(options);
|
|
||||||
spvDiagnosticDestroy(diagnostic);
|
|
||||||
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<unsigned int>& spirv,
|
|
||||||
spv::SpvBuildLogger*, const SpvOptions* options)
|
|
||||||
{
|
|
||||||
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2;
|
|
||||||
|
|
||||||
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;
|
auto &out = std::cerr;
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
|
@ -150,15 +111,81 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>
|
||||||
out << " " << message;
|
out << " " << message;
|
||||||
}
|
}
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// 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<unsigned int>& 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<unsigned int>& spirv,
|
||||||
|
spv_target_env requested_context)
|
||||||
|
{
|
||||||
|
// disassemble
|
||||||
|
spv_context context = spvContextCreate(requested_context);
|
||||||
|
spv_text text;
|
||||||
|
spv_diagnostic diagnostic = nullptr;
|
||||||
|
spvBinaryToText(context, spirv.data(), spirv.size(),
|
||||||
|
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT,
|
||||||
|
&text, &diagnostic);
|
||||||
|
|
||||||
|
// dump
|
||||||
|
if (diagnostic == nullptr)
|
||||||
|
out << text->str;
|
||||||
|
else
|
||||||
|
spvDiagnosticPrint(diagnostic);
|
||||||
|
|
||||||
|
// teardown
|
||||||
|
spvDiagnosticDestroy(diagnostic);
|
||||||
|
spvContextDestroy(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||||
|
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger* logger, bool prelegalization)
|
||||||
|
{
|
||||||
|
// validate
|
||||||
|
spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
|
||||||
|
spv_const_binary_t binary = { spirv.data(), spirv.size() };
|
||||||
|
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
|
||||||
|
if (diagnostic != nullptr) {
|
||||||
|
logger->error("SPIRV-Tools Validation Errors");
|
||||||
|
logger->error(diagnostic->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tear down
|
||||||
|
spvValidatorOptionsDestroy(options);
|
||||||
|
spvDiagnosticDestroy(diagnostic);
|
||||||
|
spvContextDestroy(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger* logger, const SpvOptions* options)
|
||||||
|
{
|
||||||
|
spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger);
|
||||||
|
|
||||||
|
spvtools::Optimizer optimizer(target_env);
|
||||||
|
optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
|
||||||
|
|
||||||
// If debug (specifically source line info) is being generated, propagate
|
// If debug (specifically source line info) is being generated, propagate
|
||||||
// line information into all SPIR-V instructions. This avoids loss of
|
// line information into all SPIR-V instructions. This avoids loss of
|
||||||
// information when instructions are deleted or moved. Later, remove
|
// information when instructions are deleted or moved. Later, remove
|
||||||
// redundant information to minimize final SPRIR-V size.
|
// redundant information to minimize final SPRIR-V size.
|
||||||
if (options->generateDebugInfo) {
|
if (options->stripDebugInfo) {
|
||||||
optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
|
optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
|
||||||
}
|
}
|
||||||
|
optimizer.RegisterPass(spvtools::CreateWrapOpKillPass());
|
||||||
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||||
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
|
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
|
||||||
optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass());
|
optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass());
|
||||||
|
@ -180,18 +207,36 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>
|
||||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
||||||
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass());
|
||||||
if (options->optimizeSize) {
|
if (options->optimizeSize) {
|
||||||
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
|
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::CreateAggressiveDCEPass());
|
||||||
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
|
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
|
||||||
if (options->generateDebugInfo) {
|
|
||||||
optimizer.RegisterPass(spvtools::CreateRedundantLineInfoElimPass());
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
optimizer.Run(spirv.data(), spirv.size(), &spirv);
|
// 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<unsigned int>& 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
|
}; // end namespace glslang
|
||||||
|
|
27
thirdparty/ShaderCompiler/spirv/SpvTools.h
vendored
27
thirdparty/ShaderCompiler/spirv/SpvTools.h
vendored
|
@ -41,8 +41,11 @@
|
||||||
#ifndef GLSLANG_SPV_TOOLS_H
|
#ifndef GLSLANG_SPV_TOOLS_H
|
||||||
#define GLSLANG_SPV_TOOLS_H
|
#define GLSLANG_SPV_TOOLS_H
|
||||||
|
|
||||||
|
#if ENABLE_OPT
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include "spirv-tools/libspirv.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../glslang/MachineIndependent/localintermediate.h"
|
#include "../glslang/MachineIndependent/localintermediate.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
@ -50,9 +53,10 @@
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
struct SpvOptions {
|
struct SpvOptions {
|
||||||
SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
|
SpvOptions() : generateDebugInfo(false), stripDebugInfo(false), disableOptimizer(true),
|
||||||
optimizeSize(false), disassemble(false), validate(false) { }
|
optimizeSize(false), disassemble(false), validate(false) { }
|
||||||
bool generateDebugInfo;
|
bool generateDebugInfo;
|
||||||
|
bool stripDebugInfo;
|
||||||
bool disableOptimizer;
|
bool disableOptimizer;
|
||||||
bool optimizeSize;
|
bool optimizeSize;
|
||||||
bool disassemble;
|
bool disassemble;
|
||||||
|
@ -61,20 +65,29 @@ struct SpvOptions {
|
||||||
|
|
||||||
#if ENABLE_OPT
|
#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<unsigned int>& spirv);
|
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
|
||||||
|
|
||||||
|
// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment.
|
||||||
|
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
|
||||||
|
spv_target_env requested_context);
|
||||||
|
|
||||||
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||||
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
spv::SpvBuildLogger*);
|
spv::SpvBuildLogger*, bool prelegalization);
|
||||||
|
|
||||||
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
|
// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process.
|
||||||
// legalizing HLSL SPIR-V.
|
void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
|
||||||
spv::SpvBuildLogger*, const SpvOptions*);
|
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<unsigned int>& spirv, spv::SpvBuildLogger*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}; // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // GLSLANG_SPV_TOOLS_H
|
#endif // GLSLANG_SPV_TOOLS_H
|
55
thirdparty/ShaderCompiler/spirv/disassemble.cpp
vendored
55
thirdparty/ShaderCompiler/spirv/disassemble.cpp
vendored
|
@ -46,32 +46,21 @@
|
||||||
|
|
||||||
#include "disassemble.h"
|
#include "disassemble.h"
|
||||||
#include "doc.h"
|
#include "doc.h"
|
||||||
#include "SpvTools.h"
|
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// Include C-based headers that don't have a namespace
|
// Include C-based headers that don't have a namespace
|
||||||
#include "GLSL.std.450.h"
|
#include "GLSL.std.450.h"
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
#include "GLSL.ext.AMD.h"
|
#include "GLSL.ext.AMD.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
#include "GLSL.ext.NV.h"
|
#include "GLSL.ext.NV.h"
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
|
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
static const char* GLSLextAMDGetDebugNames(const char*, unsigned);
|
static const char* GLSLextAMDGetDebugNames(const char*, unsigned);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
static const char* GLSLextNVGetDebugNames(const char*, unsigned);
|
static const char* GLSLextNVGetDebugNames(const char*, unsigned);
|
||||||
#endif
|
|
||||||
|
|
||||||
static void Kill(std::ostream& out, const char* message)
|
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
|
// used to identify the extended instruction library imported when printing
|
||||||
enum ExtInstSet {
|
enum ExtInstSet {
|
||||||
GLSL450Inst,
|
GLSL450Inst,
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
GLSLextAMDInst,
|
GLSLextAMDInst,
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
GLSLextNVInst,
|
GLSLextNVInst,
|
||||||
#endif
|
|
||||||
|
|
||||||
OpenCLExtInst,
|
OpenCLExtInst,
|
||||||
|
NonSemanticDebugPrintfExtInst,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Container class for a single instance of a SPIR-V stream, with methods for disassembly.
|
// Container class for a single instance of a SPIR-V stream, with methods for disassembly.
|
||||||
|
@ -497,16 +480,17 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
||||||
if (opCode == OpExtInst) {
|
if (opCode == OpExtInst) {
|
||||||
ExtInstSet extInstSet = GLSL450Inst;
|
ExtInstSet extInstSet = GLSL450Inst;
|
||||||
const char* name = idDescriptor[stream[word - 2]].c_str();
|
const char* name = idDescriptor[stream[word - 2]].c_str();
|
||||||
if (0 == memcmp("OpenCL", name, 6)) {
|
if (strcmp("OpenCL.std", name) == 0) {
|
||||||
extInstSet = OpenCLExtInst;
|
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 ||
|
} 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_trinary_minmax, name) == 0 ||
|
||||||
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
|
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
|
||||||
strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) {
|
strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) {
|
||||||
extInstSet = GLSLextAMDInst;
|
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_geometry_shader_passthrough, name) == 0 ||
|
||||||
strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 ||
|
strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 ||
|
||||||
|
@ -514,22 +498,19 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
||||||
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
|
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
|
||||||
strcmp(spv::E_SPV_NV_mesh_shader, name) == 0) {
|
strcmp(spv::E_SPV_NV_mesh_shader, name) == 0) {
|
||||||
extInstSet = GLSLextNVInst;
|
extInstSet = GLSLextNVInst;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
unsigned entrypoint = stream[word - 1];
|
unsigned entrypoint = stream[word - 1];
|
||||||
if (extInstSet == GLSL450Inst) {
|
if (extInstSet == GLSL450Inst) {
|
||||||
if (entrypoint < GLSLstd450Count) {
|
if (entrypoint < GLSLstd450Count) {
|
||||||
out << "(" << GlslStd450DebugNames[entrypoint] << ")";
|
out << "(" << GlslStd450DebugNames[entrypoint] << ")";
|
||||||
}
|
}
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if (extInstSet == GLSLextAMDInst) {
|
} else if (extInstSet == GLSLextAMDInst) {
|
||||||
out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")";
|
out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")";
|
||||||
#endif
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
}
|
}
|
||||||
else if (extInstSet == GLSLextNVInst) {
|
else if (extInstSet == GLSLextNVInst) {
|
||||||
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
|
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
|
||||||
#endif
|
} else if (extInstSet == NonSemanticDebugPrintfExtInst) {
|
||||||
|
out << "(DebugPrintf)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -537,6 +518,10 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
||||||
case OperandLiteralString:
|
case OperandLiteralString:
|
||||||
numOperands -= disassembleString();
|
numOperands -= disassembleString();
|
||||||
break;
|
break;
|
||||||
|
case OperandVariableLiteralStrings:
|
||||||
|
while (numOperands > 0)
|
||||||
|
numOperands -= disassembleString();
|
||||||
|
return;
|
||||||
case OperandMemoryAccess:
|
case OperandMemoryAccess:
|
||||||
outputMask(OperandMemoryAccess, stream[word++]);
|
outputMask(OperandMemoryAccess, stream[word++]);
|
||||||
--numOperands;
|
--numOperands;
|
||||||
|
@ -648,9 +633,11 @@ static void GLSLstd450GetDebugNames(const char** names)
|
||||||
names[GLSLstd450InterpolateAtCentroid] = "InterpolateAtCentroid";
|
names[GLSLstd450InterpolateAtCentroid] = "InterpolateAtCentroid";
|
||||||
names[GLSLstd450InterpolateAtSample] = "InterpolateAtSample";
|
names[GLSLstd450InterpolateAtSample] = "InterpolateAtSample";
|
||||||
names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset";
|
names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset";
|
||||||
|
names[GLSLstd450NMin] = "NMin";
|
||||||
|
names[GLSLstd450NMax] = "NMax";
|
||||||
|
names[GLSLstd450NClamp] = "NClamp";
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint)
|
static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
{
|
{
|
||||||
if (strcmp(name, spv::E_SPV_AMD_shader_ballot) == 0) {
|
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";
|
return "Bad";
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
{
|
{
|
||||||
if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 ||
|
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_SPV_NV_geometry_shader_passthrough) == 0 ||
|
||||||
strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
|
strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
|
||||||
strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 ||
|
strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 ||
|
||||||
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 ||
|
strcmp(name, spv::E_SPV_NVX_multiview_per_view_attributes) == 0 ||
|
||||||
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 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_mesh_shader) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_shader_image_footprint) == 0) {
|
||||||
switch (entrypoint) {
|
switch (entrypoint) {
|
||||||
// NV builtins
|
// NV builtins
|
||||||
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||||
|
@ -729,6 +715,8 @@ static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||||
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
||||||
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
||||||
|
case CapabilityImageFootprintNV: return "ImageFootprintNV";
|
||||||
|
case CapabilitySampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV";
|
||||||
|
|
||||||
// NV Decorations
|
// NV Decorations
|
||||||
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
||||||
|
@ -745,7 +733,6 @@ static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
}
|
}
|
||||||
return "Bad";
|
return "Bad";
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
|
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,6 +48,6 @@ namespace spv {
|
||||||
// disassemble with glslang custom disassembler
|
// disassemble with glslang custom disassembler
|
||||||
void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
|
void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
|
||||||
|
|
||||||
}; // end namespace spv
|
} // end namespace spv
|
||||||
|
|
||||||
#endif // disassembler_H
|
#endif // disassembler_H
|
||||||
|
|
485
thirdparty/ShaderCompiler/spirv/doc.cpp
vendored
485
thirdparty/ShaderCompiler/spirv/doc.cpp
vendored
|
@ -1,5 +1,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -50,12 +51,8 @@ namespace spv {
|
||||||
// Include C-based headers that don't have a namespace
|
// Include C-based headers that don't have a namespace
|
||||||
#include "GLSL.ext.KHR.h"
|
#include "GLSL.ext.KHR.h"
|
||||||
#include "GLSL.ext.EXT.h"
|
#include "GLSL.ext.EXT.h"
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
#include "GLSL.ext.AMD.h"
|
#include "GLSL.ext.AMD.h"
|
||||||
#endif
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
#include "GLSL.ext.NV.h"
|
#include "GLSL.ext.NV.h"
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,22 +95,17 @@ const char* ExecutionModelString(int model)
|
||||||
case 4: return "Fragment";
|
case 4: return "Fragment";
|
||||||
case 5: return "GLCompute";
|
case 5: return "GLCompute";
|
||||||
case 6: return "Kernel";
|
case 6: return "Kernel";
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case ExecutionModelTaskNV: return "TaskNV";
|
case ExecutionModelTaskNV: return "TaskNV";
|
||||||
case ExecutionModelMeshNV: return "MeshNV";
|
case ExecutionModelMeshNV: return "MeshNV";
|
||||||
#endif
|
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
case ExecutionModelRayGenerationKHR: return "RayGenerationKHR";
|
||||||
case ExecutionModelRayGenerationNV: return "RayGenerationNV";
|
case ExecutionModelIntersectionKHR: return "IntersectionKHR";
|
||||||
case ExecutionModelIntersectionNV: return "IntersectionNV";
|
case ExecutionModelAnyHitKHR: return "AnyHitKHR";
|
||||||
case ExecutionModelAnyHitNV: return "AnyHitNV";
|
case ExecutionModelClosestHitKHR: return "ClosestHitKHR";
|
||||||
case ExecutionModelClosestHitNV: return "ClosestHitNV";
|
case ExecutionModelMissKHR: return "MissKHR";
|
||||||
case ExecutionModelMissNV: return "MissNV";
|
case ExecutionModelCallableKHR: return "CallableKHR";
|
||||||
case ExecutionModelCallableNV: return "CallableNV";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +134,7 @@ const char* MemoryString(int mem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ExecutionModeCeiling = 33;
|
const int ExecutionModeCeiling = 40;
|
||||||
|
|
||||||
const char* ExecutionModeString(int mode)
|
const char* ExecutionModeString(int mode)
|
||||||
{
|
{
|
||||||
|
@ -181,15 +173,40 @@ const char* ExecutionModeString(int mode)
|
||||||
case 31: return "ContractionOff";
|
case 31: return "ContractionOff";
|
||||||
case 32: return "Bad";
|
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 ExecutionModeOutputLinesNV: return "OutputLinesNV";
|
||||||
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
|
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
|
||||||
case ExecutionModeOutputTrianglesNV: return "OutputTrianglesNV";
|
case ExecutionModeOutputTrianglesNV: return "OutputTrianglesNV";
|
||||||
case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV";
|
case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV";
|
||||||
case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV";
|
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:
|
case ExecutionModeCeiling:
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
|
@ -213,14 +230,12 @@ const char* StorageClassString(int StorageClass)
|
||||||
case 11: return "Image";
|
case 11: return "Image";
|
||||||
case 12: return "StorageBuffer";
|
case 12: return "StorageBuffer";
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
case StorageClassRayPayloadKHR: return "RayPayloadKHR";
|
||||||
case StorageClassRayPayloadNV: return "RayPayloadNV";
|
case StorageClassHitAttributeKHR: return "HitAttributeKHR";
|
||||||
case StorageClassHitAttributeNV: return "HitAttributeNV";
|
case StorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR";
|
||||||
case StorageClassIncomingRayPayloadNV: return "IncomingRayPayloadNV";
|
case StorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR";
|
||||||
case StorageClassShaderRecordBufferNV: return "ShaderRecordBufferNV";
|
case StorageClassCallableDataKHR: return "CallableDataKHR";
|
||||||
case StorageClassCallableDataNV: return "CallableDataNV";
|
case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR";
|
||||||
case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT";
|
case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT";
|
||||||
|
|
||||||
|
@ -282,10 +297,7 @@ const char* DecorationString(int decoration)
|
||||||
case DecorationCeiling:
|
case DecorationCeiling:
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case DecorationExplicitInterpAMD: return "ExplicitInterpAMD";
|
case DecorationExplicitInterpAMD: return "ExplicitInterpAMD";
|
||||||
#endif
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
||||||
case DecorationPassthroughNV: return "PassthroughNV";
|
case DecorationPassthroughNV: return "PassthroughNV";
|
||||||
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
||||||
|
@ -294,7 +306,6 @@ const char* DecorationString(int decoration)
|
||||||
case DecorationPerViewNV: return "PerViewNV";
|
case DecorationPerViewNV: return "PerViewNV";
|
||||||
case DecorationPerTaskNV: return "PerTaskNV";
|
case DecorationPerTaskNV: return "PerTaskNV";
|
||||||
case DecorationPerVertexNV: return "PerVertexNV";
|
case DecorationPerVertexNV: return "PerVertexNV";
|
||||||
#endif
|
|
||||||
|
|
||||||
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
|
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
|
||||||
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
||||||
|
@ -362,9 +373,10 @@ const char* BuiltInString(int builtIn)
|
||||||
case 4424: return "BaseVertex";
|
case 4424: return "BaseVertex";
|
||||||
case 4425: return "BaseInstance";
|
case 4425: return "BaseInstance";
|
||||||
case 4426: return "DrawIndex";
|
case 4426: return "DrawIndex";
|
||||||
|
case 4432: return "PrimitiveShadingRateKHR";
|
||||||
|
case 4444: return "ShadingRateKHR";
|
||||||
case 5014: return "FragStencilRefEXT";
|
case 5014: return "FragStencilRefEXT";
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case 4992: return "BaryCoordNoPerspAMD";
|
case 4992: return "BaryCoordNoPerspAMD";
|
||||||
case 4993: return "BaryCoordNoPerspCentroidAMD";
|
case 4993: return "BaryCoordNoPerspCentroidAMD";
|
||||||
case 4994: return "BaryCoordNoPerspSampleAMD";
|
case 4994: return "BaryCoordNoPerspSampleAMD";
|
||||||
|
@ -372,23 +384,21 @@ const char* BuiltInString(int builtIn)
|
||||||
case 4996: return "BaryCoordSmoothCentroidAMD";
|
case 4996: return "BaryCoordSmoothCentroidAMD";
|
||||||
case 4997: return "BaryCoordSmoothSampleAMD";
|
case 4997: return "BaryCoordSmoothSampleAMD";
|
||||||
case 4998: return "BaryCoordPullModelAMD";
|
case 4998: return "BaryCoordPullModelAMD";
|
||||||
#endif
|
case BuiltInLaunchIdKHR: return "LaunchIdKHR";
|
||||||
|
case BuiltInLaunchSizeKHR: return "LaunchSizeKHR";
|
||||||
#ifdef NV_EXTENSIONS
|
case BuiltInWorldRayOriginKHR: return "WorldRayOriginKHR";
|
||||||
case BuiltInLaunchIdNV: return "LaunchIdNV";
|
case BuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR";
|
||||||
case BuiltInLaunchSizeNV: return "LaunchSizeNV";
|
case BuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR";
|
||||||
case BuiltInWorldRayOriginNV: return "WorldRayOriginNV";
|
case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR";
|
||||||
case BuiltInWorldRayDirectionNV: return "WorldRayDirectionNV";
|
case BuiltInRayTminKHR: return "RayTminKHR";
|
||||||
case BuiltInObjectRayOriginNV: return "ObjectRayOriginNV";
|
case BuiltInRayTmaxKHR: return "RayTmaxKHR";
|
||||||
case BuiltInObjectRayDirectionNV: return "ObjectRayDirectionNV";
|
case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR";
|
||||||
case BuiltInRayTminNV: return "RayTminNV";
|
case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR";
|
||||||
case BuiltInRayTmaxNV: return "RayTmaxNV";
|
case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR";
|
||||||
case BuiltInInstanceCustomIndexNV: return "InstanceCustomIndexNV";
|
case BuiltInWorldToObjectKHR: return "WorldToObjectKHR";
|
||||||
case BuiltInObjectToWorldNV: return "ObjectToWorldNV";
|
|
||||||
case BuiltInWorldToObjectNV: return "WorldToObjectNV";
|
|
||||||
case BuiltInHitTNV: return "HitTNV";
|
case BuiltInHitTNV: return "HitTNV";
|
||||||
case BuiltInHitKindNV: return "HitKindNV";
|
case BuiltInHitKindKHR: return "HitKindKHR";
|
||||||
case BuiltInIncomingRayFlagsNV: return "IncomingRayFlagsNV";
|
case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR";
|
||||||
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||||
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
|
@ -398,15 +408,12 @@ const char* BuiltInString(int builtIn)
|
||||||
// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
|
// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
|
||||||
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
||||||
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||||
#endif
|
|
||||||
|
|
||||||
case BuiltInFragSizeEXT: return "FragSizeEXT";
|
case BuiltInFragSizeEXT: return "FragSizeEXT";
|
||||||
case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
|
case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
|
||||||
|
|
||||||
case 5264: return "FullyCoveredEXT";
|
case 5264: return "FullyCoveredEXT";
|
||||||
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case BuiltInTaskCountNV: return "TaskCountNV";
|
case BuiltInTaskCountNV: return "TaskCountNV";
|
||||||
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
|
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
|
||||||
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||||
|
@ -415,7 +422,11 @@ const char* BuiltInString(int builtIn)
|
||||||
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
|
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
|
||||||
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
|
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
|
||||||
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";
|
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";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
|
@ -514,6 +525,8 @@ const char* ImageFormatString(int format)
|
||||||
case 37: return "Rg8ui";
|
case 37: return "Rg8ui";
|
||||||
case 38: return "R16ui";
|
case 38: return "R16ui";
|
||||||
case 39: return "R8ui";
|
case 39: return "R8ui";
|
||||||
|
case 40: return "R64ui";
|
||||||
|
case 41: return "R64i";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "Bad";
|
return "Bad";
|
||||||
|
@ -575,7 +588,7 @@ const char* ImageChannelDataTypeString(int type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ImageOperandsCeiling = 12;
|
const int ImageOperandsCeiling = 14;
|
||||||
|
|
||||||
const char* ImageOperandsString(int format)
|
const char* ImageOperandsString(int format)
|
||||||
{
|
{
|
||||||
|
@ -592,6 +605,8 @@ const char* ImageOperandsString(int format)
|
||||||
case ImageOperandsMakeTexelVisibleKHRShift: return "MakeTexelVisibleKHR";
|
case ImageOperandsMakeTexelVisibleKHRShift: return "MakeTexelVisibleKHR";
|
||||||
case ImageOperandsNonPrivateTexelKHRShift: return "NonPrivateTexelKHR";
|
case ImageOperandsNonPrivateTexelKHRShift: return "NonPrivateTexelKHR";
|
||||||
case ImageOperandsVolatileTexelKHRShift: return "VolatileTexelKHR";
|
case ImageOperandsVolatileTexelKHRShift: return "VolatileTexelKHR";
|
||||||
|
case ImageOperandsSignExtendShift: return "SignExtend";
|
||||||
|
case ImageOperandsZeroExtendShift: return "ZeroExtend";
|
||||||
|
|
||||||
case ImageOperandsCeiling:
|
case ImageOperandsCeiling:
|
||||||
default:
|
default:
|
||||||
|
@ -674,15 +689,20 @@ const char* SelectControlString(int cont)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int LoopControlCeiling = 4;
|
const int LoopControlCeiling = LoopControlPartialCountShift + 1;
|
||||||
|
|
||||||
const char* LoopControlString(int cont)
|
const char* LoopControlString(int cont)
|
||||||
{
|
{
|
||||||
switch (cont) {
|
switch (cont) {
|
||||||
case 0: return "Unroll";
|
case LoopControlUnrollShift: return "Unroll";
|
||||||
case 1: return "DontUnroll";
|
case LoopControlDontUnrollShift: return "DontUnroll";
|
||||||
case 2: return "DependencyInfinite";
|
case LoopControlDependencyInfiniteShift: return "DependencyInfinite";
|
||||||
case 3: return "DependencyLength";
|
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:
|
case LoopControlCeiling:
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
|
@ -763,11 +783,9 @@ const char* GroupOperationString(int gop)
|
||||||
case GroupOperationInclusiveScan: return "InclusiveScan";
|
case GroupOperationInclusiveScan: return "InclusiveScan";
|
||||||
case GroupOperationExclusiveScan: return "ExclusiveScan";
|
case GroupOperationExclusiveScan: return "ExclusiveScan";
|
||||||
case GroupOperationClusteredReduce: return "ClusteredReduce";
|
case GroupOperationClusteredReduce: return "ClusteredReduce";
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case GroupOperationPartitionedReduceNV: return "PartitionedReduceNV";
|
case GroupOperationPartitionedReduceNV: return "PartitionedReduceNV";
|
||||||
case GroupOperationPartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV";
|
case GroupOperationPartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV";
|
||||||
case GroupOperationPartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV";
|
case GroupOperationPartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV";
|
||||||
#endif
|
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
|
@ -875,26 +893,23 @@ const char* CapabilityString(int info)
|
||||||
case CapabilityStoragePushConstant16: return "StoragePushConstant16";
|
case CapabilityStoragePushConstant16: return "StoragePushConstant16";
|
||||||
case CapabilityStorageInputOutput16: return "StorageInputOutput16";
|
case CapabilityStorageInputOutput16: return "StorageInputOutput16";
|
||||||
|
|
||||||
case CapabilityStorageBuffer8BitAccess: return "CapabilityStorageBuffer8BitAccess";
|
case CapabilityStorageBuffer8BitAccess: return "StorageBuffer8BitAccess";
|
||||||
case CapabilityUniformAndStorageBuffer8BitAccess: return "CapabilityUniformAndStorageBuffer8BitAccess";
|
case CapabilityUniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess";
|
||||||
case CapabilityStoragePushConstant8: return "CapabilityStoragePushConstant8";
|
case CapabilityStoragePushConstant8: return "StoragePushConstant8";
|
||||||
|
|
||||||
case CapabilityDeviceGroup: return "DeviceGroup";
|
case CapabilityDeviceGroup: return "DeviceGroup";
|
||||||
case CapabilityMultiView: return "MultiView";
|
case CapabilityMultiView: return "MultiView";
|
||||||
|
|
||||||
case CapabilityStencilExportEXT: return "StencilExportEXT";
|
case CapabilityStencilExportEXT: return "StencilExportEXT";
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case CapabilityFloat16ImageAMD: return "Float16ImageAMD";
|
case CapabilityFloat16ImageAMD: return "Float16ImageAMD";
|
||||||
case CapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD";
|
case CapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD";
|
||||||
case CapabilityFragmentMaskAMD: return "FragmentMaskAMD";
|
case CapabilityFragmentMaskAMD: return "FragmentMaskAMD";
|
||||||
case CapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD";
|
case CapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD";
|
||||||
#endif
|
|
||||||
|
|
||||||
case CapabilityAtomicStorageOps: return "AtomicStorageOps";
|
case CapabilityAtomicStorageOps: return "AtomicStorageOps";
|
||||||
|
|
||||||
case CapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage";
|
case CapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage";
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
||||||
case CapabilityShaderViewportIndexLayerNV: return "ShaderViewportIndexLayerNV";
|
case CapabilityShaderViewportIndexLayerNV: return "ShaderViewportIndexLayerNV";
|
||||||
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
||||||
|
@ -902,33 +917,67 @@ const char* CapabilityString(int info)
|
||||||
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||||
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
|
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
|
||||||
case CapabilityRayTracingNV: return "RayTracingNV";
|
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 CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
|
||||||
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
|
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
|
||||||
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
||||||
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
||||||
// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by CapabilityFragmentDensityEXT
|
case CapabilityImageFootprintNV: return "ImageFootprintNV";
|
||||||
#endif
|
// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by FragmentDensityEXT
|
||||||
|
case CapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV";
|
||||||
case CapabilityFragmentDensityEXT: return "FragmentDensityEXT";
|
case CapabilityFragmentDensityEXT: return "FragmentDensityEXT";
|
||||||
|
|
||||||
case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT";
|
case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT";
|
||||||
|
|
||||||
case CapabilityShaderNonUniformEXT: return "CapabilityShaderNonUniformEXT";
|
case CapabilityShaderNonUniformEXT: return "ShaderNonUniformEXT";
|
||||||
case CapabilityRuntimeDescriptorArrayEXT: return "CapabilityRuntimeDescriptorArrayEXT";
|
case CapabilityRuntimeDescriptorArrayEXT: return "RuntimeDescriptorArrayEXT";
|
||||||
case CapabilityInputAttachmentArrayDynamicIndexingEXT: return "CapabilityInputAttachmentArrayDynamicIndexingEXT";
|
case CapabilityInputAttachmentArrayDynamicIndexingEXT: return "InputAttachmentArrayDynamicIndexingEXT";
|
||||||
case CapabilityUniformTexelBufferArrayDynamicIndexingEXT: return "CapabilityUniformTexelBufferArrayDynamicIndexingEXT";
|
case CapabilityUniformTexelBufferArrayDynamicIndexingEXT: return "UniformTexelBufferArrayDynamicIndexingEXT";
|
||||||
case CapabilityStorageTexelBufferArrayDynamicIndexingEXT: return "CapabilityStorageTexelBufferArrayDynamicIndexingEXT";
|
case CapabilityStorageTexelBufferArrayDynamicIndexingEXT: return "StorageTexelBufferArrayDynamicIndexingEXT";
|
||||||
case CapabilityUniformBufferArrayNonUniformIndexingEXT: return "CapabilityUniformBufferArrayNonUniformIndexingEXT";
|
case CapabilityUniformBufferArrayNonUniformIndexingEXT: return "UniformBufferArrayNonUniformIndexingEXT";
|
||||||
case CapabilitySampledImageArrayNonUniformIndexingEXT: return "CapabilitySampledImageArrayNonUniformIndexingEXT";
|
case CapabilitySampledImageArrayNonUniformIndexingEXT: return "SampledImageArrayNonUniformIndexingEXT";
|
||||||
case CapabilityStorageBufferArrayNonUniformIndexingEXT: return "CapabilityStorageBufferArrayNonUniformIndexingEXT";
|
case CapabilityStorageBufferArrayNonUniformIndexingEXT: return "StorageBufferArrayNonUniformIndexingEXT";
|
||||||
case CapabilityStorageImageArrayNonUniformIndexingEXT: return "CapabilityStorageImageArrayNonUniformIndexingEXT";
|
case CapabilityStorageImageArrayNonUniformIndexingEXT: return "StorageImageArrayNonUniformIndexingEXT";
|
||||||
case CapabilityInputAttachmentArrayNonUniformIndexingEXT: return "CapabilityInputAttachmentArrayNonUniformIndexingEXT";
|
case CapabilityInputAttachmentArrayNonUniformIndexingEXT: return "InputAttachmentArrayNonUniformIndexingEXT";
|
||||||
case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT";
|
case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "UniformTexelBufferArrayNonUniformIndexingEXT";
|
||||||
case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT";
|
case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "StorageTexelBufferArrayNonUniformIndexingEXT";
|
||||||
|
|
||||||
case CapabilityVulkanMemoryModelKHR: return "CapabilityVulkanMemoryModelKHR";
|
case CapabilityVulkanMemoryModelKHR: return "VulkanMemoryModelKHR";
|
||||||
case CapabilityVulkanMemoryModelDeviceScopeKHR: return "CapabilityVulkanMemoryModelDeviceScopeKHR";
|
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";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
|
@ -1022,6 +1071,7 @@ const char* OpcodeString(int op)
|
||||||
case 82: return "OpCompositeInsert";
|
case 82: return "OpCompositeInsert";
|
||||||
case 83: return "OpCopyObject";
|
case 83: return "OpCopyObject";
|
||||||
case 84: return "OpTranspose";
|
case 84: return "OpTranspose";
|
||||||
|
case OpCopyLogical: return "OpCopyLogical";
|
||||||
case 85: return "Bad";
|
case 85: return "Bad";
|
||||||
case 86: return "OpSampledImage";
|
case 86: return "OpSampledImage";
|
||||||
case 87: return "OpImageSampleImplicitLod";
|
case 87: return "OpImageSampleImplicitLod";
|
||||||
|
@ -1260,6 +1310,7 @@ const char* OpcodeString(int op)
|
||||||
case 320: return "OpImageSparseRead";
|
case 320: return "OpImageSparseRead";
|
||||||
|
|
||||||
case OpModuleProcessed: return "OpModuleProcessed";
|
case OpModuleProcessed: return "OpModuleProcessed";
|
||||||
|
case OpExecutionModeId: return "OpExecutionModeId";
|
||||||
case OpDecorateId: return "OpDecorateId";
|
case OpDecorateId: return "OpDecorateId";
|
||||||
|
|
||||||
case 333: return "OpGroupNonUniformElect";
|
case 333: return "OpGroupNonUniformElect";
|
||||||
|
@ -1297,6 +1348,8 @@ const char* OpcodeString(int op)
|
||||||
case 365: return "OpGroupNonUniformQuadBroadcast";
|
case 365: return "OpGroupNonUniformQuadBroadcast";
|
||||||
case 366: return "OpGroupNonUniformQuadSwap";
|
case 366: return "OpGroupNonUniformQuadSwap";
|
||||||
|
|
||||||
|
case OpTerminateInvocation: return "OpTerminateInvocation";
|
||||||
|
|
||||||
case 4421: return "OpSubgroupBallotKHR";
|
case 4421: return "OpSubgroupBallotKHR";
|
||||||
case 4422: return "OpSubgroupFirstInvocationKHR";
|
case 4422: return "OpSubgroupFirstInvocationKHR";
|
||||||
case 4428: return "OpSubgroupAllKHR";
|
case 4428: return "OpSubgroupAllKHR";
|
||||||
|
@ -1304,7 +1357,10 @@ const char* OpcodeString(int op)
|
||||||
case 4430: return "OpSubgroupAllEqualKHR";
|
case 4430: return "OpSubgroupAllEqualKHR";
|
||||||
case 4432: return "OpSubgroupReadInvocationKHR";
|
case 4432: return "OpSubgroupReadInvocationKHR";
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
|
||||||
|
case OpAtomicFMinEXT: return "OpAtomicFMinEXT";
|
||||||
|
case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT";
|
||||||
|
|
||||||
case 5000: return "OpGroupIAddNonUniformAMD";
|
case 5000: return "OpGroupIAddNonUniformAMD";
|
||||||
case 5001: return "OpGroupFAddNonUniformAMD";
|
case 5001: return "OpGroupFAddNonUniformAMD";
|
||||||
case 5002: return "OpGroupFMinNonUniformAMD";
|
case 5002: return "OpGroupFMinNonUniformAMD";
|
||||||
|
@ -1316,22 +1372,64 @@ const char* OpcodeString(int op)
|
||||||
|
|
||||||
case 5011: return "OpFragmentMaskFetchAMD";
|
case 5011: return "OpFragmentMaskFetchAMD";
|
||||||
case 5012: return "OpFragmentFetchAMD";
|
case 5012: return "OpFragmentFetchAMD";
|
||||||
#endif
|
|
||||||
|
case OpReadClockKHR: return "OpReadClockKHR";
|
||||||
|
|
||||||
case OpDecorateStringGOOGLE: return "OpDecorateStringGOOGLE";
|
case OpDecorateStringGOOGLE: return "OpDecorateStringGOOGLE";
|
||||||
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
|
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
case OpReportIntersectionKHR: return "OpReportIntersectionKHR";
|
||||||
case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
|
|
||||||
case OpReportIntersectionNV: return "OpReportIntersectionNV";
|
|
||||||
case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV";
|
case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV";
|
||||||
|
case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR";
|
||||||
case OpTerminateRayNV: return "OpTerminateRayNV";
|
case OpTerminateRayNV: return "OpTerminateRayNV";
|
||||||
|
case OpTerminateRayKHR: return "OpTerminateRayKHR";
|
||||||
case OpTraceNV: return "OpTraceNV";
|
case OpTraceNV: return "OpTraceNV";
|
||||||
case OpTypeAccelerationStructureNV: return "OpTypeAccelerationStructureNV";
|
case OpTraceRayMotionNV: return "OpTraceRayMotionNV";
|
||||||
|
case OpTraceRayKHR: return "OpTraceRayKHR";
|
||||||
|
case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
|
||||||
case OpExecuteCallableNV: return "OpExecuteCallableNV";
|
case OpExecuteCallableNV: return "OpExecuteCallableNV";
|
||||||
|
case OpExecuteCallableKHR: return "OpExecuteCallableKHR";
|
||||||
|
case OpConvertUToAccelerationStructureKHR: return "OpConvertUToAccelerationStructureKHR";
|
||||||
|
|
||||||
|
case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
|
||||||
case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV";
|
case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV";
|
||||||
case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV";
|
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:
|
default:
|
||||||
return "Bad";
|
return "Bad";
|
||||||
|
@ -1375,6 +1473,7 @@ void Parameterize()
|
||||||
InstructionDesc[OpMemoryModel].setResultAndType(false, false);
|
InstructionDesc[OpMemoryModel].setResultAndType(false, false);
|
||||||
InstructionDesc[OpEntryPoint].setResultAndType(false, false);
|
InstructionDesc[OpEntryPoint].setResultAndType(false, false);
|
||||||
InstructionDesc[OpExecutionMode].setResultAndType(false, false);
|
InstructionDesc[OpExecutionMode].setResultAndType(false, false);
|
||||||
|
InstructionDesc[OpExecutionModeId].setResultAndType(false, false);
|
||||||
InstructionDesc[OpTypeVoid].setResultAndType(true, false);
|
InstructionDesc[OpTypeVoid].setResultAndType(true, false);
|
||||||
InstructionDesc[OpTypeBool].setResultAndType(true, false);
|
InstructionDesc[OpTypeBool].setResultAndType(true, false);
|
||||||
InstructionDesc[OpTypeInt].setResultAndType(true, false);
|
InstructionDesc[OpTypeInt].setResultAndType(true, false);
|
||||||
|
@ -1428,6 +1527,7 @@ void Parameterize()
|
||||||
InstructionDesc[OpBranchConditional].setResultAndType(false, false);
|
InstructionDesc[OpBranchConditional].setResultAndType(false, false);
|
||||||
InstructionDesc[OpSwitch].setResultAndType(false, false);
|
InstructionDesc[OpSwitch].setResultAndType(false, false);
|
||||||
InstructionDesc[OpKill].setResultAndType(false, false);
|
InstructionDesc[OpKill].setResultAndType(false, false);
|
||||||
|
InstructionDesc[OpTerminateInvocation].setResultAndType(false, false);
|
||||||
InstructionDesc[OpReturn].setResultAndType(false, false);
|
InstructionDesc[OpReturn].setResultAndType(false, false);
|
||||||
InstructionDesc[OpReturnValue].setResultAndType(false, false);
|
InstructionDesc[OpReturnValue].setResultAndType(false, false);
|
||||||
InstructionDesc[OpUnreachable].setResultAndType(false, false);
|
InstructionDesc[OpUnreachable].setResultAndType(false, false);
|
||||||
|
@ -1444,6 +1544,10 @@ void Parameterize()
|
||||||
InstructionDesc[OpGroupWaitEvents].setResultAndType(false, false);
|
InstructionDesc[OpGroupWaitEvents].setResultAndType(false, false);
|
||||||
InstructionDesc[OpAtomicFlagClear].setResultAndType(false, false);
|
InstructionDesc[OpAtomicFlagClear].setResultAndType(false, false);
|
||||||
InstructionDesc[OpModuleProcessed].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
|
// Specific additional context-dependent operands
|
||||||
|
|
||||||
|
@ -1557,6 +1661,10 @@ void Parameterize()
|
||||||
InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'");
|
InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'");
|
||||||
InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <<Execution_Mode,Execution Mode>>");
|
InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <<Execution_Mode,Execution Mode>>");
|
||||||
|
|
||||||
|
InstructionDesc[OpExecutionModeId].operands.push(OperandId, "'Entry Point'");
|
||||||
|
InstructionDesc[OpExecutionModeId].operands.push(OperandExecutionMode, "'Mode'");
|
||||||
|
InstructionDesc[OpExecutionModeId].operands.push(OperandVariableIds, "See <<Execution_Mode,Execution Mode>>");
|
||||||
|
|
||||||
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'");
|
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'");
|
||||||
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'");
|
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'");
|
||||||
|
|
||||||
|
@ -1650,7 +1758,7 @@ void Parameterize()
|
||||||
|
|
||||||
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'");
|
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'");
|
||||||
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, "");
|
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(OperandId, "'Structure Type'");
|
||||||
InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'");
|
InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'");
|
||||||
|
@ -1660,7 +1768,7 @@ void Parameterize()
|
||||||
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'");
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'");
|
||||||
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'");
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'");
|
||||||
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, "");
|
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(OperandId, "'Decoration Group'");
|
||||||
InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'");
|
InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'");
|
||||||
|
@ -1921,6 +2029,8 @@ void Parameterize()
|
||||||
|
|
||||||
InstructionDesc[OpTranspose].operands.push(OperandId, "'Matrix'");
|
InstructionDesc[OpTranspose].operands.push(OperandId, "'Matrix'");
|
||||||
|
|
||||||
|
InstructionDesc[OpCopyLogical].operands.push(OperandId, "'Operand'");
|
||||||
|
|
||||||
InstructionDesc[OpIsNan].operands.push(OperandId, "'x'");
|
InstructionDesc[OpIsNan].operands.push(OperandId, "'x'");
|
||||||
|
|
||||||
InstructionDesc[OpIsInf].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(OperandMemorySemantics, "'Semantics'");
|
||||||
InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'");
|
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(OperandId, "'Pointer'");
|
||||||
InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'");
|
InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'");
|
||||||
InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'");
|
InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||||
|
@ -2236,6 +2351,16 @@ void Parameterize()
|
||||||
InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'");
|
InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||||
InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Value'");
|
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(OperandId, "'Pointer'");
|
||||||
InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'");
|
InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'");
|
||||||
InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'");
|
InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||||
|
@ -2614,7 +2739,7 @@ void Parameterize()
|
||||||
|
|
||||||
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'");
|
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'");
|
||||||
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X");
|
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X");
|
||||||
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandLiteralNumber, "'Direction'");
|
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "'Direction'");
|
||||||
|
|
||||||
InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'");
|
InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'");
|
||||||
|
|
||||||
|
@ -2634,7 +2759,6 @@ void Parameterize()
|
||||||
|
|
||||||
InstructionDesc[OpModuleProcessed].operands.push(OperandLiteralString, "'process'");
|
InstructionDesc[OpModuleProcessed].operands.push(OperandLiteralString, "'process'");
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandScope, "'Execution'");
|
InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandScope, "'Execution'");
|
||||||
InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
|
InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
|
||||||
InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandId, "'X'");
|
InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandId, "'X'");
|
||||||
|
@ -2673,14 +2797,12 @@ void Parameterize()
|
||||||
InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Image'");
|
InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Image'");
|
||||||
InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Coordinate'");
|
InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Coordinate'");
|
||||||
InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Fragment Index'");
|
InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Fragment Index'");
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
|
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, "'Ray Flags'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'");
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'");
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'");
|
||||||
|
@ -2693,17 +2815,149 @@ void Parameterize()
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
|
||||||
InstructionDesc[OpTraceNV].setResultAndType(false, false);
|
InstructionDesc[OpTraceNV].setResultAndType(false, false);
|
||||||
|
|
||||||
InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Parameter'");
|
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'");
|
||||||
InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Kind'");
|
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[OpIgnoreIntersectionNV].setResultAndType(false, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpIgnoreIntersectionKHR].setResultAndType(false, false);
|
||||||
|
|
||||||
InstructionDesc[OpTerminateRayNV].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, "SBT Record Index");
|
||||||
InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID");
|
InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID");
|
||||||
InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false);
|
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, "'Sampled Image'");
|
||||||
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");
|
||||||
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Granularity'");
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Granularity'");
|
||||||
|
@ -2713,7 +2967,36 @@ void Parameterize()
|
||||||
|
|
||||||
InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Index Offset'");
|
InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Index Offset'");
|
||||||
InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Packed Indices'");
|
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
|
}; // end spv namespace
|
||||||
|
|
3
thirdparty/ShaderCompiler/spirv/doc.h
vendored
3
thirdparty/ShaderCompiler/spirv/doc.h
vendored
|
@ -125,6 +125,7 @@ enum OperandClass {
|
||||||
OperandVariableLiteralId,
|
OperandVariableLiteralId,
|
||||||
OperandLiteralNumber,
|
OperandLiteralNumber,
|
||||||
OperandLiteralString,
|
OperandLiteralString,
|
||||||
|
OperandVariableLiteralStrings,
|
||||||
OperandSource,
|
OperandSource,
|
||||||
OperandExecutionModel,
|
OperandExecutionModel,
|
||||||
OperandAddressing,
|
OperandAddressing,
|
||||||
|
@ -255,4 +256,4 @@ const char* AccessQualifierString(int attr);
|
||||||
|
|
||||||
void PrintOperands(const OperandParameters& operands, int reservedOperands);
|
void PrintOperands(const OperandParameters& operands, int reservedOperands);
|
||||||
|
|
||||||
}; // end namespace spv
|
} // end namespace spv
|
||||||
|
|
2
thirdparty/ShaderCompiler/spirv/hex_float.h
vendored
2
thirdparty/ShaderCompiler/spirv/hex_float.h
vendored
|
@ -784,7 +784,7 @@ inline std::istream& ParseNormalFloat(std::istream& is, bool negate_value,
|
||||||
if (val.isInfinity()) {
|
if (val.isInfinity()) {
|
||||||
// Fail the parse. Emulate standard behaviour by setting the value to
|
// Fail the parse. Emulate standard behaviour by setting the value to
|
||||||
// the closest normal value, and set the fail bit on the stream.
|
// the closest normal value, and set the fail bit on the stream.
|
||||||
value.set_value((value.isNegative() | negate_value) ? T::lowest()
|
value.set_value((value.isNegative() || negate_value) ? T::lowest()
|
||||||
: T::max());
|
: T::max());
|
||||||
is.setstate(std::ios_base::failbit);
|
is.setstate(std::ios_base::failbit);
|
||||||
}
|
}
|
||||||
|
|
1111
thirdparty/ShaderCompiler/spirv/spirv.hpp
vendored
1111
thirdparty/ShaderCompiler/spirv/spirv.hpp
vendored
File diff suppressed because it is too large
Load diff
78
thirdparty/ShaderCompiler/spirv/spvIR.h
vendored
78
thirdparty/ShaderCompiler/spirv/spvIR.h
vendored
|
@ -55,6 +55,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
|
||||||
|
@ -83,6 +84,7 @@ const MemorySemanticsMask MemorySemanticsAllMemory =
|
||||||
struct IdImmediate {
|
struct IdImmediate {
|
||||||
bool isId; // true if word is an Id, false if word is an immediate
|
bool isId; // true if word is an Id, false if word is an immediate
|
||||||
unsigned word;
|
unsigned word;
|
||||||
|
IdImmediate(bool i, unsigned w) : isId(i), word(w) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -225,6 +227,35 @@ public:
|
||||||
return nullptr;
|
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<Instruction>(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<Instruction>(branch));
|
||||||
|
successors.push_back(header);
|
||||||
|
}
|
||||||
|
|
||||||
bool isTerminated() const
|
bool isTerminated() const
|
||||||
{
|
{
|
||||||
switch (instructions.back()->getOpCode()) {
|
switch (instructions.back()->getOpCode()) {
|
||||||
|
@ -232,8 +263,10 @@ public:
|
||||||
case OpBranchConditional:
|
case OpBranchConditional:
|
||||||
case OpSwitch:
|
case OpSwitch:
|
||||||
case OpKill:
|
case OpKill:
|
||||||
|
case OpTerminateInvocation:
|
||||||
case OpReturn:
|
case OpReturn:
|
||||||
case OpReturnValue:
|
case OpReturnValue:
|
||||||
|
case OpUnreachable:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -267,10 +300,24 @@ protected:
|
||||||
bool unreachable;
|
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
|
// Traverses the control-flow graph rooted at root in an order suited for
|
||||||
// readable code generation. Invokes callback at every node in the traversal
|
// readable code generation. Invokes callback at every node in the traversal
|
||||||
// order.
|
// order. The callback arguments are:
|
||||||
void inReadableOrder(Block* root, std::function<void(Block*)> callback);
|
// - 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<void(Block*, ReachReason, Block* header)> callback);
|
||||||
|
|
||||||
//
|
//
|
||||||
// SPIR-V IR Function.
|
// SPIR-V IR Function.
|
||||||
|
@ -306,10 +353,28 @@ public:
|
||||||
const std::vector<Block*>& getBlocks() const { return blocks; }
|
const std::vector<Block*>& getBlocks() const { return blocks; }
|
||||||
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
||||||
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
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; }
|
void setImplicitThis() { implicitThis = true; }
|
||||||
bool hasImplicitThis() const { return implicitThis; }
|
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<unsigned int>& out) const
|
void dump(std::vector<unsigned int>& out) const
|
||||||
{
|
{
|
||||||
// OpFunction
|
// OpFunction
|
||||||
|
@ -320,7 +385,7 @@ public:
|
||||||
parameterInstructions[p]->dump(out);
|
parameterInstructions[p]->dump(out);
|
||||||
|
|
||||||
// Blocks
|
// 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);
|
Instruction end(0, 0, OpFunctionEnd);
|
||||||
end.dump(out);
|
end.dump(out);
|
||||||
}
|
}
|
||||||
|
@ -334,6 +399,8 @@ protected:
|
||||||
std::vector<Instruction*> parameterInstructions;
|
std::vector<Instruction*> parameterInstructions;
|
||||||
std::vector<Block*> blocks;
|
std::vector<Block*> blocks;
|
||||||
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
|
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
|
||||||
|
bool reducedPrecisionReturn;
|
||||||
|
std::set<int> reducedPrecisionParams; // list of parameter indexes that need a relaxed precision arg
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -394,7 +461,8 @@ protected:
|
||||||
// - the OpFunction instruction
|
// - the OpFunction instruction
|
||||||
// - all the OpFunctionParameter instructions
|
// - all the OpFunctionParameter instructions
|
||||||
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
__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
|
// OpFunction
|
||||||
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
||||||
|
@ -435,6 +503,6 @@ __inline void Block::addInstruction(std::unique_ptr<Instruction> inst)
|
||||||
parent.getParent().mapInstruction(raw_instruction);
|
parent.getParent().mapInstruction(raw_instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // end spv namespace
|
} // end spv namespace
|
||||||
|
|
||||||
#endif // spvIR_H
|
#endif // spvIR_H
|
||||||
|
|
Loading…
Reference in a new issue